RBAC(Role-Based Access Control),它將權限授予角色(role)上,可以想像它是一個責任。對 RBAC 來說,使用者(User)是一個獨立可存取資源的主體(Subject)。這過程中被允許對一或多個 Object 執行的操作可以稱做許可(Permission),一個使用者可藉由授權而擁有多個 role。
人
O
\|/
/ \ action(verb)
Subject --------------------> Object
RBAC 中 User、Role 和 Permission 關係如下
___________________________
-----> Role | Permissions |
/ \ | |
User -----> | Operations -----> Objects |
\ / | |
-----> Role |___________________________|
RBAC 是一個限定操作的機制,用於定義誰(subject)能或不能操作(verb)哪個物件(object)。動作的發出者(subject)可以是一個 User Accoun 或是 Service Account;verb 表示要執行的操作 create、apply、delete、update、patch、edit 和 get 等;object 是指要被操作的目標資源,以 Kubernetes API 來看是以 URL 作為對象。
RBAC 支援 Role 和 ClusterRole 兩種角色,前者是 namespace 級別後者則是集群級別,對這兩類給權限時,需要用到 RoleBinding 和 ClusterRoleBinding。RoleBinding 將 role 上的 Permissions 綁定到一個或一組使用者上,此綁定只能隸屬於某一個 namespace
。ClusterRoleBinding 則用於及群集別。
在一個 namespace
下可以包含多個 Role
和 RoleBinding
對象,集群級別也是可存在多個 ClusterRole
和 ClusterRoleBinding
。一個使用者可以經由 RoleBinding
或 ClusterRoleBinding
關連至多個角色,並實現多重授權。
Role 和 RoleBinding
Role 僅是一組 permission 權限的集合,在 Role 類型的 yaml 檔中使用 rules
字段定義授權規則。下面是一個 Kubernetes Dashboard 的 Role
範例,它監視了 secrets
、configmaps
和 services
資源的權限。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
rules:
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
verbs: ["get", "update", "delete"]
# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get", "update"]
# Allow Dashboard to get metrics.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster", "dashboard-metrics-scraper"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
verbs: ["get"]
rules
下定義了規則其字段有。
- apiGroups
包含 API 組的名稱,可以使用列表方式定義,如果以
""
表示是 core API group。 - resource
要將規範應用的目標資源種類(pods、deployments…),同樣可以列表方式呈現。
ResourceAll
表示所有資源 - resourceNames 要將規範應用的目標資源種類下名稱,如果為空表示所有資源
- verbs 資源類型的操作,有 get、list、create、update、patch、watch、proxy、redirect、delete 和 deletecollection
- nonResourceURLs
定義用戶應該有權限訪問的網址列表,非
namespace
級別,因此適用於 ClusterRole 和 ClusterRoleBinding
在範例中 resources: ["services/proxy"]
表示 proxy 是 services 的子資源,因此使用 resource/subre-source
格式呈現。
以下是一個透過 kubectl create role
建立 role 資源的快速方式
kubectl create role pods-reader --verb="get,list,watch" --resource="pods,pods/log" -n test
kubectl create role service-admin --verb="*" --resource="service,services/*" -n test
role.rbac.authorization.k8s.io/service-admin created
kubectl -n test describe role service-admin
Name: service-admin
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
services/* [] [] [*]
services [] [] [*]
建立 role 後需要綁定 Role-Binding 到 subject 上才有作用。RoleBinding
用於將 Role
中定義的權限賦予一個或一組用戶,它由一組 subject
以及一個要引用來賦予這組 subject
的 Role
或 ClusterRole
組成。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: reader-resource
namespace: test
subjects: # 要綁定的 subject
- kind: User
name: kube-user1
apiGroup: rbac.authorization.k8s.io
roleRef: # 要綁定的 Role 或 ClusterRole 資源
kind: Role
name: pods-reader
apiGroup: rbac.authorization.k8s.io
透過指令方式
kubectl create rolebinding reader-resource --role=pods-reader --user=kube-user1 -n testing
- subjects
- apiGroup ServiceAccount 為 “";User 和 Group 為 “rbac.authorization.k8s.io”
- kind 所屬類別,User、Group 和 ServiceAccount
- name 名稱
- namespace 所屬的 namespace,User、Group 須為空 roleRef 的字段與 subjects 大同小異
Role 和 RoleBinding 屬於 namespace 級別,有時須注意非 namespace 級別的資源,如 PersistentVolume
、NameSpace
和 Node
等,而這些資源就得用 ClusterRole
和 ClusterRoleBinding
進行配置。
ClusterRole 和 ClusterRoleBinding
ClusterRole
能夠管理和 Role
資源一樣的准許權限外,還可以管理集群資源的授權。下面為一個 kubernetes dashboard 範例,由於不屬於 namespace 級別,因此不會有其字段。
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
rules:
# Allow Metrics Scraper to get metrics from the Metrics server
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
RoleBinding
也能將 subject 綁定 ClusterRole
資源,但權限會被 RoleBinding
所限制,也就是 ClusterRole
所賦予權限只能使用在 RoleBinding
所在的 namespace
。系統預設下建立許多的 ClusterRole
資源
○ → kubectl get clusterrole
NAME CREATED AT
admin 2021-11-27T08:03:26Z
cilium 2021-11-27T08:03:31Z
cilium-operator 2021-11-27T08:03:31Z
cluster-admin 2021-11-27T08:03:26Z
edit 2021-11-27T08:03:26Z
kubeadm:get-nodes 2021-11-27T08:03:28Z
...
創建使用者與綁定角色範例
openssl genrsa -out itachi.key 2048
openssl req -new -key itachi.key -out itachi.csr -subj "/CN=itachi/O=test"
sudo openssl x509 -req -in itachi.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out itachi.crt -days 30
kubectl config set-credentials itachi --client-certificate itachi.crt --client-key itachi.key
kubectl config set-context itachi-context --cluster=kubernetes --namespace=test --user=itachi
kubectl --context=itachi-context get pod
Error from server (Forbidden): pods is forbidden: User "itachi" cannot list resource "pods" in API group "" in the namespace "test"
發生無權限存取。此時將 Role
範例的 User 設定成 itachi 即可
kubectl --context=itachi-context get pods
No resources found in test namespace.
刪除使用者
kubectl config unset users.itachi