使用角色型存取控管授權叢集中的動作


本頁面說明如何使用 Kubernetes 內建的角色型存取權控管 (RBAC) 機制,授權在 Google Kubernetes Engine (GKE) 叢集中的資源上執行動作。Kubernetes RBAC 預設為啟用,可讓您精細控管叢集存取權。

您將瞭解如何定義及指派精確的權限、建立角色和角色繫結來管理使用者存取權、驗證 API 存取權來檢查存取層級、排解常見問題,以及瞭解在 GKE 中使用 RBAC 時的限制。

本頁面適用於希望使用 RBAC 提升 GKE 叢集安全性的安全專家和營運人員。如要進一步瞭解 Google Cloud 內容中提及的常見角色和範例工作,請參閱常見的 GKE Enterprise 使用者角色和工作

閱讀本頁面之前,請先熟悉下列概念:

事前準備

開始之前,請確認你已完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update,取得最新版本。

與 Identity and Access Management 互動

Identity and Access Management (IAM) Kubernetes RBAC「都」可以用來控制 GKE 叢集的存取權:

  • IAM 並非專屬於 Kubernetes,而是為多種 Google Cloud 產品提供身分管理功能,主要在 Google Cloud 專案層級運作。

  • Kubernetes RBAC 是 Kubernetes 的核心元件,可用於建立和授予叢集「內」任何物件或物件類型的角色 (即一組權限)。

  • 如要授權動作,GKE 會先檢查 RBAC 政策。如果沒有 RBAC 政策,GKE 會檢查 IAM 權限。

在 GKE 中,IAM 和 Kubernetes RBAC 會整合在一起,如果使用者根據「任一項」工具擁有足夠的權限,在此情況下就會授權使用者執行動作。這是啟動 GKE 叢集的重要環節,因為在預設情況下, Google Cloud 使用者不具任何 Kubernetes RBAC RoleBindings。

如要使用 Google Cloud 帳戶授權使用者,必須先使用這些帳戶正確設定用戶端,以進行驗證。舉例來說,如果您使用的是 kubectl,則必須在執行任何需要授權的指令之前,kubectl 指令設定為向 Google Cloud進行驗證

在幾乎所有情況下,都可以使用 Kubernetes RBAC 取代 IAM。GKE 使用者至少需要叢集所在專案的 container.clusters.get IAM 權限。這項權限包含在 container.clusterViewer 角色中,以及其他權限更高的角色中。使用者必須具備 container.clusters.get 權限,才能驗證專案中的叢集,但這項權限不會授權使用者在這些叢集中執行任何動作。然後可透過 IAM 或 Kubernetes RBAC 授權。

定義及指派權限

您可以在 ClusterRoleRole 物件中定義 RBAC 規則,然後使用 ClusterRoleBindingRoleBinding 物件指派這些規則,如下所示:

  • ClusterRole:叢集層級的資源和允許作業分組,您可以使用 RoleBindingClusterRoleBinding 指派給使用者或群組。
  • 角色:資源和允許作業的命名空間分組,您可以使用 RoleBinding 指派給使用者或使用者群組。
  • ClusterRoleBinding:將 ClusterRole 指派給使用者或群組,適用於叢集中的所有命名空間。
  • RoleBinding:將 RoleClusterRole 指派給特定命名空間中的使用者或群組。

使用 RoleBindingClusterRole 指派給使用者或群組時,這些使用者和群組只能存取 RoleBinding 中指定的命名空間內的資源。如要讓使用者或群組存取所有命名空間的資源,請改用 ClusterRoleBinding

使用 Role 或 ClusterRole 定義權限

您可以定義 Role 或 ClusterRole 物件中的權限。Role 可定義單個命名空間中資源的存取權,ClusterRole 則可定義整個叢集中資源的存取權。

