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