一 RBAC介紹
1.1 RBAC授權
基於角色的訪問控制(RBAC)是一種基於個人用戶的角色來管理對計算機或網絡資源的訪問的方法。
RBAC使用rbac.authorization.k8s.io API組來推動授權決策,允許管理員通過Kubernetes API動態配置策略。
使用--authorization-mode=RBAC開啟RBAC授權模塊功能。
RBAC API定義了四個資源對象用於描述RBAC中用戶和資源之間的連接權限:
- Role
- ClusterRole
- RoleBinding
- ClusterRoleBinding
二 RBAC詳解
2.1 Role 和 ClusterRole
RBAC API聲明了四種類型。
在RBAC API中,角色包含表示一組權限的規則。權限都是疊加的,沒有deny規則(沒有“拒絕”規則)。可以使用參數role在一個namespace中定義一個普通角色,或者在集群范圍內使用ClusterRole定義集群角色。
一個Role只能用於授予對單個命名空間內的資源的訪問權限。
示例1:在“default”命令空間中定義了一個名為“pod-reader”的角色,此角色能夠對在“default”命名空間中訪問Pod。
1 [root@k8smaster01 study]# vi pod-reader-Role.yaml 2 apiVersion: rbac.authorization.k8s.io/v1 3 kind: Role 4 metadata: 5 namespace: default 6 name: pod-reader 7 rules: 8 - apiGroups: [""] # "" indicates the core API group 9 resources: ["pods"] #資源類型 10 verbs: ["get", "watch", "list"] #操作類型
解釋:名為pod-reader的角色授予對“default”命名空間中的pod的讀取權限。
一個ClusterRole可用於授予與一個Role相同的權限,同時由於它們是群集范圍的,因此它們還可用於授予對以下內容的訪問權限:
- 集群范圍的資源(如nodes);
- non-resource endpoints(如“/healthz”);
- 跨所有命名空間(可通過kubectl get pods --all-namespaces查看)的命名空間資源(如pods)。
示例2:
1 [root@k8smaster01 study]# vi secret-reader-ClusterRole.yaml 2 apiVersion: rbac.authorization.k8s.io/v1 3 kind: ClusterRole 4 metadata: 5 # 因為ClusterRoles是針對所有命名空間,因此省略了“命名空間”。 6 name: secret-reader 7 rules: 8 - apiGroups: [""] 9 resources: ["secrets"] #資源類型 10 verbs: ["get", "watch", "list"] #操作類型
解釋:名為secret-reader的ClusterRole,授予對所有命名空間中的secrets資源的讀訪問權限。
2.2 RoleBinding 和 ClusterRoleBinding
角色綁定用於將角色與一個或一組用戶進行綁定,從而實現將對用戶進行授權的目的。它包含由(用戶)users、groups(組)、或service accounts(服務帳戶)組成的列表。
角色綁定也分為普通角色綁定和集群角色綁定。
集群角色是跨命名空間的,但普通角色有命名空間屬性,因此普通角色綁定只能引用同一個命名空間下的角色。
示例1:普通角色綁定示例。
1 kind: RoleBinding 2 apiVersion: rbac.authorization.k8s.io/v1 3 metadata: 4 name: read-pods 5 namespace: default #普通角色綁定指定namespace 6 subjects: #主體參數 7 - kind: User #指定主體類型為user 8 name: jane #指定user用戶名 9 apiGroup: rbac.authorization.k8s.io 10 roleRef: #角色引用 11 kind: Role #類型為普通角色 12 name: pod-reader #角色名 13 apiGroup: rbac.authorization.k8s.io
解釋:在“default”命名空間中,角色綁定將用戶“jane”和“pod-reader”的普通角色進行綁定,從而授予“jane”具有在“default”命名空間的“pod-reader”的普通角色所定義的相應權限。如2.1示例所創建的“pod-reader”的普通角色權限為:對“default”命名空間中的pod的具有讀取權限。
普通角色綁定也可以通過引用集群角色授予訪問權限,當需要主體對資源的訪問僅限與本命名空間。
則可以定義整個集群的公共角色集合(將相應的權限追加的一個集合所形成的集群角色),然后在多個命名空間中進行復用。
示例2:使用普通角色綁定綁定集群角色,並指明特定的命名空間。
1 [root@k8smaster01 study]# vi dave_RoleBinding.yaml 2 kind: RoleBinding 3 apiVersion: rbac.authorization.k8s.io/v1 4 metadata: 5 name: read-secrets 6 namespace: development #指定特定的命名空間 7 subjects: #主體參數 8 - kind: User #指定主體類型為user 9 name: dave #指定user用戶名 10 apiGroup: rbac.authorization.k8s.io 11 roleRef: #角色引用 12 kind: ClusterRole #類型為集群角色 13 name: secret-reader #角色名 14 apiGroup: rbac.authorization.k8s.io
解釋:如上的普通角色綁定,實現允許名為dave的user主體,在development的命名空間中,具有名為secret-reader的集群角色的所有權限。即普通角色綁定引用的實體為集群角色,但也只能訪問特定命名空間(如上為development)的secrets資源。
集群角色綁定可以被用來在集群層面和整個命名空間進行授權,即實現集群角色在集群層面的授權。
示例3:允許在“manager”組的用戶能夠訪問所有命名空間中的secrets資源。
1 [root@k8smaster01 study]# vi manager_ClusterRoleBinding.yaml 2 kind: ClusterRoleBinding 3 apiVersion: rbac.authorization.k8s.io/v1 4 metadata: 5 name: read-secrets-global 6 subjects: #主體參數 7 - kind: Group #指定主體類型為group 8 name: manager #指定group組名 9 apiGroup: rbac.authorization.k8s.io 10 roleRef: #角色引用 11 kind: ClusterRole #類型為集群角色 12 name: secret-reader #角色名 13 apiGroup: rbac.authorization.k8s.io
2.3 默認角色
API服務器創建了一組默認ClusterRole和ClusterRoleBinding對象。其中格式為system:前綴的表示該資源由系統基礎設施所擁有。手動修改該類資源可能導致集群功能異常,若system:node的ClusterRole,定義了kubelet的權限。
提示:所有默認群集角色和角色綁定都標有kubernetes.io/bootstrapping=rbac-defaults。
三 資源與主體
3.1 資源介紹
在Kubernets中,主要的資源包括:Pods、Nodes、Services、Deployment、Replicasets、Statefulsets、Namespace、Persistents、Secrets和ConfigMaps等。
同時,有些資源下面存在子資源,例如:Pod下就存在log子資源。
示例1:普通角色的資源列表。
1 [root@k8smaster01 study]# vi pod-and-pod_log.yaml 2 kind: Role 3 apiVersion: rbac.authorization.k8s.io/v1 4 metadata: 5 namespace: default 6 name: pod-and-pod-logs-reader 7 rules: 8 - apiGroups: [""] 9 resources: ["pods","pods/log"] 10 verbs: ["get","list"]
解釋:如上限定在default的命名空間的名為pod-and-pod-logs-reader的普通角色,對pod和pods/log資資源就有get和list的權限。
示例2:更精細粒度的資源控制,可通過resourceNamess指定特定的資源實例,以限制角色只能夠對具體的某個實例進行訪問控制。
1 [root@k8smaster01 study]# vi updater_configmap.yaml 2 kind: Role 3 apiVersion: rbac.authorization.k8s.io/v1 4 metadata: 5 namespace: default 6 name: configmap-updater 7 rules: 8 - apiGroups: [""] 9 resources: ["configmaps"] 10 resourceNames: ["my-configmap"] 11 verbs: ["update","get"]
解釋:如上限定在default的命名空間的名為configmap-updater的普通角色,對名為my-configmap的configmaps類型的特定資源,具有update和get權限。
3.2 主體介紹
RBAC授權中的主體可以是組,用戶或者服務帳戶。用戶通過字符串表示,比如“alice”、“bob@example.com”等,具體的形式取決於管理員在認證模塊中所配置的用戶名。
system: 被保留作為用來Kubernetes系統內部使用,因此不能作為用戶的前綴。組也有認證模塊提供,格式與用戶類似。
示例1:類型為user(用戶)。
1 subjects: 2 - kind: User 3 name: "alice@example.com" 4 apiGroup: rbac.authorization.k8s.io
示例2:類型為group(組)。
1 subjects: 2 - kind: Group 3 name: "frontend-admins" 4 apiGroup: rbac.authorization.k8s.io
示例3:查看default的服務賬戶。
1 subjects: 2 - kind: ServiceAccount 3 name: default 4 namespace: kube-system
示例4:設置所有qa命名空間的服務賬戶。
1 subjects: 2 - kind: Group 3 name: system:serviceaccounts:qa 4 apiGroup: rbac.authorization.k8s.io
示例5:設置所有命名空間的所有服務賬戶。
1 subjects: 2 - kind: Group 3 name: system:serviceaccounts 4 apiGroup: rbac.authorization.k8s.io
示例6:所有被認證的用戶。
1 subjects: 2 - kind: Group 3 name: system:authenticated 4 apiGroup: rbac.authorization.k8s.io
示例7:所有未被認證的用戶。
1 subjects: 2 - kind: Group 3 name: system:unauthenticated 4 apiGroup: rbac.authorization.k8s.io
示例8:所有用戶。
1 subjects: 2 - kind: Group 3 name: system:authenticated 4 apiGroup: rbac.authorization.k8s.io 5 - kind: Group 6 name: system:unauthenticated 7 apiGroup: rbac.authorization.k8s.io
四 角色相關命令
4.1 創建角色
[root@master ~]# kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
解釋:創建一個名為“pod-reader”的Role,允許用戶在pod上執行“get”,“watch”和“list”。
[root@master ~]# kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --namespace=anotherpod
解釋:創建一個指定了namespace為anotherpod的名為“pod-reader”的Role,對資源名為readablepod的pod具有get權限。
[root@master ~]# kubectl create role foo --verb=get,list,watch --resource=replicasets.apps
解釋:創建一個role名為“foo”的Role,允許用戶在replicasets.apps上執行“get”,“watch”和“list”。
[root@master ~]# kubectl create role foo --verb=get,list,watch --resource=pods,pods/status
解釋:創建一個role名為“foo”的Role,允許用戶在pods及pods/status子資源上上執行“get”,“watch”和“list”。
4.2 創建集群角色
[root@master ~]# kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
解釋:創建一個名為“pod-reader”的clusterrole,允許集群角色在pod上執行“get”,“watch”和“list”。
[root@master ~]# kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod --namespace=anotherpod
解釋:創建一個指定了namespace為anotherpod的名為“pod-reader”的Rclusterrole,對資源名為readablepod的pod具有get權限。
[root@master ~]# kubectl create clusterrole foo --verb=get,list,watch --resource=replicasets.apps
解釋:創建一個clusterrole名為“foo”的clusterrole,允許集群角色在replicasets.apps上執行“get”,“watch”和“list”。
[root@master ~]# kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status
解釋:創建一個clusterrole名為“foo”的clusterrole,允許集群角色在pods及pods/status子資源上上執行“get”,“watch”和“list”。
[root@master ~]# kubectl create clusterrole "foo" --verb=get --non-resource-url=/logs/*
解釋:創建一個clusterrole名為“foo”的clusterrole,指定了non-resource為/logs/*的“get”權限。
4.3 權限和角色綁定
[root@master ~]# kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
解釋:在acme的namespace中,將admin的clusterrole和bob用戶進行綁定。
[root@master ~]# kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme
解釋:在acme的namespace中,將view的clusterrole和myapp服務賬號進行綁定。
[root@master ~]# kubectl create rolebinding myappnamespace-myapp-view-binding --clusterrole=view --serviceaccount=myappnamespace:myapp --namespace=acme
解釋:在acme的namespace中,將view的clusterrole和myapp的namespace中的服務賬號進行綁定。
4.4 權限和集群角色綁定
[root@master ~]# kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
解釋:在整個集群中,將cluster-admin的clusterrole和root用戶進行綁定。
[root@master ~]# kubectl create clusterrolebinding kube-proxy-binding --clusterrole=system:node-proxier --user=system:kube-proxy
解釋:在整個集群中,將system:node-proxier的clusterrole和system:kube-proxy用戶進行綁定。
[root@master ~]# kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp
解釋:在整個集群中,將view的clusterrole和myapp中的acme服務賬戶進行綁定。
提示:roles和clusterroles的區別在於roles只能對某個命令空間內的資源定義權限。而集群角色定義的權限都是針對整個集群的命名空間的。
更多RBAC參考:https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole
4.5 相關對比
ClusterRole和ClusterRoleBinding是針對整個Cluster范圍內有效的,無論用戶或資源所在的namespace是什么;
Role和RoleBinding的作用范圍是局限在某個k8s namespace中的。
kubernetes在安裝之初就已經生成了許多role、rolebinding、clusterrole和clusterrolebinding,它們也是屬於kubernetes資源的一部分,可通過get、describe等命令查看,如下:
[root@master ~]# kubectl get role -n kube-system
[root@master ~]# kubectl describe role extension-apiserver-authentication-reader -n kube-system
五 服務賬戶權限
5.1 服務賬戶
默認情況下,RBAC策略授予控制板組件、Node和控制器作用域的權限,但是未授予“kube-system”命名空間外服務帳戶的訪問權限。同時允許管理員按照需要將特定角色授予服務帳戶。
5.2 服務賬號授權
- 授予角色給一個指定Pod的服務帳戶
需要在Pod規格中指定serviveAccountName,同時此服務帳戶已被創建(通過API、kubectl create serviceaccount等已經成功創建)。
示例1:在“my-namespace”命名空間內,授予”my-sa”服務帳戶“view”集群角色。
1 kubectl create rolebinding my-sa-view \ 2 --clusterrole=view \ 3 --serviceaccount=my-namespace:my-sa \ 4 --namespace=my-namespace
- 在一個命名空間授予“view”集群角色給“default”服務帳戶
如果Pod沒有指定serviceAccountName,它將使用”default” 服務帳戶。
示例2:在“my-namespace”命名空間內,授予”default”服務帳戶“view”集群角色
1 kubectl create rolebinding default-view \ 2 --clusterrole=view \ 3 --serviceaccount=my-namespace:default \ 4 --namespace=my-namespace
提示:在”kube-system“命名空間中,很多插件作為”default“服務帳戶進行運行。為了允許default能訪問這些插件,在“kube-system”命名空間中授予”cluster-admin“角色給”default”帳戶。
1 kubectl create clusterrolebinding add-on-cluster-admin \ 2 --clusterrole=cluster-admin \ 3 --serviceaccount=kube-system:default
- 在一個命名空間中,授予角色給所有的服務帳戶
如果希望在一個命名空間中的所有Pod都擁有一個角色,而不管它們所使用的服務帳戶,可以授予集群角色給服務帳戶組。
示例3:在“my-namespace”命名空間中,將”view“集群角色授予“system:serviceaccounts:my-namespace“組。
1 kubectl create rolebinding serviceaccounts-view \ 2 --clusterrole=view \ 3 --group=system:serviceaccounts:my-namespace \ 4 --namespace=my-namespace
- 在整個集群中授予一個角色給所有的服務帳戶 (不推薦)
如果不想按照每個命名空間管理權限,可以在整個集群的訪問進行授權。
示例4:在整個集群層面,將”view“集群角色授予“sytem:serviceaccounts“。
1 kubectl create clusterrolebinding serviceaccounts-view \ 2 --clusterrole=view \ 3 --group=system:serviceaccounts
- 在整個集群中授予超級用戶訪問所有的服務帳戶 (強烈不推薦)
如果對訪問權限不太重視,可以授予超級用戶訪問所有的服務帳戶。
1 kubectl create clusterrolebinding serviceaccounts-cluster-admin \ 2 --clusterrole=cluster-admin \ 3 --group=system:serviceaccounts
- 寬松的RBAC權限(致命危險)
下面的策略允許所有的服務帳戶作為集群管理員。在容器中運行的Pod將自動的收取到服務帳戶證書,並執行所有的API行為。包括查看保密字典恩將和修改權限,這是不被推薦的訪問策略。
1 kubectl create clusterrolebinding permissive-binding \ 2 --clusterrole=cluster-admin \ 3 --user=admin \ 4 --user=kubelet \ 5 --group=system:serviceaccounts
參考:https://www.cnblogs.com/linuxk/p/9772117.html
http://docs.kubernetes.org.cn/148.html
https://www.kubernetes.org.cn/4062.html