從 GKE 工作負載向 Google Cloud API 進行驗證

本頁面說明如何使用 Workload Identity Federation for GKE,從 Google Kubernetes Engine (GKE) 叢集執行的工作負載,以更安全的方式存取 Google Cloud API。

本頁面適用於建立及管理使用者權限相關政策的身分和帳戶管理員、操作員和開發人員。如要進一步瞭解 Google Cloud 內容中提及的常見角色和工作範例,請參閱「常見的 GKE 使用者角色和工作」。

閱讀本頁內容前,請務必先熟悉 Workload Identity Federation for GKE 概念。

事前準備

開始之前,請確認您已執行下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。

為叢集和節點集區啟用 Workload Identity Federation for GKE

在 Autopilot 中,Workload Identity Federation for GKE 一律啟用。直接跳至「設定應用程式以使用 Workload Identity Federation for GKE」一節。

在 Standard 中,您可以使用 Google Cloud CLI 或 Google Cloud 控制台,為叢集和節點集區啟用 GKE 適用的工作負載身分聯盟。您必須先在叢集層級啟用 Workload Identity Federation for GKE,才能在節點集區啟用這項功能。

您可以使用 gcloud CLI 或 Google Cloud 控制台,在現有的 Standard 叢集上啟用 Workload Identity Federation for GKE。現有的節點集區不會受到影響,但叢集中的所有新節點集區都會使用 Workload Identity Federation for GKE。

gcloud

  1. 在 Google Cloud 控制台啟用 Cloud Shell。

    啟用 Cloud Shell

    Google Cloud 控制台底部會開啟 Cloud Shell 工作階段,並顯示指令列提示。Cloud Shell 是已安裝 Google Cloud CLI 的殼層環境,並已設定適用於您目前專案的值。工作階段可能要幾秒鐘的時間才能初始化。

  2. 如要在現有叢集上啟用 Workload Identity Federation for GKE,請執行下列指令:

    gcloud container clusters update CLUSTER_NAME \
        --location=LOCATION \
        --workload-pool=PROJECT_ID.svc.id.goog
    

    更改下列內容:

    • CLUSTER_NAME:現有叢集的名稱。
    • LOCATION:叢集控制層的 Compute Engine區域或可用區,例如 us-central1 或 us-central1-a。
    • PROJECT_ID:您的 Google Cloud 專案 ID。

控制台

如要在現有叢集上啟用 Workload Identity Federation for GKE,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往「Google Kubernetes Engine」

  2. 在叢集清單中,按一下您要修改的叢集名稱。

  3. 在叢集詳細資料頁面的「安全性」區段中,按一下 「編輯 Workload Identity」。

  4. 在「Edit Workload Identity」(編輯 Workload Identity) 對話方塊中,勾選「Enable Workload Identity」(啟用 Workload Identity) 核取方塊。

  5. 按一下 [儲存變更]。

將現有工作負載遷移至 Workload Identity Federation for GKE

在現有叢集啟用 Workload Identity Federation for GKE 後,您可能需要遷移執行中的工作負載,才能使用 Workload Identity Federation for GKE。選取最適合您環境的遷移策略。您可以建立啟用 Workload Identity Federation for GKE 的新節點集區,也可以更新現有節點集區來啟用這項功能。

只有在叢集上啟用 Workload Identity Federation for GKE 時,才能在節點集區上啟用這項功能。

最佳做法:

如果您也需要修改應用程式,使其與 Workload Identity Federation for GKE 相容,請建立新的節點集區。

如果叢集已啟用 Workload Identity Federation for GKE,您建立的所有新節點集區預設都會使用這項功能。如要建立啟用 Workload Identity Federation for GKE 的新節點集區,請執行下列指令:

gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --workload-metadata=GKE_METADATA

更改下列內容:

  • NODEPOOL_NAME:新節點集區的名稱。
  • CLUSTER_NAME:已啟用 Workload Identity Federation for GKE 的現有叢集名稱。
  • CONTROL_PLANE_LOCATION:叢集控制層的 Compute Engine區域或可用區,例如 us-central1 或 us-central1-a。

