部门角色权限rbac_k8s十 | 一文读懂基于角色的权限控制RBAC
一、ServiceAccount
. 1. ServiceAccount 介紹
首先Kubernetes中賬戶區分為:User Accounts(用戶賬戶) 和 Service Accounts(服務賬戶) 兩種,它們的設計區別如下:
UserAccount是給kubernetes集群外部用戶使用的,例如運維或者集群管理人員,使用kubectl命令時用的就是UserAccount賬戶;UserAccount是全局性。在集群所有namespaces中,名稱具有唯一性,默認情況下用戶為admin;
ServiceAccount是給運行在Pod的程序使用的身份認證,Pod容器的進程需要訪問API Server時用的就是ServiceAccount賬戶;ServiceAccount僅局限它所在的namespace,每個namespace都會自動創建一個default service account;創建Pod時,如果沒有指定Service Account,Pod則會使用default Service Account。
. 2. 默認Service Account
在上篇文章 k8s九 | 詳解配置對象ConfigMap與Secret最后kubernetes.io/service-account-token一節中我們已經提到創建命名空間時會創建一個默認的Service Account,而ServiceAccout 創建時也會創建對應的 Secret,下面我們實際操作下。
創建命名空間
1$?kubectl??create??ns??anmin2namespace/anmin?created
查看命名空間的ServiceAccount
1$?kubectl??get?sa?-n?anmin2NAME??????SECRETS???AGE
3default???1?????????27s
查看ServiceAccount的Secret
1$?kubectl??describe??sa??default???-n?anmin2Name:????????????????default
3Namespace:???????????anmin
4Labels:?????????????? 5Annotations:????????? 6Image?pull?secrets:?? 7Mountable?secrets:???default-token-bskds 8Tokens:??????????????default-token-bskds 9Events:??????????????10$?kubectl??get??secret?-n?anmin11NAME??????????????????TYPE??????????????????????????????????DATA???AGE12default-token-bskds???kubernetes.io/service-account-token???3??????75s
可以看到在創建名為“anmin”的命名空間后,自動創建了名為“default”的ServiceAccount,并為“default”服務賬戶創建了對應kubernetes.io/service-account-token類型的secret。
創建一個Pod
1apiVersion:?v12kind:?Pod
3metadata:
4??name:?testpod
5??namespace:?anmin
6spec:
7??containers:
8??-?name:?testpod
9????image:?busybox
10????args:?[/bin/sh,?-c,
11????????????'i=0;?while?true;?do?echo?"$i:?$(date)";?i=$((i+1));?sleep?1;?done']
查看Pod的Service Account信息
1$?kubectl??create?-f?anmin.yaml?2pod/testpod?created
3$?kubectl??describe?pod??testpod??-n?anmin
4..........
5????Mounts:
6??????/var/run/secrets/kubernetes.io/serviceaccount?from?default-token-bskds?(ro)
7..........
8Volumes:
9??default-token-bskds:
10????Type:????????Secret?(a?volume?populated?by?a?Secret)
11????SecretName:??default-token-bskds
12????Optional:????false
13.........
在不指定ServiceAccount的情況下,當前 namespace 下面的 Pod 會默認使用 “default” 這個 ServiceAccount,對應的 Secret 會自動掛載到 Pod 的 /var/run/secrets/kubernetes.io/serviceaccount/ 目錄中,我們可以在 Pod 里面獲取到用于身份認證的信息。
1$?kubectl??exec?-it?testpod?-n?anmin?--?/bin/sh2/?#?ls?/var/run/secrets/kubernetes.io/serviceaccount/
3ca.crt?????namespace??token
. 3. 使用自定義的ServiceAccount
創建一個Service Account
1$?kubectl??create?sa?anmin?-n?anmin2serviceaccount/anmin?created
3$?kubectl??get?sa?-n?anmin
4NAME??????SECRETS???AGE
5anmin?????1?????????20s
6default???1?????????31m
7$?kubectl???get?secret?-n?anmin
8NAME??????????????????TYPE??????????????????????????????????DATA???AGE
9anmin-token-nkb8b?????kubernetes.io/service-account-token???3??????28s
10default-token-bskds???kubernetes.io/service-account-token???3??????31m
Pod使用剛創建的ServiceAccount
1apiVersion:?v12kind:?Pod
3metadata:
4??name:?testpod
5??namespace:?anmin
6spec:
7??containers:
8??-?name:?testpod
9????image:?busybox
10????args:?[/bin/sh,?-c,
11????????????'i=0;?while?true;?do?echo?"$i:?$(date)";?i=$((i+1));?sleep?1;?done']
12??serviceAccountName:?anmin
13?```
14?更新Pod
15?```shell
16?$?kubectl???apply?-f?anmin.yaml?
17pod/testpod?created
18$?kubectl??describe??pod??testpod?-n?anmin
19.........
20????Mounts:
21??????/var/run/secrets/kubernetes.io/serviceaccount?from?anmin-token-nkb8b?(ro)
22Conditions:
23??Type??????????????Status
24??Initialized???????True?
25??Ready?????????????True?
26??ContainersReady???True?
27??PodScheduled??????True?
28Volumes:
29??anmin-token-nkb8b:
30????Type:????????Secret?(a?volume?populated?by?a?Secret)
31????SecretName:??anmin-token-nkb8b
32????Optional:????false
33????............
可以看到更新后的Pod已經使用了新創建的ServiceAccount服務賬戶。
. 4. ServiceAccount中添加Image pull secrets
我們也可以在Service Account中設置imagePullSecrets,然后就會自動為使用該 SA 的 Pod 注入 imagePullSecrets 信息。
創建kubernetes.io/dockerconfigjson類型的私有倉庫鏡像Secret
1$?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?anmin22secret/harbor?created
將鏡像倉庫的Secret添加到ServiceAccount
1$?kubectl??edit?sa??anmin??-n?anmin2#?Please?edit?the?object?below.?Lines?beginning?with?a?'#'?will?be?ignored,
3#?and?an?empty?file?will?abort?the?edit.?If?an?error?occurs?while?saving?this?file?will?be
4#?reopened?with?the?relevant?failures.
5#
6apiVersion:?v1
7kind:?ServiceAccount
8metadata:
9??creationTimestamp:?"2020-06-16T16:09:54Z"
10??name:?anmin
11??namespace:?anmin
12??resourceVersion:?"37509823"
13??selfLink:?/api/v1/namespaces/anmin/serviceaccounts/anmin
14??uid:?c6bec7bb-808d-459f-86c8-6c78b48cb3ab
15secrets:
16-?name:?anmin-token-nkb8b
17imagePullSecrets:
18-?name:?harbor
查看ServiceAccount中Image pull secrets字段信息
1$?kubectl??describe?sa??anmin?-n??anmin?2Name:????????????????anmin
3Namespace:???????????anmin
4Labels:??????????????5Annotations:?????????6Image?pull?secrets:??harbor7Mountable?secrets:???anmin-token-nkb8b8Tokens:??????????????anmin-token-nkb8b9Events:??????????????
使用ServiceAccount拉取私有鏡像部署Pod
1apiVersion:?v12kind:?Pod
3metadata:
4??name:?anmin2
5??namespace:?anmin
6spec:
7??containers:
8??-?name:?anmin2
9????image:?192.168.166.229/1an/node-exporter:latest
10??serviceAccountName:?anmin
更新Pod并查看狀態
1$?kubectl??apply?-f?harborsecret.yaml?2pod/anmin2?created
3$?kubectl??get?pod?-n?anmin
4NAME?????????READY???STATUS?????????????RESTARTS???AGE
5anmin2???????1/1?????Running????????????0??????????20s
6$?kubectl?describe?pod??anmin2?-n?anmin
7......
8Volumes:
9??anmin-token-nkb8b:
10????Type:????????Secret?(a?volume?populated?by?a?Secret)
11????SecretName:??anmin-token-nkb8b
12????Optional:????false
13QoS?Class:???????BestEffort
14Node-Selectors:??15Tolerations:?????node.kubernetes.io/not-ready:NoExecute?for?300s16?????????????????node.kubernetes.io/unreachable:NoExecute?for?300s17Events:18??Type????Reason?????Age???From?????????????????Message19??----????------?????----??----?????????????????-------20??Normal??Pulling????8h????kubelet,?k8s-node01??Pulling?image?"192.168.166.229/1an/node-exporter:latest"21??Normal??Pulled?????8h????kubelet,?k8s-node01??Successfully?pulled?image?"192.168.166.229/1an/node-exporter:latest"
可以看到Pod已經成功從鏡像倉庫拉取鏡像并正常運行。
二、RBAC
. 1. RBAC介紹
在Kubernetes 中所有資源對象都是通過 API 對象進行操作, 它們保存在 Etcd 里。而對Etcd的操作我們需要通過訪問 kube-apiserver來實現,上面的Service Account其實就是APIServer的認證過程,而授權的機制則是通過RBAC:基于角色的訪問控制實現的。
Role + RoleBinding + ServiceAccount 的權限分配方式是要重點掌握的內容。
RBAC的三個基本概念:
Role:角色,其實是一組規則,定義了一組對 Kubernetes API 對象的操作權限;
Subject:被作用者,既可以是“人”,也可以是“機器”,也就是在 Kubernetes 里定義的“用戶”;
RoleBinding:定義了“被作用者”和“角色”的綁定關系。
. 2. Role與RoleBinding
現在我們通過實際操作來理解RBAC的工作機制
創建一個Service Account
2serviceaccount/zhanmin?created
定義一個Role對象 zhanmin-sa-role.yaml
1apiVersion:?rbac.authorization.k8s.io/v12kind:?Role
3metadata:
4??name:?zhanmin-sa-role
5??namespace:?kube-system
6rules:
7-?apiGroups:?[""]
8??resources:?["pods"]
9??verbs:?["get",?"watch",?"list"]
10-?apiGroups:?["apps"]
11??resources:?["deployments"]
12??verbs:?["get",?"list",?"watch",?"create",?"update",?"patch",?"delete"]
在上面的文件我們定義了被作用的命名空間為:kube-system,其中的rules 字段,就是它所定義的權限規則。其中規則定義的角色對Pod沒有創建、刪除、更新的權限。
其中的“被作用者”我們則是通過RoleBinding ?對象來指定。
定義Rolebinding對象 zhanmin-sa-rolebinding.yaml
1kind:?RoleBinding2apiVersion:?rbac.authorization.k8s.io/v1
3metadata:
4??name:?zhanmin-sa-rolebinding
5??namespace:?kube-system
6subjects:
7-?kind:?ServiceAccount
8??name:?zhanmin-sa
9??namespace:?kube-system
10roleRef:
11??kind:?Role
12??name:?zhanmin-sa-role
13??apiGroup:?rbac.authorization.k8s.io
subjects 字段,即“被作用者”。它的類型是 User,即 Kubernetes 里的用戶,也就是上文中的Service Account,這里我們定義被作用者用戶為“zhanmin-sa”。
roleRef則是定義:RoleBinding 對象可以直接通過名字,來引用我們前面定義的 Role 對象,也就是“zhanmin-sa-role”,從而定義了“被作用者(Subject)”和“角色(Role)”之間的綁定關系。
所以Pod使用名為“zhanmin-sa”的ServiceAccount訪問API Server時只能夠做對Pod做get", "watch", "list"操作。這是因為“zhanmin-sa” 這個 ServiceAccount 的權限,已經被我們綁定了 Role 做了限制。
注意:Role 和 RoleBinding 對象都是 Namespaced 對象(Namespaced Object),它們對權限的限制規則僅在它們自己的 Namespace 內有效,roleRef 也只能引用當前 Namespace 里的 Role 對象。
下面創建這些對象
1$?kubectl???create?-f?zhanmin-sa-role.yaml?2role.rbac.authorization.k8s.io/zhanmin-sa-role?created
3$?kubectl??create?-f??zhanmin-sa-rolebinding.yaml?
4rolebinding.rbac.authorization.k8s.io/zhanmin-sa-rolebinding?created
現在可以去之前部署的kubernetes-dashboard上驗證權限
獲取當前Service Account的Secret信息
2zhanmin-sa-token-x6gxs???????????????????????????kubernetes.io/service-account-token???3??????136m
3$?kubectl???get?secret???zhanmin-sa-token-x6gxs??-o?jsonpath={.data.token}?-n?kube-system?|base64?-d
4eyJhbGciOiJSUzI1NiIsImtpZCI6InJCZFhYLTVRc2E4STlGVVN0VzEwWlc2M1VGMVF0ZDZFaFdJQlc3V2RLMzAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VeXN
現在可以去之前部署的kubernetes-dashboard上驗證權限
命名空間修改為kube-system,因為上面我們已經說了Service Account只對當前的namespace有效。
可以看到,權限是符合我們上面的定義,只可以查看Pod和Deployments對象,查看其他資源比如SVC顯示是沒有數據的。后面我們可以根據自己的需求去查詢API對象修改相應的權限規則。
. 3. ?ClusterRole 和 ClusterRoleBinding
上面的Role和RoleBinding只可以在他們自己的命名空間中有效,如果我們需要一個具有全部命名空間或者對節點有權限的角色時,就需要使用ClusterRole 和 ClusterRoleBinding 對象來做授權了。
ClusterRole 和 ClusterRoleBinding 這兩個 API 對象的用法跟 Role 和 RoleBinding 幾乎完全一樣。不一樣的是,它們的定義里,沒有了 Namespace 字段,權限可以作用于整個集群。
創建ClusterRole集群角色 ?clusterrole.yaml
1kind:?ClusterRole2apiVersion:?rbac.authorization.k8s.io/v1
3metadata:
4??name:?clusterrole-anmin
5rules:
6-?apiGroups:?[""]
7??resources:?["pods"]
8??verbs:?["get",?"watch",?"list"]
含義為:名為“clusterrole-anmin”的集群角色可以對集群所有命名空間的Pod進行“GET、Watch、List” 操作。
在Role 或者 ClusterRole 里面,如果要賦予用戶 example-user 所有權限,那你就可以給它指定一個 verbs 字段的全集,如下所示:
1verbs:?["get",?"list",?"watch",?"create",?"update",?"patch",?"delete"]創建 ClusterRoleBinding集群角色綁定 ?ClusterRoleBinding.yaml
1kind:?ClusterRoleBinding2apiVersion:?rbac.authorization.k8s.io/v1
3metadata:
4??name:?example-clusterrolebinding
5subjects:
6-?kind:?User
7??name:?user-anmin
8??apiGroup:?rbac.authorization.k8s.io
9roleRef:
10??kind:?ClusterRole
11??name:?clusterrole-anmin
12??apiGroup:?rbac.authorization.k8s.io
含義為:subjects字段定義被作用者用戶為“user-anmin”,roleRef字段定義:綁定名為“clusterrole-anmin”集群角色。
在 Kubernetes 中已經內置了很多個為系統保留的 ClusterRole,它們的名字都以 system: 開頭。你可以通過 kubectl get clusterroles查看到它們。
查看集群角色
1$?kubectl?get?clusterroles?2NAME???????????????????????????????????????????????????????????????????AGE
3admin??????????????????????????????????????????????????????????????????242d
4calico-kube-controllers????????????????????????????????????????????????211d
5calico-node????????????????????????????????????????????????????????????211d
6cluster-admin??????????????????????????????????????????????????????????242d
7cluster-regular????????????????????????????????????????????????????????217d
8edit???????????????????????????????????????????????????????????????????242d
9......
查看角色的權限
1$?kubectl?describe?clusterrole?edit?2Name:?????????edit
3Labels:???????kubernetes.io/bootstrapping=rbac-defaults
4??????????????rbac.authorization.k8s.io/aggregate-to-admin=true
5Annotations:??rbac.authorization.kubernetes.io/autoupdate:?true
6PolicyRule:
7??Resources????????????????????????????????Non-Resource?URLs??Resource?Names??Verbs
8??---------????????????????????????????????-----------------??--------------??-----
9??configmaps???????????????????????????????[]?????????????????[]??????????????[create?delete?deletecollection?patch?update?get?list?watch]
10??endpoints????????????????????????????????[]?????????????????[]??????????????[create?delete?deletecollection?patch?update?get?list?watch]
11??persistentvolumeclaims???????????????????[]?????????????????[]??????????????[create?delete?deletecollection?patch?update?get?list?watch]
12??pods?????????????????????????????????????[]?????????????????[]??????????????[create?delete?deletecollection?patch?update?get?list?watch]
13??replicationcontrollers/scale?????????????[]?????????????????[]??????????????[create?delete?deletecollection?patch?update?get?list?watch]
14......
. 4. Group用戶組
Kubernetes 還擁有“用戶組”(Group)的概念,也就是一組“用戶”的意思。如果你為 Kubernetes 配置了外部認證服務的話,這個“用戶組”的概念就會由外部認證服務提供。
ServiceAccount,在 Kubernetes 里對應的“用戶”的名字是:
1system:serviceaccount:<Namespace名字>:<ServiceAccount名字>對應的內置“用戶組”的名字,就是:
1system:serviceaccounts:<Namespace名字>比如,現在我們可以在 RoleBinding 里定義如下的 subjects:
1subjects:2-?kind:?Group
3??name:?system:serviceaccounts
4??apiGroup:?rbac.authorization.k8s.io
這就意味著這個 Role 的權限規則,作用于 mynamespace 里的所有 ServiceAccount。這就用到了“用戶組”的概念。而下面這個例子:
1subjects:2-?kind:?Group
3??name:?system:serviceaccounts
4??apiGroup:?rbac.authorization.k8s.io
就意味著這個 Role 的權限規則,作用于整個系統里的所有 ServiceAccount。
總結:通過上面的實踐,我們了解了在kubernetes中用戶分為User Accounts和 Service Accounts,在我們平常的使用中會經常使用ServiceAccount。而對于權限的控制,我們需要先創建角色(Role),其實就是一組權限規則列表。然后我們分配這些權限的方式,就是通過創建 RoleBinding 對象,將被作用者(subject)Service Account和權限列表Role進行綁定,也就是Role + RoleBinding + ServiceAccount來實現。另外ClusterRole 和 ClusterRoleBinding,則是 Kubernetes 集群級別的 Role 和 RoleBinding,它們的作用范圍不受 Namespace 限制。
參考資料:
https://time.geekbang.org/column/article/42154
https://www.qikqiak.com/k8s-book/docs/30.RBAC.html
關注公眾號回復【k8s】獲取視頻教程及更多資料:
image.png總結
以上是生活随笔為你收集整理的部门角色权限rbac_k8s十 | 一文读懂基于角色的权限控制RBAC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 两个date 相差得到月份_DATE和T
- 下一篇: vb操作excel图表_EXCEL的简单