Kubernetes 基於 RBAC 的授權(十六)
一、RBAC介紹
在Kubernetes中,授權有ABAC(基於屬性的訪問控制)、RBAC(基於角色的訪問控制)、Webhook、Node、AlwaysDeny(一直拒絕)和AlwaysAllow(一直允許)這6種模式。
從1.6版本起,Kubernetes 預設啟用RBAC訪問控制策略。從1.8開始,RBAC已作為穩定的功能。通過設定--authorization-mode=RBAC
,啟用RABC。在RABC API中,通過如下的步驟進行授權:
定義角色:在定義角色時會指定此角色對於資源的訪問控制的規則;
繫結角色:將主體與角色進行繫結,對使用者進行訪問授權。
1.1、角色和叢集角色
在 RBAC API 中,角色包含代表權限集合的規則。在這裡,許可權只有被授予,而沒有被拒絕的設定。在 Kubernetes 中有兩類角色,即普通角色(Role)和叢集角色(ClusterRole)。可以通過Role
ClusterRole
定義叢集範圍的角色。一個Role
只能被用來授予訪問單一命令空間中的資源。下面是在 default 命令空間中定義了一個名為 pod-reader 的角色,此角色能夠對在 default 名稱空間中訪問 Pod:
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: default name: pod-reader rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"]
ClusterRole
可用於授予與Role
相同的許可權。他們能夠被授予如下資源的許可權:
- 叢集範圍的資源(類似於Node)
- 非資源端點(類似於”/healthz”)
- 叢集中所有名稱空間的資源(類似Pod)
下面的ClusterRole
可用於授予對任何特定namespaces
中的祕密的讀取訪問許可權,或跨所有名稱空間的訪問許可權。
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: # "namespace" omitted since ClusterRoles are not namespaced name: secret-reader rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"]
1.2、RoleBinding 和 ClusterRoleBinding
角色繫結用於將角色與一個或一組使用者進行繫結,從而實現將對使用者進行授權的目的。主體分為使用者、組和服務帳戶。角色繫結也分為角色普通角色繫結和叢集角色繫結。角色繫結只能引用同一個名稱空間下的角色。
在下面的例子中,在 default 名稱空間中角色繫結將 jane 使用者和 pod-reader 角色進行了繫結,這就授予了 jane 能夠訪問 default 名稱空間下的 Pod。
# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
角色繫結也可以通過引用叢集角色授予訪問許可權,當主體對資源的訪問僅限與本名稱空間,這就允許管理員定義整個叢集的公共角色集合,然後在多個名稱空間中進行復用。
例如,下面的角色繫結引用了叢集角色,但是 dave 使用者也僅僅只能讀取 development 名稱空間中的 secret s資源:
# This role binding allows "dave" to read secrets in the "development" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-secrets
namespace: development # This only grants permissions within the "development" namespace.
subjects:
- kind: User
name: dave # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
叢集角色可以被用來在叢集層面和整個名稱空間進行授權。下面的示例允許在 manager 組的使用者能夠訪問所有名稱空間中的保密字典資源。
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind:ClusterRoleBinding
apiVersion:rbac.authorization.k8s.io/v1
metadata:
name:read-secrets-global
subjects:
- kind:Group
name:manager
apiGroup:rbac.authorization.k8s.io
roleRef:
kind:ClusterRole
name:secret-reader
apiGroup:rbac.authorization.k8s.io
1.3、資源
在Kubernets中,主要的資源包括:Pods、Nodes、Services、Deployment、Replicasets、Statefulsets、Namespace、Persistents、Secrets和ConfigMaps等。另外,有些資源下面存在子資源,例如:Pod下就存在log子資源:
GET /api/v1/namespaces/{namespace}/pods/{name}/log
下面的例子顯示, pod-and-pod-logs-reader 角色能夠對 pods 和 pods/log 進行訪問:
kind:Role
apiVersion:rbac.authorization.k8s.io/v1
metadata:
namespace:default
name:pod-and-pod-logs-reader
rules:
- apiGroups:[""]
resources:["pods","pods/log"]
verbs:["get","list"]
也可以通過 resourceNamess 指定特定的資源例項,以限制角色只能夠對例項進行訪問控制:
kind:Role
apiVersion:rbac.authorization.k8s.io/v1
metadata:
namespace:default
name:configmap-updater
rules:
- apiGroups:[""]
resources:["configmaps"]
resourceNames:["my-configmap"]
verbs:["update","get"]
1.4、主體
RBAC授權中的主體可以是組,使用者或者服務帳戶。使用者通過字串表示,比如“alice”、 “[email protected].com”等,具體的形式取決於管理員在認證模組中所配置的使用者名稱。system: 被保留作為用來 Kubernetes 系統使用,因此不能作為使用者的字首。組也有認證模組提供,格式與使用者類似。
在角色繫結主體的例子:
名稱為 “[email protected]”使用者:
subjects:
- kind:User
name:"[email protected]"
apiGroup:rbac.authorization.k8s.io
名稱為“frontend-admins”的組:
subjects:
- kind:Group
name:"frontend-admins"
apiGroup:rbac.authorization.k8s.io
在 kube-system 名稱空間中,名稱為“default”的服務帳戶:
subjects:
- kind:ServiceAccount
name:default
namespace:kube-system
在“qa”名稱空間中,所有的服務帳戶:
subjects:
- kind:Group
name:system:serviceaccounts:qa
apiGroup:rbac.authorization.k8s.io
所有的服務帳戶:
subjects:
- kind:Group
name:system:serviceaccounts
apiGroup:rbac.authorization.k8s.io
所有被認證的使用者 (version 1.5+):
subjects:
- kind:Group
name:system:authenticated
apiGroup:rbac.authorization.k8s.io
所有未被認證的使用者 (version 1.5+):
subjects:
- kind:Group
name:system:unauthenticated
apiGroup:rbac.authorization.k8s.io
所有使用者(version 1.5+):
subjects:
- kind:Group
name:system:authenticated
apiGroup:rbac.authorization.k8s.io
- kind:Group
name:system:unauthenticated
apiGroup:rbac.authorization.k8s.io
二、命令列工具
Kubernetes可以通過命令工具進行角色繫結。
2.1、kubectl create rolebinding
在指定的名稱空間中進行角色繫結:
1)在acme
名稱空間中,將admin
叢集角色授予bob
使用者:
$ kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
2)在acme
名稱空間中,將admin
叢集角色授予acme:myapp
服務帳戶:
$ kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme
2.2、kubectl create clusterrolebinding
在整個叢集中進行角色繫結:
1)在整個叢集中,授予cluster-admin
叢集角色給root
使用者:
$ kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
2)在整個叢集中,授予system:node
叢集角色給kubelet
使用者:
$ kubectl create clusterrolebinding kubelet-node-binding --clusterrole=system:node --user=kubelet
3)在整個叢集中,授予view
叢集角色給acme:myapp
服務帳戶:
$ kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp
三、服務帳戶許可權
預設情況下,RBAC策略授予控制板元件、Node和控制器作用域的許可權,但是未授予kube-system
名稱空間外服務帳戶的訪問許可權。這就允許管理員按照需要將特定角色授予服務帳戶。
從最安全到最不安全的順序,方法如下:
- 1)授予角色給一個指定應用的服務帳戶(最佳實踐)
這要求在Pod規格中指定ServiveAccountName
,同時此服務帳戶已被建立(通過API、kubectl create serviceaccount等)。例如,在my-namespace
名稱空間內,授予my-sa
服務帳戶view
叢集角色:
kubectl create rolebinding my-sa-view \
--clusterrole=view \
--serviceaccount=my-namespace:my-sa \
--namespace=my-namespace
- 2)在一個名稱空間授予
view
叢集角色給default
服務帳戶
如果應用沒有指定serviceAccountName,它將使用default
服務帳戶。例如,例如,在my-namespace
名稱空間內,授予default
服務帳戶view
叢集角色:
kubectl create rolebinding default-view \
--clusterrole=view \
--serviceaccount=my-namespace:default \
--namespace=my-namespace
當前,在 kube-system 名稱空間中,很多外掛作為 default 服務帳戶進行執行。為了允許超級使用者訪問這些外掛,在 kube-system 名稱空間中授予 cluster-admin 角色給 default 帳戶。
$ kubectl create clusterrolebinding add-on-cluster-admin \
--clusterrole=cluster-admin \
--serviceaccount=kube-system:default
- 3)在一個名稱空間中,授予角色給所有的服務帳戶:
如果希望在一個名稱空間中的所有應用都擁有一個角色,而不管它們所使用的服務帳戶,可以授予角色給服務帳戶組。例如,在 my-namespace 名稱空間中,將 view 叢集角色授予 system:serviceaccounts:my-namespace 組:
$ kubectl create rolebinding serviceaccounts-view \
--clusterrole=view \
--group=system:serviceaccounts:my-namespace \
--namespace=my-namespace
- 4)在整個叢集中授予一個角色給所有的服務帳戶 (不推薦)
如果不想按照每個名稱空間管理許可權,可以在整個叢集的訪問進行授權。例如,在整個叢集層面,將 view 叢集角色授予 sytem:serviceaccounts :
$ kubectl create clusterrolebinding serviceaccounts-view \
--clusterrole=view \
--group=system:serviceaccounts
- 5)在整個叢集中授予超級使用者訪問所有的服務帳戶 (強烈不推薦)
如果對訪問許可權不太重視,可以授予超級使用者訪問所有的服務帳戶。
$ kubectl create clusterrolebinding serviceaccounts-cluster-admin \
--clusterrole=cluster-admin \
--group=system:serviceaccounts
- 6)寬鬆的RBAC許可權
下面的策略允許所有的服務帳戶作為叢集管理員。在容器中執行的應用將自動的收取到服務帳戶證書,並執行所有的API行為。包括檢視保密字典恩將和修改許可權,這是不被推薦的訪問策略。
$ kubectl create clusterrolebinding permissive-binding \
--clusterrole=cluster-admin \
--user=admin \
--user=kubelet \
--group=system:serviceaccounts
官方文件:https://kubernetes.io/docs/reference/access-authn-authz/rbac/