--workload-metadata=GKE_METADATA 旗標會將節點集區設為使用 GKE 中繼資料伺服器。

最佳做法:

加入這個旗標,如果叢集未啟用 Workload Identity Federation for GKE,節點集區建立作業就會失敗。

更新現有節點集區

在叢集上啟用 Workload Identity Federation for GKE 後,您可以在現有節點集區上,手動啟用 Workload Identity Federation for GKE。

gcloud

  1. 在 Google Cloud 控制台中啟用 Cloud Shell。

    啟用 Cloud Shell

    Google Cloud 控制台底部會開啟 Cloud Shell 工作階段,並顯示指令列提示。Cloud Shell 是已安裝 Google Cloud CLI 的殼層環境,並已設定適用於您目前專案的值。工作階段可能要幾秒鐘的時間才能初始化。

  2. 如要修改現有節點集區,使其使用 Workload Identity Federation for GKE,請執行下列指令:

    gcloud container node-pools update NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --workload-metadata=GKE_METADATA
    

    如果叢集已啟用 GKE 適用的 Workload Identity Federation,您可以明確指定 --workload-metadata=GCE_METADATA,選擇性停用特定節點集區的這項功能。

控制台

如要修改現有節點集區,以使用 Workload Identity Federation for GKE,請執行下列步驟:

  1. 前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往「Google Kubernetes Engine」

  2. 在叢集清單中,按一下要修改的叢集名稱。

  3. 按一下「Nodes」(節點) 分頁標籤。

  4. 在「Node Pools」(節點集區) 區段中,按一下要修改的節點集區名稱。

  5. 在「Node pool details」(節點集區詳細資料) 頁面中,按一下 「Edit」(編輯)。

  6. 在「Edit node pool」(編輯節點集區) 頁面的「Security」(安全性) 區段中,勾選「Enable GKE Metadata Server」(啟用 GKE 中繼資料伺服器) 核取方塊。

  7. 按一下 [儲存]。

設定應用程式以使用 Workload Identity Federation for GKE

如要讓 GKE 應用程式使用 Workload Identity Federation for GKE 向 Google CloudAPI 驗證身分,請為特定 API 建立 IAM 政策。這些政策中的主體是 IAM 主體 ID,對應至工作負載、命名空間或 Kubernetes ServiceAccount。這個程序會傳回聯邦存取權杖,工作負載可用於 API 呼叫。

或者,您也可以設定 Kubernetes ServiceAccount 來模擬 IAM 服務帳戶,這會將 GKE 設定為透過 Service Account Credentials API,將同盟存取權權杖換成存取權杖。詳情請參閱「替代方案:將 Kubernetes ServiceAccount 連結至 IAM」一節。

設定授權和主體

  1. 取得叢集憑證:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

    更改下列內容:

    • CLUSTER_NAME:已啟用 Workload Identity Federation for GKE 的叢集名稱。
    • CONTROL_PLANE_LOCATION:叢集控制層的 Compute Engine區域或可用區,例如 us-central1 或 us-central1-a。
  2. 建立要用於 Kubernetes 服務帳戶的命名空間。您也可以使用 default 命名空間或任何現有命名空間。

    kubectl create namespace NAMESPACE
    
  3. 為應用程式建立要使用的 Kubernetes ServiceAccount。您也可以在任何命名空間中使用現有的 Kubernetes ServiceAccount。如果您未將 ServiceAccount 指派給工作負載,Kubernetes 會指派命名空間中的 default ServiceAccount。

    kubectl create serviceaccount KSA_NAME \
        --namespace NAMESPACE
    

    更改下列內容:

    • KSA_NAME:新 Kubernetes ServiceAccount 的名稱。
    • NAMESPACE:ServiceAccount 的 Kubernetes 命名空間名稱。
  4. 建立參照 Kubernetes ServiceAccount 的 IAM 允許政策。建議您將權限授予應用程式需要存取的特定Google Cloud 資源。您必須具備相關 IAM 權限,才能在專案中建立允許政策。

    舉例來說,下列指令會將「Kubernetes Engine 叢集檢視者」(roles/container.clusterViewer) 角色授予您建立的 ServiceAccount:

    gcloud projects add-iam-policy-binding projects/PROJECT_ID \
        --role=roles/container.clusterViewer \
        --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME \
        --condition=None
    

    更改下列內容:

    • PROJECT_ID:您的 Google Cloud 專案 ID。
    • PROJECT_NUMBER:您的數值 Google Cloud專案編號。

    您可以在任何支援 IAM 允許政策的 Google Cloud 資源上授予角色。主體 ID 的語法取決於 Kubernetes 資源。如需支援的 ID 清單,請參閱「Workload Identity Federation for GKE 的主體 ID」。

