Kubernetes RBAC 權限控制

RBAC (Role-Based Access Control) 是 Kubernetes 為了管理「誰 (Subject) 可以對什麼 (Resource) 做什麼 (Verb)」的核心機制。

在 K8s 中,沒有所謂的 useradd 指令。所有的權限管理都是透過綁定 Role (角色) 來達成。

RBAC 四大元件

要搞懂 RBAC,必須先理解這四個元件的關係:

元件作用範圍 (Scope)說明
Role定義「能做什麼」 (權限集合)Namespace只能控制特定 Namespace 下的資源 (如 Pods, Deployments)。
ClusterRole定義「能做什麼」Global1. 控制全叢集資源 (如 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.yamlrolebinding-jane.yaml) 並執行:

kubectl apply -f role-pod-reader.yaml
kubectl apply -f rolebinding-jane.yaml

ServiceAccount (SA) - 給機器的帳號

K8s 有兩種使用者:

  1. User Account: 真人 (開發者、管理員)。由外部身分驗證系統管理 (如 GCP IAM, AWS IAM, LDAP, X.509 憑證)。K8s 不會儲存 User 列表。
  2. ServiceAccount (SA): 機器人 (Pod)。由 K8s 內部管理。

Pod 如何取得權限?

當你的 App (例如 CI/CD Runner 或 K8s Operator) 需要呼叫 kubectl 或 K8s API 時,它必須有一個有權限的 ServiceAccount。

流程:

  1. 建立 ServiceAccount: kubectl create sa my-robot -n default
  2. 建立 Role: 定義它能做什麼 (例如能 Delete Pod)。
  3. 建立 RoleBinding: 將 my-robot 與 Role 綁定。
  4. 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

總結與最佳實踐

  1. 最小權限原則 (Least Privilege): 只給剛好夠用的權限。能給 Role 就不要給 ClusterRole。能給 view 就不要給 edit
  2. 善用內建 ClusterRole: 90% 的情況下,內建的 view, edit, admin 就夠用了,不用自己手寫 YAML。
  3. 小心 bind verbs: 如果你給某人 bindescalate 權限,他就能自己把自己提升成 admin。
  4. ServiceAccount: 每個應用程式最好有獨立的 SA,不要大家都用 default SA。