Role 和 ClusterRole 的語法相同,各有一個 rules 區段,可以在其中定義規則適用的資源,以及允許該 Role 進行的作業。舉例來說,下列 Role 會將讀取權限 (getwatchlist) 授予 accounting 命名空間中的所有 Pod:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: accounting
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

如需允許使用的欄位完整清單,請參閱 RoleClusterRole API 說明文件。

Role (與 ClusterRole比較)

因為 ClusterRole 授予的權限會套用在整個叢集上,所以與 Role 相比,使用 ClusterRole 所能控制的不同種類資源的存取權更多。包括:

  • 叢集範圍內的資源,例如節點
  • 非資源 REST 端點,例如 /healthz
  • 「橫跨所有命名空間」的命名空間資源 (例如,整個叢集中不論命名空間為何的所有 Pod)

使用 RoleBinding 或 ClusterRoleBinding 指派角色

建立 Role 或 ClusterRole 後,您可以建立 RoleBinding 或 ClusterRoleBinding,以此方式將其指派給使用者或使用者群組。使用者和群組稱為subjects,可以屬於下列任何一種類型:

主體類型 kind」的值 name」的值
Google Cloud 使用者帳戶 User Google Cloud 註冊電子郵件地址
Kubernetes 服務帳戶 ServiceAccount 叢集中 Kubernetes ServiceAccount 物件的名稱
IAM 服務帳戶 User 自動產生的 IAM 服務帳戶電子郵件地址
已驗證網域上的 Google 網路論壇地址 Group Google Workspace 群組的電子郵件地址 (該群組是 gke-security-groups 群組的成員)。如需設定 RBAC 適用的 Google 群組的操作說明,請參閱「設定 RBAC 適用的 Google 群組」。

下列 RoleBinding 會將 pod-reader 角色授予使用者、Kubernetes 服務帳戶、IAM 服務帳戶和 Google 網路論壇:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: pod-reader-binding
  namespace: accounting
subjects:
# Google Cloud user account
- kind: User
  name: janedoe@example.com
# Kubernetes service account
- kind: ServiceAccount
  name: johndoe
# IAM service account
- kind: User
  name: test-account@test-project.iam.gserviceaccount.com
# Google Group
- kind: Group
  name: accounting-group@example.com
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

使用 kubectl 驗證 API 存取權

kubectl 提供 auth can-i 子指令,可快速查詢 API 授權層。平台管理員可能需要模擬使用者身分,判斷他們可以執行的動作。您可以使用 auth can-i,並傳遞額外的 --as 標記。

執行 kubectl auth can-i 指令時,如果沒有 --as 旗標,Identity and Access Management (IAM) 會執行授權。反之,附加 --as 旗標時,Kubernetes RBAC 會執行授權作業。因此,您需要為 RBAC 建立必要的 RoleRoleBinding 物件。

詳情請參閱「驗證 API 存取權」。

API 用法和範例

如需使用 Kubernetes API 針對 RBAC 建立必要的 RoleClusterRoleRoleBindingClusterRoleBinding 物件的完整資訊,請參閱 Kubernetes 說明文件中的「使用角色型存取控制授權」。

排解 RBAC 問題

如要偵錯 RBAC 問題,請使用管理員活動稽核記錄,這項記錄預設會在所有叢集上啟用。如果因權限不足而無法存取資源或作業,API 伺服器會記錄 RBAC DENY 錯誤,以及其他資訊,例如使用者的隱含和明確群組成員資格。如果您使用 RBAC 適用的 Google 網路論壇,記錄訊息中會顯示 google groups

限制

以下各節會說明使用 Kubernetes RBAC 和 IAM 時可能不太明顯的互動情形。

預設的探索角色

叢集是使用一組預設 ClusterRoles 和 ClusterRoleBindings 建立而成的。以有效憑證發出的要求會放在 system:authenticated 群組中,其他要求則放在 system:unauthenticated 中。

system:basic-user 叢集角色可讓使用者執行 SelfSubjectAccessReviews,以測試其在叢集中的權限。system:discovery 角色可讓使用者讀取探索 API,以顯示叢集新增之 CustomResourceDefinitions 的相關資訊。