選用:設定服務網格選項

如果您使用 Istio 或 Cloud Service Mesh 管理環境,請在 Pod 規格的 metadata.annotations 欄位中新增下列註解:

metadata:
  annotations:
    proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'

這項註解可防止容器在服務網格 Proxy 準備好重新導向應用程式流量前啟動。

驗證 Workload Identity Federation for GKE 設定

在本節中,您將建立 Cloud Storage bucket,並將 bucket 的檢視權限授予您在上一節建立的 Kubernetes ServiceAccount。接著部署工作負載,並測試容器是否可以列出專案中的叢集。

  1. 建立空白的 Cloud Storage bucket:

    gcloud storage buckets create gs://BUCKET
    

    將 BUCKET 替換為新 bucket 的名稱。

  2. 將 Storage 物件檢視者 (roles/storage.objectViewer) 角色授予您建立的 ServiceAccount:

    gcloud storage buckets add-iam-policy-binding gs://BUCKET \
        --role=roles/storage.objectViewer \
        --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME \
        --condition=None
    

    更改下列內容:

    • PROJECT_ID:您的 Google Cloud 專案 ID。
    • PROJECT_NUMBER:您的數值 Google Cloud專案編號。
    • NAMESPACE:包含 ServiceAccount 的 Kubernetes 命名空間。
    • KSA_NAME:ServiceAccount 的名稱。
  3. 將下列資訊清單儲存為 test-app.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod
      namespace: NAMESPACE
    spec:
      serviceAccountName: KSA_NAME
      containers:
      - name: test-pod
        image: google/cloud-sdk:slim
        command: ["sleep","infinity"]
        resources:
          requests:
            cpu: 500m
            memory: 512Mi
            ephemeral-storage: 10Mi
    
  4. 僅限 Standard 叢集,在 template.spec 欄位中新增下列項目,將 Pod 放置在採用 Workload Identity Federation for GKE 的節點集區中。

    在 Autopilot 叢集中,請略過這個步驟,因為每個節點都使用 Workload Identity Federation for GKE,所以會拒絕這個 nodeSelector。

    spec:
      nodeSelector:
        iam.gke.io/gke-metadata-server-enabled: "true"
    
  5. 將設定套用到叢集:

    kubectl apply -f test-app.yaml
    
  6. 等待 Pod 準備就緒。如要檢查 Pod 的狀態,請執行下列指令:

    kubectl get pods --namespace=NAMESPACE
    

    Pod 準備就緒後,輸出內容會大致如下:

    NAME       READY   STATUS    RESTARTS   AGE
    test-pod   1/1     Running   0          5m27s
    
  7. 在 Pod 中開啟殼層工作階段:

    kubectl exec -it pods/test-pod --namespace=NAMESPACE -- /bin/bash
    
  8. 取得 bucket 中的物件清單:

    curl -X GET -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        "https://storage.googleapis.com/storage/v1/b/BUCKET/o"
    

    輸出內容如下:

    {
      "kind": "storage#objects"
    }
    

    這項輸出內容顯示 Pod 可以存取 bucket 中的物件。

替代方案:將 Kubernetes ServiceAccounts 連結至 IAM

最佳做法:

使用 IAM 主體 ID 設定 Workload Identity Federation for GKE。不過,這個聯合身分對每個支援的 Google Cloud API 都有特定的限制。如果適用這些限制,請按照下列步驟,從 GKE 工作負載設定這些 API 的存取權。

  1. 建立 Kubernetes 命名空間:

    kubectl create namespace NAMESPACE
    
  2. 建立 Kubernetes ServiceAccount:

    kubectl create serviceaccount KSA_NAME \
        --namespace=NAMESPACE
    
  3. 建立 IAM 服務帳戶。您也可以使用組織中任何專案的現有 IAM 服務帳戶。

    gcloud iam service-accounts create IAM_SA_NAME \
        --project=IAM_SA_PROJECT_ID
    

    更改下列內容:

    • IAM_SA_NAME:新 IAM 服務帳戶的名稱。
    • IAM_SA_PROJECT_ID:IAM 服務帳戶的專案 ID。

    如要瞭解如何授權 IAM 服務帳戶存取 API,請參閱「瞭解服務帳戶」。 Google Cloud

  4. 將特定 Google Cloud API 的必要角色授予 IAM 服務帳戶:

    gcloud projects add-iam-policy-binding IAM_SA_PROJECT_ID \
        --member "serviceAccount:IAM_SA_NAME@IAM_SA_PROJECT_ID.iam.gserviceaccount.com" \
        --role "ROLE_NAME"
    

    將 ROLE_NAME 替換為角色名稱,例如 roles/spanner.viewer。

  5. 建立 IAM 允許政策,授予 Kubernetes 服務帳戶模擬 IAM 服務帳戶的權限:

    gcloud iam service-accounts add-iam-policy-binding IAM_SA_NAME@IAM_SA_PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]"
    

    成員名稱必須包含命名空間和 Kubernetes ServiceAccount 名稱。例如 serviceAccount:example-project.svc.id.goog[example-namespace/example-serviceaccount]。

  6. 為 Kubernetes ServiceAccount 加註,讓 GKE 看到服務帳戶之間的連結:

    kubectl annotate serviceaccount KSA_NAME \
        --namespace NAMESPACE \
        iam.gke.io/gcp-service-account=IAM_SA_NAME@IAM_SA_PROJECT_ID.iam.gserviceaccount.com
    

    使用這個方法時,您必須同時提供 IAM 允許政策和註解。

  7. 選用:為 Kubernetes ServiceAccount 加註,讓應用程式以 IAM 主體 ID 語法取得 ID:

    kubectl annotate serviceaccount KSA_NAME \
        --namespace=NAMESPACE \
        iam.gke.io/return-principal-id-as-email="true"
    

透過程式碼使用 Workload Identity Federation for GKE

從程式碼向 Google Cloud 服務進行驗證的程序,與使用 Compute Engine 中繼資料伺服器進行驗證的程序相同。使用 Workload Identity Federation for GKE 時,傳送至執行個體中繼資料伺服器的要求會轉送至 GKE 中繼資料伺服器。使用執行個體中繼資料伺服器進行驗證的現有程式碼 (例如使用 Google Cloud 用戶端程式庫 的程式碼) 應可正常運作,無須修改。

透過 Workload Identity Federation for GKE 使用其他專案的配額

在執行 GKE 1.24 以上版本的叢集上,您可以選擇設定 Kubernetes 服務帳戶,在呼叫 IAM Service Account Credentials API 中的 GenerateAccessToken 和 GenerateIdToken 方法時,使用其他 Google Cloud 專案的配額。這樣一來,您就不必在主要專案中使用整個配額,而是可以改用其他專案的配額,在叢集內使用這些服務。

如要透過 Workload Identity Federation for GKE 設定配額專案,請完成下列步驟:

  1. 將配額專案的 serviceusage.services.use 權限授予 Kubernetes 服務帳戶。

    gcloud projects add-iam-policy-binding QUOTA_PROJECT_ID \
        --role=roles/serviceusage.serviceUsageConsumer \
        --member='principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME' \
    

    將 QUOTA_PROJECT_ID 替換為配額專案的專案 ID。

  2. 使用配額專案為 Kubernetes 服務帳戶加註:

    kubectl annotate serviceaccount KSA_NAME \
        --namespace NAMESPACE \
        iam.gke.io/credential-quota-project=QUOTA_PROJECT_ID
    

如要確認設定是否正常運作,請按照下列步驟操作:

  1. 建立 Pod 並啟動 Shell 工作階段。請參閱 Kubernetes 說明文件,瞭解如何取得執行中容器的 Shell。

  2. 向中繼資料伺服器提出要求:

    curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token
    
  3. 在配額專案的 Google Cloud 控制台中,前往「IAM Service Accounts Credentials API」(IAM 服務帳戶憑證 API) 頁面:

    前往 API 頁面

  4. 檢查流量變化。

清除所用資源

如要停止使用 Workload Identity Federation for GKE,請撤銷 IAM 服務帳戶的存取權,並在叢集上停用 Workload Identity Federation for GKE。

撤銷存取權

如要撤銷主體的存取權,請移除您在「設定應用程式以使用 GKE 適用的工作負載身分聯盟」一節中建立的 IAM 允許政策。

舉例來說,如要撤銷 Artifact Registry 存放區的存取權,請執行下列指令:

gcloud artifacts repositories remove-iam-policy-binding REPOSITORY_NAME \
    --location=REPOSITORY_LOCATION \
    --member='principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME' \
    --role='roles/artifactregistry.reader' \
    --all

停用 Workload Identity Federation for GKE

您只能在 Standard 叢集停用 Workload Identity Federation for GKE。

gcloud

  1. 在 Google Cloud 控制台啟用 Cloud Shell。

    啟用 Cloud Shell

    Google Cloud 控制台底部會開啟 Cloud Shell 工作階段,並顯示指令列提示。Cloud Shell 是已安裝 Google Cloud CLI 的殼層環境,並已設定適用於您目前專案的值。工作階段可能要幾秒鐘的時間才能初始化。

  2. 在每個節點集區上停用 Workload Identity Federation for GKE:

    gcloud container node-pools update NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --workload-metadata=GCE_METADATA
    

    針對叢集中的每個節點集區重複執行這項指令。

  3. 在叢集中停用 Workload Identity Federation for GKE:

    gcloud container clusters update CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --disable-workload-identity
    

控制台

  1. 前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往「Google Kubernetes Engine」

  2. 在叢集清單中,按一下要修改的叢集名稱。

  3. 按一下「Nodes」(節點) 分頁標籤。

  4. 如要為每個節點集區停用 GKE 適用的 Workload Identity Federation,請在「Node Pools」(節點集區) 區段中,為每個節點集區執行下列操作:

    1. 按一下要修改的節點集區名稱。
    2. 在「Node pool details」(節點集區詳細資料) 頁面中,按一下 「Edit」(編輯)。
    3. 在「Edit node pool」(編輯節點集區) 頁面的「Security」(安全性) 區段中,取消勾選「Enable GKE Metadata Server」(啟用 GKE 中繼資料伺服器) 核取方塊。
    4. 按一下 [儲存]。
  5. 如要為叢集停用 Workload Identity Federation for GKE,請按照下列步驟操作:

    1. 點按「Details」(詳細資料) 分頁標籤。
    2. 在「Security」(安全性) 區段中,按一下「Workload Identity」旁邊的 「Edit」(編輯)。
    3. 在「Edit Workload Identity」(編輯 Workload Identity) 對話方塊中,取消勾選「Enable Workload Identity」(啟用 Workload Identity) 核取方塊。
    4. 按一下 [儲存變更]。

在貴機構中停用 Workload Identity Federation for GKE

「將 Kubernetes 服務帳戶連結至 IAM」一節中的步驟,可讓 Kubernetes 服務帳戶模擬所連結 IAM 服務帳戶的身分。Kubernetes ServiceAccount 的長期 API 權杖可換取對應的 IAM 服務帳戶存取權杖。

如要將工作負載與 IAM 服務帳戶隔離,可以停用組織、資料夾或專案中叢集的 GKE Workload Identity Federation。舉例來說,如果您打算停用服務帳戶建立功能或停用服務帳戶金鑰建立功能,停用 GKE 的 Workload Identity Federation,可防止 ServiceAccount 權杖交換 IAM 服務帳戶存取權杖。

詳情請參閱「禁止建立 workload identity 叢集」。

疑難排解

如需疑難排解資訊,請參閱「排解 GKE 的 Workload Identity Federation 問題」。

後續步驟