提升CKA考試勝算:一文帶你全面了解RBAC權(quán)限控制!
一、RBAC概述
RBAC引入了四個(gè)新的頂級(jí)資源對(duì)象。Role、ClusterRole、RoleBinding、 ClusterRoleBinding。同其他 API 資源對(duì)象一樣,用戶可以使用 kubectl 或者 API 調(diào)用等 方式操作這些資源對(duì)象。kubernetes集群相關(guān)所有的交互都通過(guò)apiserver來(lái)完成,對(duì)于這樣集中式管理的系統(tǒng)來(lái)說(shuō),從1.6版本起,K8S默認(rèn)啟用RBAC訪問(wèn)控制策略,目前RBAC已作為穩(wěn)定的功能,通過(guò)啟動(dòng)文件kube-apiserver.service中的-authorization-mode=RBAC來(lái)啟用RABC。在RBAC API中,通過(guò)如下步驟進(jìn)行授權(quán):
- 「定義角色」:在定義角色時(shí)會(huì)指定此角色對(duì)于資源訪問(wèn)控制的規(guī)則;
- 「綁定角色」:將主體與角色進(jìn)行綁定,對(duì)用戶進(jìn)行訪問(wèn)授權(quán);
二、RBAC資源對(duì)象
在 Kubernetes 中,RBAC 是一種強(qiáng)大的訪問(wèn)控制機(jī)制,用于管理對(duì)集群資源的訪問(wèn)權(quán)限。RBAC 可以幫助管理員精確地控制用戶、ServiceAccount 或其他實(shí)體對(duì) Kubernetes API 中資源的操作權(quán)限。RBAC 基于角色的授權(quán)模型使得管理員可以定義角色和角色綁定,從而實(shí)現(xiàn)對(duì)不同用戶或?qū)嶓w的訪問(wèn)權(quán)限控制。RBAC 由四個(gè)基本概念組成:
- 「角色(Role)」:角色定義了一組操作權(quán)限,例如對(duì)某個(gè)命名空間下資源的讀取、創(chuàng)建或刪除等操作。
- 「角色綁定(RoleBinding)」:角色綁定將特定的角色授予 User、Group 或者 ServiceAccount,從而賦予它們相應(yīng)的權(quán)限。
- 「集群角色(ClusterRole)」:類似于角色,但作用范圍更廣,可以授權(quán)對(duì)整個(gè)集群中資源的操作權(quán)限。
- 「集群角色綁定(ClusterRoleBinding)」:將集群角色綁定給 User、Group 或者 ServiceAccount,授予它們?cè)谡麄€(gè)集群范圍內(nèi)的權(quán)限。
三、角色
一個(gè)角色就是一組權(quán)限的集合,這里的權(quán)限都是許可形式的,「不存在拒絕的規(guī)則」。Role 總是用來(lái)在某個(gè)名字空間內(nèi)設(shè)置訪問(wèn)權(quán)限;在你創(chuàng)建 Role 時(shí),你必須指定該 Role 所屬的名字空間。與之相對(duì),ClusterRole 則是一個(gè)集群作用域的資源。這兩種資源的名字不同(Role 和 ClusterRole) 是因?yàn)?Kubernetes 對(duì)象要么是名字空間作用域的,要么是集群作用域的,不可兩者兼具。ClusterRole 有若干用法。你可以用它來(lái):
- 定義對(duì)某名字空間域?qū)ο蟮脑L問(wèn)權(quán)限,并將在個(gè)別名字空間內(nèi)被授予訪問(wèn)權(quán)限;
- 為名字空間作用域的對(duì)象設(shè)置訪問(wèn)權(quán)限,并被授予跨所有名字空間的訪問(wèn)權(quán)限;
- 為集群作用域的資源定義訪問(wèn)權(quán)限。
如果你希望在名字空間內(nèi)定義角色,應(yīng)該使用 Role;如果你希望定義集群范圍的角色,應(yīng)該使用 ClusterRole。
1.Role 示例
(1) 命令方式創(chuàng)建
如果忘記了命令方式,也可以通過(guò)kubectl create role --help查閱幫助,如下圖:
help
kubectl create role pod-reader \
--verb=get,list,watch \
--resource=pods
- verb:是指定這個(gè)角色包含哪些操作,如get、list、watch
- resource:是指這個(gè)角色能操作哪些資源對(duì)象,如pods
- resource-name:指定對(duì)特定資源實(shí)例的訪問(wèn)權(quán)限。
(2) 資源清單方式創(chuàng)建
下面是一個(gè)位于 default 名字空間的 Role 的示例,可用來(lái)授予對(duì) Pod 的讀訪問(wèn)權(quán)限:
apiVersion:rbac.authorization.k8s.io/v1
kind:Role
metadata:
namespace:default
name:pod-reader
rules:
-apiGroups:[""]# "" 標(biāo)明 core API 組
resources:["pods"]
verbs:["get","watch","list"]
2.ClusterRole 示例
ClusterRole 同樣可以用于授予 Role 能夠授予的權(quán)限。因?yàn)?ClusterRole 屬于集群范圍,所以它也可以為以下資源授予訪問(wèn)權(quán)限:
- 集群范圍資源(比如節(jié)點(diǎn)(Node))
- 非資源端點(diǎn)(比如 /healthz)
- 跨名字空間訪問(wèn)的名字空間作用域的資源(如 Pod)
比如,你可以使用 ClusterRole 來(lái)允許某特定用戶執(zhí)行 kubectl get pods --all-namespaces下面是一個(gè) ClusterRole 的示例,可用來(lái)為任一特定名字空間中的 Secret 授予讀訪問(wèn)權(quán)限, 或者跨名字空間的訪問(wèn)權(quán)限(取決于該角色是如何綁定的):
命令行創(chuàng)建:
kubectl create clusterrole secret-reader \
--verb=get,watch,list \
--resource=secrets
資源清單創(chuàng)建:
apiVersion:rbac.authorization.k8s.io/v1
kind:ClusterRole
metadata:
# "namespace" 被忽略,因?yàn)?ClusterRoles 不受名字空間限制
name:secret-reader
rules:
-apiGroups:[""]
# 在 HTTP 層面,用來(lái)訪問(wèn) Secret 資源的名稱為 "secrets"
resources:["secrets"]
verbs:["get","watch","list"]
三、角色綁定和集群角色綁定
角色綁定(Role Binding)是將角色中定義的權(quán)限賦予一個(gè)或者一組用戶。它包含若干「主體(Subject」)(用戶、組或服務(wù)賬戶)的列表和對(duì)這些主體所獲得的角色的引用。RoleBinding 在指定的名字空間中執(zhí)行授權(quán),而 ClusterRoleBinding 在集群范圍執(zhí)行授權(quán)。一個(gè) RoleBinding 可以引用同一的名字空間中的任何Role。或者,一個(gè)RoleBinding可以引用某 ClusterRole并將該 ClusterRole 綁定到 RoleBinding 所在的名字空間。如果你希望將某 ClusterRole綁定到集群中所有名字空間,你要使用ClusterRoleBinding。
RoleBinding 示例
下面的例子中的RoleBinding 將pod-reader Role授予在default名字空間中的用戶 jane。這樣,用戶 jane 就具有了讀取 default名字空間中所有Pod的權(quán)限。
命令行創(chuàng)建:
kubectl create rolebinding read-pods \
--role=pod-reader \
--user=jance \
--namespace=default
詳細(xì)清楚可以使用幫助文件 kubectl create rolebinding --help。
資源清單創(chuàng)建:
apiVersion:rbac.authorization.k8s.io/v1
# 此角色綁定允許 "jane" 讀取 "default" 名字空間中的 Pod
# 你需要在該名字空間中有一個(gè)名為 “pod-reader” 的 Role
kind:RoleBinding
metadata:
name:read-pods
namespace:default
subjects:
# 你可以指定不止一個(gè)“subject(主體)”
-kind:User
name:jane# "name" 是區(qū)分大小寫(xiě)的
apiGroup:rbac.authorization.k8s.io
roleRef:
# "roleRef" 指定與某 Role 或 ClusterRole 的綁定關(guān)系
kind:Role# 此字段必須是 Role 或 ClusterRole
name:pod-reader# 此字段必須與你要綁定的 Role 或 ClusterRole 的名稱匹配
apiGroup:rbac.authorization.k8s.io
四、ClusterRoleBinding 示例
要跨整個(gè)集群完成訪問(wèn)權(quán)限的授予,你可以使用一個(gè)ClusterRoleBinding。下面的ClusterRoleBinding 允許manager組內(nèi)的所有用戶訪問(wèn)任何名字空間中的 Secret。
命令行創(chuàng)建:
kubectl create clusterrolebinding read-secrets-global\
--group=manager \
--clusterrole=secret-reader
資源清單創(chuàng)建:
apiVersion:rbac.authorization.k8s.io/v1
# 此集群角色綁定允許 “manager” 組中的任何人訪問(wèn)任何名字空間中的 Secret 資源
kind:ClusterRoleBinding
metadata:
name:read-secrets-global
subjects:
-kind:Group
name:manager# 'name' 是區(qū)分大小寫(xiě)的
apiGroup:rbac.authorization.k8s.io
roleRef:
kind:ClusterRole
name:secret-reader
apiGroup:rbac.authorization.k8s.io
五、資源
在Kubernetes API 中,大多數(shù)資源都是使用對(duì)象名稱的字符串表示來(lái)呈現(xiàn)與訪問(wèn)的。例如,對(duì)于Pod應(yīng)使用 pods。RBAC 使用對(duì)應(yīng) API 端點(diǎn)的 URL 中呈現(xiàn)的名字來(lái)引用資源。有一些Kubernetes API 涉及子資源(subresource),例如 Pod 的日志。對(duì) Pod 日志的請(qǐng)求看起來(lái)像這樣:
GET /api/v1/namespaces/{namespace}/pods/{name}/log
在這里,pods 對(duì)應(yīng)名字空間作用域的 Pod 資源,而 log 是 pods 的子資源。在 RBAC 角色表達(dá)子資源時(shí),使用斜線(/)來(lái)分隔資源和子資源。要允許某主體讀取 pods 同時(shí)訪問(wèn)這些 Pod 的 log 子資源,你可以這樣寫(xiě):
apiVersion:rbac.authorization.k8s.io/v1
kind:Role
metadata:
namespace:default
name:pod-and-pod-logs-reader
rules:
-apiGroups:[""]
resources:["pods","pods/log"]
verbs:["get","list"]
對(duì)于某些請(qǐng)求,也可以通過(guò) resourceNames 列表按名稱引用資源。在指定時(shí),可以將請(qǐng)求限定為資源的單個(gè)實(shí)例。下面的例子中限制可以 get 和 update 一個(gè)名為 my-configmap 的 ConfigMap:
命令行創(chuàng)建:
kubectl create role configmap-updater \
--verb=update,get \
--resource=configmaps \
--resource-name=my-configmap
資源清單創(chuàng)建:
apiVersion:rbac.authorization.k8s.io/v1
kind:Role
metadata:
namespace:default
name:configmap-updater
rules:
-apiGroups:[""]
# 在 HTTP 層面,用來(lái)訪問(wèn) ConfigMap 資源的名稱為 "configmaps"
resources:["configmaps"]
resourceNames:["my-configmap"]
verbs:["update","get"]
六、主體
RoleBinding或者ClusterRoleBinding可綁定角色到某「主體(Subject)」 上。主體可以是組,用戶或者服務(wù)賬戶。K8s的用戶分兩種,一種是普通用戶,一種是ServiceAccount(服務(wù)賬戶)。
1.普通用戶
普通用戶是假定被外部或獨(dú)立服務(wù)管理的。管理員分配私鑰。平時(shí)常用的kubectl命令都是普通用戶執(zhí)行的。如果是用戶需求權(quán)限,則將Role與User(或Group)綁定(這需要?jiǎng)?chuàng)建User/Group),是給用戶使用的。
2.ServiceAccount(服務(wù)賬戶)
ServiceAccount(服務(wù)帳戶)是由KubernetesAPI管理的用戶。它們綁定到特定的命名空間,并由API服務(wù)器自動(dòng)創(chuàng)建或通過(guò)API調(diào)用手動(dòng)創(chuàng)建。
服務(wù)帳戶與存儲(chǔ)為Secrets的一組證書(shū)相關(guān)聯(lián),這些憑據(jù)被掛載到pod中,以便集群進(jìn)程與Kubernetes API通信。(登錄dashboard時(shí)我們使用的就是ServiceAccount)
如果是程序需求權(quán)限,將Role與ServiceAccount指定(這需要?jiǎng)?chuàng)建ServiceAccount并且在deployment中指定ServiceAccount),是給程序使用的。
下面示例是RoleBinding中的片段,僅展示其subjects的部分。
對(duì)于名稱為 alice@example.com 的用戶:
subjects:
-kind:User
name:"alice@example.com"
apiGroup:rbac.authorization.k8s.io
對(duì)于名稱為 frontend-admins 的用戶組:
subjects:
-kind:Group
name:"frontend-admins"
apiGroup:rbac.authorization.k8s.io
對(duì)于在任何名字空間中的服務(wù)賬戶:
subjects:
-kind:Group
name:system:serviceaccounts
apiGroup:rbac.authorization.k8s.io
七、CKA中的真題
CKA真題
- 「Context:」為部署流水線創(chuàng)建一個(gè)新的 ClusterRole 并將其綁定到范圍為特定的 namespace 的特ServiceAccount。
- 「Task:」創(chuàng)建一個(gè)名為 「deployment-clusterrole」 的clusterrole,該 clusterrole 只允許「Deployment、Daemonset、Statefulset」 具有「create」 權(quán)限,在現(xiàn)有的namespace app-team1中創(chuàng)建一個(gè)名為 「cicd-token」 的新ServiceAccount。
- 「限于」namespace app-team1 中,將新的 ClusterRole deployment-clusterrole 綁定到新的 ServiceAccount cicd-token。
這題考點(diǎn)是對(duì)RBAC授權(quán)模型的理解。可以參考官網(wǎng)文檔有關(guān)RBAC的資料或者使用-h幫助。
#考試時(shí)務(wù)必執(zhí)行,切換集群。
kubectl config use-context k8s
#創(chuàng)建一個(gè)名稱為deployment-clusterrole的clusterrole
kubectl create clusterrole deployment-clusterrole \
-verb=create -resource=deployments,daemonsets,statefulsets
#在命名空間app-team1創(chuàng)建一個(gè)名為cicd-token
kubectl create sa cicd-token -n app-team1
#題目中寫(xiě)了“限于 namespace app-team1 中”,則創(chuàng)建 rolebinding。沒(méi)有寫(xiě)的話,則創(chuàng)建 clusterrolebinding。
kubectl create rolebinding cicd-token-rolebinding \
--clusterrole=clusterrole
--serviceaccount=app-team1:cicd-token --namespace=app-team1
# rolebinding 后面的名字 cicd-token-rolebinding 隨便起的,因?yàn)轭}目中沒(méi)有要求,如果題目中有要求,就不能隨便起了。
可以通過(guò)下面的命令檢查:
kubectl -n app-team1 describe rolebindings cicd-token-rolebinding
出現(xiàn)如下圖的證明已經(jīng)創(chuàng)建成功。