匿名使用者 (system:unauthenticated) 會改為接收 system:public-info-viewer ClusterRole,其擁有唯讀存取 /healthz/version API 的權限。

如要查看 system:discovery ClusterRole 允許的 API 端點,請執行以下指令:

kubectl get clusterroles system:discovery -o yaml

Google Cloud VM 執行個體上服務帳戶的禁止錯誤

如果 VM 執行個體沒有 userinfo-email 範圍,可能會發生下列錯誤:

Error from server (Forbidden): error when creating ... "role-name" is forbidden: attempt to grant extra privileges:...

舉例來說,假設 VM 具有 cloud-platform 範圍,但不具有 userinfo-email 範圍,當 VM 取得存取權杖時, Google Cloud會建立該權杖與 cloud-platform 範圍之間的關聯性。當 Kubernetes API 伺服器要求 Google Cloud 提供與存取權杖相關聯的身分時,會收到服務帳戶的專屬 ID,而不是服務帳戶的電子郵件地址。

如要成功驗證,請建立具有 userinfo-email 範圍的新 VM,或是建立使用該唯一 ID 的新角色繫結。

如要建立具有 userinfo-email 範圍的新 VM 執行個體,請執行下列指令:

gcloud compute instances create INSTANCE_NAME \
    --service-account SERVICE_ACCOUNT_EMAIL \
    --scopes userinfo-email

如建立使用現有 VM 服務帳戶的唯一識別碼的新角色繫結,請執行以下步驟:

  1. 找出服務帳戶的唯一識別碼:

    gcloud iam service-accounts describe SERVICE_ACCOUNT_EMAIL
    

    舉例來說,下列輸出內容會顯示 my-iam-account@somedomain.com 服務帳戶的 uniqueId

    displayName: Some Domain IAM service account
    email: my-iam-account@somedomain.com
    etag: BwWWja0YfJA
    name: projects/project-name/serviceAccounts/my-iam-account@somedomain.com
    oauth2ClientId: '123456789012345678901'
    projectId: project-name
    uniqueId: '123456789012345678901'
    
  2. 使用服務帳戶的 uniqueId 建立角色繫結:

    kubectl create clusterrolebinding CLUSTERROLEBINDING_NAME \
        --clusterrole cluster-admin \
        --user UNIQUE_ID
    

具備建立或更新角色和角色繫結的權限

在 Kubernetes 中,您必須符合下列條件,才能建立或更新具有特定權限的角色或角色繫結:

  • 建立或更新角色:您必須已具備要授予角色的權限。否則,您必須有權對角色執行 escalate 動詞。
  • 建立或更新角色繫結:您必須已具備角色繫結中授予的相同權限,且範圍與角色繫結相同。或者,您必須有權對參照角色執行 bind 動詞。

如果角色中授予的權限原本是透過 IAM 允許政策授予您,而非 RBAC,您的角色或角色繫結要求可能會失敗。舉例來說,假設使用者已獲授 IAM 權限 container.pods.*container.roles.create,並提出下列角色建立要求:

kubectl create role allowed-to-view-pods --resource pods --verb list,get

如果使用者僅透過 IAM 取得權限,可能會發生下列錯誤:

Error from server (Forbidden): clusterroles.rbac.authorization.k8s.io "allowed-to-view-pods" is forbidden:
user "caller@example.com" (groups=["system:authenticated"]) is attempting to grant RBAC permissions not currently held:
{APIGroups:[""], Resources:["pods"], Verbs:["list" "get"]}

如要解決這項限制,請使用 RBAC,而非 IAM,在角色中授予呼叫端權限。

或者,您也可以使用 RBAC 或 IAM,授予呼叫端 escalate 動詞、bind 動詞或兩者。不過,GKE 不建議採用這種做法,因為呼叫端可以將任何權限授予任何角色。

後續步驟