?一洞渔、ServiceAccount
1. ServiceAccount 介紹
首先Kubernetes中賬戶區(qū)分為:User Accounts(用戶賬戶) 和 Service Accounts(服務(wù)賬戶) 兩種,它們的設(shè)計(jì)區(qū)別如下:
- UserAccount是給kubernetes集群外部用戶使用的吧慢,例如運(yùn)維或者集群管理人員,使用kubectl命令時(shí)用的就是UserAccount賬戶引矩;UserAccount是全局性严里。在集群所有namespaces中,名稱具有唯一性伤靠,默認(rèn)情況下用戶為admin;
- ServiceAccount是給運(yùn)行在Pod的程序使用的身份認(rèn)證啼染,Pod容器的進(jìn)程需要訪問API Server時(shí)用的就是ServiceAccount賬戶宴合;ServiceAccount僅局限它所在的namespace,每個(gè)namespace都會(huì)自動(dòng)創(chuàng)建一個(gè)default service account迹鹅;創(chuàng)建Pod時(shí)卦洽,如果沒有指定Service Account,Pod則會(huì)使用default Service Account斜棚。
2. 默認(rèn)Service Account
在上篇文章 k8s九 | 詳解配置對(duì)象ConfigMap與Secret最后kubernetes.io/service-account-token一節(jié)中我們已經(jīng)提到創(chuàng)建命名空間時(shí)會(huì)創(chuàng)建一個(gè)默認(rèn)的Service Account阀蒂,而ServiceAccout 創(chuàng)建時(shí)也會(huì)創(chuàng)建對(duì)應(yīng)的 Secret该窗,下面我們實(shí)際操作下。
創(chuàng)建命名空間
$ kubectl create ns anmin
namespace/anmin created
查看命名空間的ServiceAccount
$ kubectl get sa -n anmin
NAME SECRETS AGE
default 1 27s
查看ServiceAccount的Secret
$ kubectl describe sa default -n anmin
Name: default
Namespace: anmin
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: default-token-bskds
Tokens: default-token-bskds
Events: <none>
$ kubectl get secret -n anmin
NAME TYPE DATA AGE
default-token-bskds kubernetes.io/service-account-token 3 75s
可以看到在創(chuàng)建名為“anmin”的命名空間后蚤霞,自動(dòng)創(chuàng)建了名為“default”的ServiceAccount酗失,并為“default”服務(wù)賬戶創(chuàng)建了對(duì)應(yīng)kubernetes.io/service-account-token類型的secret。
創(chuàng)建一個(gè)Pod
apiVersion: v1
kind: Pod
metadata:
name: testpod
namespace: anmin
spec:
containers:
- name: testpod
image: busybox
args: [/bin/sh, -c,
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
查看Pod的Service Account信息
$ kubectl create -f anmin.yaml
pod/testpod created
$ kubectl describe pod testpod -n anmin
..........
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bskds (ro)
..........
Volumes:
default-token-bskds:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-bskds
Optional: false
.........
在不指定ServiceAccount的情況下昧绣,當(dāng)前 namespace 下面的 Pod 會(huì)默認(rèn)使用 “default” 這個(gè) ServiceAccount规肴,對(duì)應(yīng)的 Secret 會(huì)自動(dòng)掛載到 Pod 的 /var/run/secrets/kubernetes.io/serviceaccount/ 目錄中,我們可以在 Pod 里面獲取到用于身份認(rèn)證的信息夜畴。
$ kubectl exec -it testpod -n anmin -- /bin/sh
/ # ls /var/run/secrets/kubernetes.io/serviceaccount/
ca.crt namespace token
3. 使用自定義的ServiceAccount
創(chuàng)建一個(gè)Service Account
$ kubectl create sa anmin -n anmin
serviceaccount/anmin created
$ kubectl get sa -n anmin
NAME SECRETS AGE
anmin 1 20s
default 1 31m
$ kubectl get secret -n anmin
NAME TYPE DATA AGE
anmin-token-nkb8b kubernetes.io/service-account-token 3 28s
default-token-bskds kubernetes.io/service-account-token 3 31m
Pod使用剛創(chuàng)建的ServiceAccount
apiVersion: v1
kind: Pod
metadata:
name: testpod
namespace: anmin
spec:
containers:
- name: testpod
image: busybox
args: [/bin/sh, -c,
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
serviceAccountName: anmin
更新Pod
$ kubectl apply -f anmin.yaml
pod/testpod created
$ kubectl describe pod testpod -n anmin
.........
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from anmin-token-nkb8b (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
anmin-token-nkb8b:
Type: Secret (a volume populated by a Secret)
SecretName: anmin-token-nkb8b
Optional: false
............
可以看到更新后的Pod已經(jīng)使用了新創(chuàng)建的ServiceAccount服務(wù)賬戶拖刃。
4. ServiceAccount中添加Image pull secrets
我們也可以在Service Account中設(shè)置imagePullSecrets,然后就會(huì)自動(dòng)為使用該 SA 的 Pod 注入 imagePullSecrets 信息贪绘。
創(chuàng)建kubernetes.io/dockerconfigjson類型的私有倉庫鏡像Secret
$ kubectl create secret docker-registry harbor --docker-server=http://192.168.166.229 --docker-username=admin --docker-password=1234567 --docker-email=test@163.com -n anmin
2secret/harbor created
將鏡像倉庫的Secret添加到ServiceAccount
$ kubectl edit sa anmin -n anmin
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2020-06-16T16:09:54Z"
name: anmin
namespace: anmin
resourceVersion: "37509823"
selfLink: /api/v1/namespaces/anmin/serviceaccounts/anmin
uid: c6bec7bb-808d-459f-86c8-6c78b48cb3ab
secrets:
- name: anmin-token-nkb8b
imagePullSecrets:
- name: harbor
查看ServiceAccount中Image pull secrets字段信息
$ kubectl describe sa anmin -n anmin
Name: anmin
Namespace: anmin
Labels: <none>
Annotations: <none>
Image pull secrets: harbor
Mountable secrets: anmin-token-nkb8b
Tokens: anmin-token-nkb8b
Events: <none>
使用ServiceAccount拉取私有鏡像部署Pod
apiVersion: v1
kind: Pod
metadata:
name: anmin2
namespace: anmin
spec:
containers:
- name: anmin2
image: 192.168.166.229/1an/node-exporter:latest
serviceAccountName: anmin
更新Pod并查看狀態(tài)
$ kubectl apply -f harborsecret.yaml
pod/anmin2 created
$ kubectl get pod -n anmin
NAME READY STATUS RESTARTS AGE
anmin2 1/1 Running 0 20s
$ kubectl describe pod anmin2 -n anmin
......
Volumes:
anmin-token-nkb8b:
Type: Secret (a volume populated by a Secret)
SecretName: anmin-token-nkb8b
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Pulling 8h kubelet, k8s-node01 Pulling image "192.168.166.229/1an/node-exporter:latest"
Normal Pulled 8h kubelet, k8s-node01 Successfully pulled image "192.168.166.229/1an/node-exporter:latest"
可以看到Pod已經(jīng)成功從鏡像倉庫拉取鏡像并正常運(yùn)行兑牡。
二、RBAC
1. RBAC介紹
在Kubernetes 中所有資源對(duì)象都是通過 API 對(duì)象進(jìn)行操作兔簇, 它們保存在 Etcd 里发绢。而對(duì)Etcd的操作我們需要通過訪問 kube-apiserver來實(shí)現(xiàn)硬耍,上面的Service Account其實(shí)就是APIServer的認(rèn)證過程垄琐,而授權(quán)的機(jī)制則是通過RBAC:基于角色的訪問控制實(shí)現(xiàn)的。
Role + RoleBinding + ServiceAccount 的權(quán)限分配方式是要重點(diǎn)掌握的內(nèi)容经柴。
RBAC的三個(gè)基本概念:
- Role:角色狸窘,其實(shí)是一組規(guī)則,定義了一組對(duì) Kubernetes API 對(duì)象的操作權(quán)限坯认;
- Subject:被作用者翻擒,既可以是“人”,也可以是“機(jī)器”牛哺,也就是在 Kubernetes 里定義的“用戶”陋气;
- RoleBinding:定義了“被作用者”和“角色”的綁定關(guān)系。
2. Role與RoleBinding
現(xiàn)在我們通過實(shí)際操作來理解RBAC的工作機(jī)制
創(chuàng)建一個(gè)Service Account
$ kubectl create sa zhanmin-sa -n kube-system
serviceaccount/zhanmin created
定義一個(gè)Role對(duì)象 zhanmin-sa-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: zhanmin-sa-role
namespace: kube-system
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
在上面的文件我們定義了被作用的命名空間為:kube-system引润,其中的rules 字段巩趁,就是它所定義的權(quán)限規(guī)則。其中規(guī)則定義的角色對(duì)Pod沒有創(chuàng)建淳附、刪除议慰、更新的權(quán)限。
其中的“被作用者”我們則是通過RoleBinding
對(duì)象來指定奴曙。
定義Rolebinding對(duì)象 zhanmin-sa-rolebinding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: zhanmin-sa-rolebinding
namespace: kube-system
subjects:
- kind: ServiceAccount
name: zhanmin-sa
namespace: kube-system
roleRef:
kind: Role
name: zhanmin-sa-role
apiGroup: rbac.authorization.k8s.io
subjects 字段别凹,即“被作用者”。它的類型是 User洽糟,即 Kubernetes 里的用戶炉菲,也就是上文中的Service Account堕战,這里我們定義被作用者用戶為“zhanmin-sa”。
roleRef則是定義:RoleBinding 對(duì)象可以直接通過名字拍霜,來引用我們前面定義的 Role 對(duì)象践啄,也就是“zhanmin-sa-role”,從而定義了“被作用者(Subject)”和“角色(Role)”之間的綁定關(guān)系沉御。
所以Pod使用名為“zhanmin-sa”的ServiceAccount訪問API Server時(shí)只能夠做對(duì)Pod做get", "watch", "list"操作屿讽。這是因?yàn)椤皕hanmin-sa” 這個(gè) ServiceAccount 的權(quán)限,已經(jīng)被我們綁定了 Role 做了限制吠裆。
注意:Role 和 RoleBinding 對(duì)象都是 Namespaced 對(duì)象(Namespaced Object)伐谈,它們對(duì)權(quán)限的限制規(guī)則僅在它們自己的 Namespace 內(nèi)有效,roleRef 也只能引用當(dāng)前 Namespace 里的 Role 對(duì)象试疙。
下面創(chuàng)建這些對(duì)象
$ kubectl create -f zhanmin-sa-role.yaml
role.rbac.authorization.k8s.io/zhanmin-sa-role created
$ kubectl create -f zhanmin-sa-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/zhanmin-sa-rolebinding created
現(xiàn)在可以去之前部署的kubernetes-dashboard上驗(yàn)證權(quán)限
獲取當(dāng)前Service Account的Secret信息
$ kubectl get secret -n kube-system
zhanmin-sa-token-x6gxs kubernetes.io/service-account-token 3 136m
$ kubectl get secret zhanmin-sa-token-x6gxs -o jsonpath={.data.token} -n kube-system |base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6InJCZFhYLTVRc2E4STlGVVN0VzEwWlc2M1VGMVF0ZDZFaFdJQlc3V2RLMzAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VeXN
現(xiàn)在可以去之前部署的kubernetes-dashboard上驗(yàn)證權(quán)限
命名空間修改為kube-system诵棵,因?yàn)樯厦嫖覀円呀?jīng)說了Service Account只對(duì)當(dāng)前的namespace有效。
可以看到祝旷,權(quán)限是符合我們上面的定義履澳,只可以查看Pod和Deployments對(duì)象,查看其他資源比如SVC顯示是沒有數(shù)據(jù)的怀跛。后面我們可以根據(jù)自己的需求去查詢API對(duì)象修改相應(yīng)的權(quán)限規(guī)則距贷。
3. ClusterRole 和 ClusterRoleBinding
上面的Role和RoleBinding只可以在他們自己的命名空間中有效,如果我們需要一個(gè)具有全部命名空間或者對(duì)節(jié)點(diǎn)有權(quán)限的角色時(shí)吻谋,就需要使用ClusterRole 和 ClusterRoleBinding 對(duì)象來做授權(quán)了忠蝗。
ClusterRole 和 ClusterRoleBinding 這兩個(gè) API 對(duì)象的用法跟 Role 和 RoleBinding 幾乎完全一樣。不一樣的是漓拾,它們的定義里阁最,沒有了 Namespace 字段,權(quán)限可以作用于整個(gè)集群骇两。
創(chuàng)建ClusterRole集群角色 clusterrole.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: clusterrole-anmin
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
含義為:名為“clusterrole-anmin”的集群角色可以對(duì)集群所有命名空間的Pod進(jìn)行“GET速种、Watch、List” 操作低千。
在Role 或者 ClusterRole 里面配阵,如果要賦予用戶 example-user 所有權(quán)限,那你就可以給它指定一個(gè) verbs 字段的全集栋操,如下所示:
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
創(chuàng)建 ClusterRoleBinding集群角色綁定 ClusterRoleBinding.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-clusterrolebinding
subjects:
- kind: User
name: user-anmin
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: clusterrole-anmin
apiGroup: rbac.authorization.k8s.io
含義為: subjects字段定義被作用者用戶為“user-anmin”闸餐,roleRef字段定義:綁定名為“clusterrole-anmin”集群角色。
在 Kubernetes 中已經(jīng)內(nèi)置了很多個(gè)為系統(tǒng)保留的 ClusterRole矾芙,它們的名字都以 system: 開頭舍沙。你可以通過 kubectl get clusterroles
查看到它們。
查看集群角色
$ kubectl get clusterroles
NAME AGE
admin 242d
calico-kube-controllers 211d
calico-node 211d
cluster-admin 242d
cluster-regular 217d
edit 242d
......
查看角色的權(quán)限
$ kubectl describe clusterrole edit
Name: edit
Labels: kubernetes.io/bootstrapping=rbac-defaults
rbac.authorization.k8s.io/aggregate-to-admin=true
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
configmaps [] [] [create delete deletecollection patch update get list watch]
endpoints [] [] [create delete deletecollection patch update get list watch]
persistentvolumeclaims [] [] [create delete deletecollection patch update get list watch]
pods [] [] [create delete deletecollection patch update get list watch]
replicationcontrollers/scale [] [] [create delete deletecollection patch update get list watch]
......
4. Group用戶組
Kubernetes 還擁有“用戶組”(Group)的概念剔宪,也就是一組“用戶”的意思拂铡。如果你為 Kubernetes 配置了外部認(rèn)證服務(wù)的話壹无,這個(gè)“用戶組”的概念就會(huì)由外部認(rèn)證服務(wù)提供。
ServiceAccount感帅,在 Kubernetes 里對(duì)應(yīng)的“用戶”的名字是:
system:serviceaccount:<Namespace名字>:<ServiceAccount名字>
對(duì)應(yīng)的內(nèi)置“用戶組”的名字斗锭,就是:
system:serviceaccounts:<Namespace名字>
比如,現(xiàn)在我們可以在 RoleBinding 里定義如下的 subjects:
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
這就意味著這個(gè) Role 的權(quán)限規(guī)則失球,作用于 mynamespace 里的所有 ServiceAccount岖是。這就用到了“用戶組”的概念。而下面這個(gè)例子:
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
就意味著這個(gè) Role 的權(quán)限規(guī)則实苞,作用于整個(gè)系統(tǒng)里的所有 ServiceAccount豺撑。
總結(jié):通過上面的實(shí)踐,我們了解了在kubernetes中用戶分為User Accounts和 Service Accounts黔牵,在我們平常的使用中會(huì)經(jīng)常使用ServiceAccount聪轿。而對(duì)于權(quán)限的控制,我們需要先創(chuàng)建角色(Role)猾浦,其實(shí)就是一組權(quán)限規(guī)則列表陆错。然后我們分配這些權(quán)限的方式,就是通過創(chuàng)建 RoleBinding 對(duì)象金赦,將被作用者(subject)Service Account和權(quán)限列表Role進(jìn)行綁定音瓷,也就是Role + RoleBinding + ServiceAccount來實(shí)現(xiàn)。另外ClusterRole 和 ClusterRoleBinding素邪,則是 Kubernetes 集群級(jí)別的 Role 和 RoleBinding外莲,它們的作用范圍不受 Namespace 限制猪半。
參考資料:
https://time.geekbang.org/column/article/42154
https://www.qikqiak.com/k8s-book/docs/30.RBAC.html
關(guān)注公眾號(hào)回復(fù)【k8s】獲取視頻教程及更多資料: