搭配使用 Workload Identity 與 Google Cloud

Workload Identity 可為叢集中的每個應用程式指派不重複的精細身分與授權。對於在 GKE on AWS 中執行的應用程式,建議使用工作負載身分存取Google Cloud 服務。詳情請參閱「Workload Identity」。

本主題說明如何使用 Workload Identity,從工作負載連線至Google Cloud 服務。

設定 Google Cloud 服務帳戶

在本節中,您會建立 Google Cloud 服務帳戶 (GSA),並限制存取 Google Cloud 服務的權限。

取得工作負載身分集區和提供者

如要設定工作負載身分,您必須擁有叢集身分識別提供者 URI 和工作負載身分集區的值。

  1. 判斷叢集的工作負載身分集區:

    所有 GKE 叢集都會在 workload identity pool PROJECT_ID.svc.id.goog 中建立身分提供者。如要取得叢集的 ID 集區名稱,請使用 Google Cloud CLI:

    gcloud container aws clusters describe CLUSTER_NAME \
        --location=GOOGLE_CLOUD_LOCATION \
        --format='value(workloadIdentityConfig.workloadPool)'
    

    更改下列內容:

    • CLUSTER_NAME 改為叢集名稱。
    • GOOGLE_CLOUD_LOCATION 改為管理叢集的位置名稱 Google Cloud

    輸出結果會包含叢集身分集區的名稱。請儲存這個值。稍後需使用這項資訊。

  2. 判斷叢集的識別資訊提供者。

    如要找出叢集的 IDP 名稱,請使用 Google Cloud CLI:

    gcloud container aws clusters describe CLUSTER_NAME \
        --location=GOOGLE_CLOUD_LOCATION \
        --format='value(workloadIdentityConfig.identityProvider)'
    

    更改下列內容:

    • CLUSTER_NAME
    • GOOGLE_CLOUD_LOCATION

    輸出結果包含叢集身分識別提供者的名稱。 請儲存這個值。稍後需使用這項資訊。

建立 Google Cloud 服務帳戶

如要建立 Google Cloud 服務帳戶 (GSA)、授予權限,並將 IAM 政策繫結新增至 GSA,請按照下列步驟操作:

  1. 使用 Google Cloud CLI 建立 GSA:

    gcloud iam service-accounts create GSA_NAME --project=PROJECT_ID
    

    更改下列內容:

    • GSA_NAME:應用程式的 GSA 名稱。
    • PROJECT_ID:GSA 的 Google Cloud 專案。
  2. 新增 IAM 繫結,允許 GSA 存取服務。

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:GSA_NAME@PROJECT_ID.iam.gserviceaccount.com \
        --role IAM_ROLE
    

    更改下列內容:

    • GSA_NAME:應用程式的 GSA 名稱
    • PROJECT_ID:GSA 的專案 ID
    • :要授予 GSA 的 IAM 角色IAM_ROLE

    在本範例中,我們將使用 roles/compute.viewer 角色,這個角色可授予運算服務的唯讀存取權:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:GSA_NAME@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/compute.viewer
    
  3. 授予 Kubernetes 服務帳戶 (KSA) 模擬 GSA 的權限。方法是新增具有 roles/iam.workloadIdentityUser 角色的 IAM 政策繫結:

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

    更改下列內容:

    • GSA_NAME
    • PROJECT_ID
    • NAMESPACE:應用程式的 Kubernetes 命名空間
    • KSA_NAME:用於應用程式的 KSA

部署範例應用程式

在本節中,您將部署可存取 Compute Engine API 的範例應用程式。如要使用這個範例,服務帳戶必須具備 roles/compute.viewer IAM 角色。如要部署範例應用程式,請按照下列步驟操作:

  1. 將下列資訊清單複製到名為 workload-identity-sample.yaml 的檔案:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: NAMESPACE
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: KSA_NAME
      namespace: NAMESPACE
    automountServiceAccountToken: false
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: cloud-sdk-config
      namespace: NAMESPACE
    data:
      config: |
        {
          "type": "external_account",
          "audience": "identitynamespace:PROJECT_ID.svc.id.goog:IDENTITY_PROVIDER",
          "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/GSA_NAME@PROJECT_ID.iam.gserviceaccount.com:generateAccessToken",
          "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
          "token_url": "https://sts.googleapis.com/v1/token",
          "credential_source": {
            "file": "/var/run/secrets/tokens/gcp-ksa/token"
          }
        }
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: cloud-sdk-example
      namespace: NAMESPACE
    spec:
      serviceAccount: KSA_NAME
      containers:
      - name: cloud-sdk
        image: gcr.io/google.com/cloudsdktool/cloud-sdk:latest
        command:
        - /bin/bash
        - -c
        - 'set -eu -o pipefail; while true; do gcloud compute zones list --filter="name ~ us-central1-*"; sleep 5; done'
        env:
        - name: CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE
          value: /var/run/secrets/tokens/gcp-ksa/google-application-credentials.json
        - name: CLOUDSDK_CORE_PROJECT
          value: PROJECT_ID
        volumeMounts:
        - name: gcp-ksa
          mountPath: /var/run/secrets/tokens/gcp-ksa
          readOnly: true
      volumes:
      - name: gcp-ksa
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              audience: PROJECT_ID.svc.id.goog
              expirationSeconds: 86400
              path: token
          - configMap:
              name: cloud-sdk-config
              optional: false
              items:
              - key: config
                path: google-application-credentials.json
    

    更改下列內容:

    • PROJECT_ID
    • NAMESPACE
    • KSA_NAME
    • GSA_NAME
    • IDENTITY_PROVIDER 改成叢集的識別資訊提供者名稱。
  2. 將資訊清單套用至叢集

    kubectl apply -f workload-identity-sample.yaml
    
  3. 確認範例應用程式運作正常,並檢查 Pod 的記錄:

    kubectl logs -f cloud-sdk-example -n NAMESPACE
    

    更改下列內容:

    • NAMESPACE

    如果 Pod 成功存取 Google Cloud Compute API,您會看到類似以下的輸出內容:

    NAME           REGION       STATUS  NEXT_MAINTENANCE  TURNDOWN_DATE
    us-central1-c  us-central1  UP
    us-central1-a  us-central1  UP
    us-central1-f  us-central1  UP
    us-central1-b  us-central1  UP
    

正在清除所用資源

  1. 刪除範例應用程式

    kubectl delete -f manifest.yaml
    
  2. 從 Google Cloud 服務帳戶移除 IAM 政策繫結

    gcloud iam service-accounts remove-iam-policy-binding \
        GSA_NAME@PROJECT_ID.iam.gserviceaccount.com \
        --member serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE//KSA_NAME] \
        roles/iam.workloadIdentityUser
    

    更改下列內容:

    • GSA_NAME
    • PROJECT_ID
    • NAMESPACE
    • KSA_NAME
  3. 從專案中移除 IAM 政策繫結

    gcloud projects remove-iam-policy-binding PROJECT_ID \
        --member serviceAccount:GSA_NAME@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/compute.viewer
    

    更改下列內容:

    • GSA_NAME
    • PROJECT_ID
  4. 刪除 Google Cloud 服務帳戶

    gcloud iam service-accounts delete \
       GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
    

    更改下列內容:

    • GSA_NAME
    • PROJECT_ID

後續步驟