本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

使用 Kubernetes v1.8 中正式可用的 RBAC

編者注:這篇文章是 Kubernetes 1.8 新功能系列深度文章的一部分。

Kubernetes 1.8 是基於角色的訪問控制 (RBAC) 授權器的一個重要里程碑,它在此版本中晉升為 GA(普遍可用)。RBAC 是一種控制對 Kubernetes API 訪問的機制,自其在 1.6 中釋出 Beta 版以來,許多 Kubernetes 叢集和配置策略都預設啟用了它。

展望未來,我們預計 RBAC 將成為保護 Kubernetes 叢集的基石。本文探討了如何使用 RBAC 管理使用者和應用程式對 Kubernetes API 的訪問。

授予使用者訪問許可權

RBAC 使用標準 Kubernetes 資源進行配置。使用者可以透過繫結(ClusterRoleBindings 和 RoleBindings)繫結到一組角色(ClusterRoles 和 Roles)。使用者最初沒有任何許可權,必須由管理員明確授予訪問許可權。

所有 Kubernetes 叢集都安裝了一組預設的 ClusterRoles,代表了使用者可以歸屬的常見類別。“edit”角色允許使用者執行部署 Pod 等基本操作;“view”角色允許使用者檢視非敏感資源;“admin”角色允許使用者管理名稱空間;“cluster-admin”角色授予管理叢集的許可權。


$ kubectl get clusterroles

NAME            AGE

admin           40m

cluster-admin   40m

edit            40m

# ...


view            40m

ClusterRoleBindings 授予使用者、組或服務賬戶 ClusterRole 在整個叢集中的許可權。使用 kubectl,我們可以透過將示例使用者“jane”繫結到“edit”ClusterRole,讓她在所有名稱空間中執行基本操作。


$ kubectl create clusterrolebinding jane --clusterrole=edit --user=jane

$ kubectl get namespaces --as=jane

NAME          STATUS    AGE

default       Active    43m

kube-public   Active    43m

kube-system   Active    43m

$ kubectl auth can-i create deployments --namespace=dev --as=jane

yes

RoleBindings 在名稱空間內授予 ClusterRole 的許可權,允許管理員管理一箇中央 ClusterRoles 列表,該列表在整個叢集中重複使用。例如,當新資源新增到 Kubernetes 時,預設的 ClusterRoles 會更新,以自動授予其名稱空間內 RoleBinding 主體正確的許可權。

接下來,我們將允許“infra”組修改“dev”名稱空間中的資源


$ kubectl create rolebinding infra --clusterrole=edit --group=infra --namespace=dev

rolebinding "infra" created

因為我們使用了 RoleBinding,這些許可權只適用於 RoleBinding 的名稱空間。在我們的例子中,“infra”組中的使用者可以檢視“dev”名稱空間中的資源,但不能檢視“prod”中的資源。


$ kubectl get deployments --as=dave --as-group=infra --namespace dev

No resources found.

$ kubectl get deployments --as=dave --as-group=infra --namespace prod

Error from server (Forbidden): deployments.extensions is forbidden: User "dave" cannot list deployments.extensions in the namespace "prod".

建立自定義角色

當預設的 ClusterRoles 不夠用時,可以建立定義自定義許可權集的新角色。由於 ClusterRoles 只是常規的 API 資源,它們可以用 YAML 或 JSON 清單表示,並使用 kubectl 應用。

每個 ClusterRole 都包含一個指定“規則”的許可權列表。規則是純粹的累加性規則,允許對一組資源執行特定的 HTTP 動詞。例如,以下 ClusterRole 擁有對“deployments”、“configmaps”或“secrets”執行任何操作以及檢視任何“pod”的許可權。


kind: ClusterRole

apiVersion: rbac.authorization.k8s.io/v1

metadata:

 name: deployer

rules:

- apiGroups: ["apps"]

 resources: ["deployments"]

 verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]



- apiGroups: [""] # "" indicates the core API group

 resources: ["configmaps", "secrets"]

 verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]



- apiGroups: [""] # "" indicates the core API group

 resources: ["pods"]

 verbs: ["get", "list", "watch"]

動詞對應於請求的 HTTP 動詞,而資源和 API 組則指代被引用的資源。考慮以下 Ingress 資源:


apiVersion: extensions/v1beta1

kind: Ingress

metadata:

 name: test-ingress

spec:

 backend:

   serviceName: testsvc

   servicePort: 80

要 POST 該資源,使用者需要以下許可權:


rules:

- apiGroups: ["extensions"] # "apiVersion" without version

 resources: ["ingresses"]  # Plural of "kind"

 verbs: ["create"]         # "POST" maps to "create"

應用程式的角色

當部署需要訪問 Kubernetes API 的容器時,最佳實踐是在應用程式清單中附帶一個 RBAC Role。除了確保您的應用程式在啟用 RBAC 的叢集上執行外,這還有助於使用者審計您的應用程式將在叢集上執行的操作,並考慮其安全影響。

對於應用程式來說,名稱空間級別的 Role 通常更合適,因為應用程式通常在單個名稱空間中執行,並且名稱空間的資源應該與應用程式的生命週期相關聯。然而,Role 不能授予對非名稱空間資源(例如節點)或跨名稱空間的訪問許可權,因此某些應用程式可能仍然需要 ClusterRoles。

以下 Role 允許 Prometheus 例項在“dev”名稱空間中監控和發現服務、端點和 Pod:


kind: Role

metadata:

 name: prometheus-role

 namespace: dev

rules:

- apiGroups: [""] # "" refers to the core API group

 Resources: ["services", "endpoints", "pods"]

 verbs: ["get", "list", "watch"]

在 Kubernetes 叢集中執行的容器會收到服務賬戶憑據以與 Kubernetes API 通訊,並且服務賬戶可以透過 RoleBinding 進行定向。Pod 通常使用“default”服務賬戶執行,但最佳實踐是讓每個應用程式都使用唯一的服務賬戶,這樣 RoleBindings 就不會無意中將許可權授予其他應用程式。

要使用自定義服務賬戶執行 Pod,請在同一名稱空間中建立 ServiceAccount 資源,並指定清單的 `serviceAccountName` 欄位。


apiVersion: apps/v1beta2 # Abbreviated, not a full manifest

kind: Deployment

metadata:

 name: prometheus-deployment

 namespace: dev

spec:

 replicas: 1

 template:

   spec:

     containers:

     - name: prometheus

       image: prom/prometheus:v1.8.0

       command: ["prometheus", "-config.file=/etc/prom/config.yml"]

   # Run this pod using the "prometheus-sa" service account.

   serviceAccountName: prometheus-sa

---

apiVersion: v1

kind: ServiceAccount

metadata:

 name: prometheus-sa

 namespace: dev

參與其中

RBAC 的開發是透過 Auth 興趣小組組織的社群工作,它是負責維護 Kubernetes 的眾多 SIG 之一。參與 Kubernetes 社群的一個好方法是加入一個符合您興趣的 SIG,提供反饋,並協助制定路線圖。

關於作者

Eric Chiang 是 CoreOS 的軟體工程師和 Kubernetes 開發技術負責人,CoreOS 是企業級 Kubernetes 平臺 Tectonic 的建立者。Eric 共同領導 Kubernetes SIG Auth,並代表 CoreOS 維護多個開源專案和庫。