Kubernetes RBAC 權限控制
RBAC (Role-Based Access Control) 是 Kubernetes 為了管理「誰 (Subject) 可以對什麼 (Resource) 做什麼 (Verb)」的核心機制。
在 K8s 中,沒有所謂的 useradd 指令。所有的權限管理都是透過綁定 Role (角色) 來達成。
RBAC 四大元件
要搞懂 RBAC,必須先理解這四個元件的關係:
| 元件 | 作用 | 範圍 (Scope) | 說明 |
|---|---|---|---|
| Role | 定義「能做什麼」 (權限集合) | Namespace | 只能控制特定 Namespace 下的資源 (如 Pods, Deployments)。 |
| ClusterRole | 定義「能做什麼」 | Global | 1. 控制全叢集資源 (如 Nodes, PVs)。 2. 控制所有 Namespaces 的資源。 |
| RoleBinding | 將 Role 綁定給某人 | Namespace | 讓某人在「這個 Namespace」擁有 Role 定義的權限。 |
| ClusterRoleBinding | 將 ClusterRole 綁定給某人 | Global | 讓某人在「所有 Namespace/全叢集」擁有權限。 |
口訣:Role 是鑰匙 (權限),Binding 是把鑰匙交給 User (授權)。
實戰範例:只讀權限 (Read-Only)
假設我們想給一個測試員 (User: jane) 只讀權限,他只能看 default namespace 的 Pod,不能刪除或修改。
Step 1: 定義 Role (權限)
# role-pod-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [''] # "" 代表 Core API Group (Pod, Service, ConfigMap...)
resources: ['pods', 'pods/log'] # 可以看 Pod 和 Log
verbs: ['get', 'watch', 'list'] # 只能讀,不能 create/delete
Step 2: 定義 RoleBinding (綁定)
將 pod-reader 角色綁支給使用者 jane。
# rolebinding-jane.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: default
subjects:
# 誰要被授權?
- kind: User
name: jane # 使用者名稱 (這通常來自 Kubeconfig 的憑證 CN)
apiGroup: rbac.authorization.k8s.io
roleRef:
# 綁定哪個 Role?
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Step 3: 套用設定
將上述內容存檔 (例如 role-pod-reader.yaml 和 rolebinding-jane.yaml) 並執行:
kubectl apply -f role-pod-reader.yaml
kubectl apply -f rolebinding-jane.yaml
ServiceAccount (SA) - 給機器的帳號
K8s 有兩種使用者:
- User Account: 真人 (開發者、管理員)。由外部身分驗證系統管理 (如 GCP IAM, AWS IAM, LDAP, X.509 憑證)。K8s 不會儲存 User 列表。
- ServiceAccount (SA): 機器人 (Pod)。由 K8s 內部管理。
Pod 如何取得權限?
當你的 App (例如 CI/CD Runner 或 K8s Operator) 需要呼叫 kubectl 或 K8s API 時,它必須有一個有權限的 ServiceAccount。
流程:
- 建立 ServiceAccount:
kubectl create sa my-robot -n default - 建立 Role: 定義它能做什麼 (例如能 Delete Pod)。
- 建立 RoleBinding: 將
my-robot與 Role 綁定。 - Pod 掛載 SA: 在 Pod YAML 中指定
serviceAccountName: my-robot。
常用指令範例
# 1. 建立 SA
kubectl create sa deploy-bot
# 2. 綁定權限 (直接用 create rolebinding 指令更外)
# 讓 deploy-bot 擁有 cluster-admin (最高權限 - 危險,僅供測試!)
kubectl create clusterrolebinding deploy-bot-admin \
--clusterrole=cluster-admin \
--serviceaccount=default:deploy-bot
# 3. 測試權限 (模擬該 SA)
kubectl auth can-i delete nodes --as=system:serviceaccount:default:deploy-bot
# 輸出: yes
ClusterRole 與 ClusterRoleBinding
有些資源是不屬於 Namespace 的 (例如 Node),或者你想一次給予「所有 Namespace」的權限,這時就要用 ClusterRole。
常見內建 ClusterRole
K8s 預設已經幫你建好了幾個常用的 ClusterRole,你可以直接綁定:
- cluster-admin: 神之權限。超級管理員,可做任何事。
- admin: 該 Namespace 的管理員。除了配額 (Quota) 和 Namespace 本身不能動之外,其他都能做 (包含建立 RoleBinding)。
- edit: 可讀寫大部分資源,但不能查看或修改 Role/RoleBinding。
- view: 唯讀權限。能看大部份資源,但不能看 Secret (安全性考量)。
如何讓 User 只能看(View) 所有 Namespace?
# 使用 ClusterRoleBinding + 內建 view 角色
kubectl create clusterrolebinding jane-view-all \
--clusterrole=view \
--user=jane
除錯工具:kubectl auth can-i
設定完 RBAC 後,最怕就是權限不通或給太大。一定要驗證!
# 檢查「我」能不能刪除 pod
kubectl auth can-i delete pod
# 檢查「Jane」能不能 list secret (模擬身分)
kubectl auth can-i list secret --as jane
# 檢查 default namespace 下的 serviceaccount "deploy-bot" 能不能 get deployment
kubectl auth can-i get deployment \
--as=system:serviceaccount:default:deploy-bot
總結與最佳實踐
- 最小權限原則 (Least Privilege): 只給剛好夠用的權限。能給
Role就不要給ClusterRole。能給view就不要給edit。 - 善用內建 ClusterRole: 90% 的情況下,內建的
view,edit,admin就夠用了,不用自己手寫 YAML。 - 小心
bindverbs: 如果你給某人bind或escalate權限,他就能自己把自己提升成 admin。 - ServiceAccount: 每個應用程式最好有獨立的 SA,不要大家都用 default SA。