搭配使用 Workload Identity 與 Google Cloud

本指南說明如何在 AWS 上的 GKE 設定工作負載身分,控管工作負載對 GCP 資源的存取權。其中包含如何使用身分存取叢集 Google Cloud 資源的範例。

如要瞭解如何搭配使用 Workload Identity 與 AWS IAM 帳戶,控管 AWS 資源的存取權,請參閱「透過 AWS 使用 Workload Identity」。

總覽

工作負載身分會使用 Google Cloud IAM 權限控管資源存取權Google Cloud 。透過工作負載身分,您可以為每個工作負載指派不同的 IAM 角色。透過這項精細的權限控管機制,您可以遵循最低權限原則。如果沒有 Workload Identity,您必須將 Google Cloud IAM 角色指派給 GKE on AWS 節點,讓這些節點上的所有工作負載都擁有與節點本身相同的權限。

必要條件

  • 建立使用者叢集,Kubernetes 版本為 v1.20 以上。

  • 如果 AWS VPC 使用 Proxy 或防火牆,請將下列網址加入許可清單:

    • securetoken.googleapis.com
    • iamcredentials.googleapis.com
    • sts.googleapis.com
  • anthos-aws 目錄中,使用 anthos-gke 將環境切換至使用者叢集。

    cd anthos-aws
    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials CLUSTER_NAME
    CLUSTER_NAME 替換為使用者叢集名稱。

  • 使用下列指令,啟用這項功能所需的四項新服務:

    gcloud services enable securetoken.googleapis.com
    gcloud services enable iam.googleapis.com
    gcloud services enable iamcredentials.googleapis.com
    gcloud services enable sts.googleapis.com
    

撰寫 WI 集區和提供者名稱

每個 Google Cloud 專案都會自動建立代管工作負載身分集區,名稱格式為 PROJECT_ID.svc.id.goog。同樣地,Google Cloud 會建立名稱符合 https://gkehub.googleapis.com/projects/PROJECT_ID/locations/global/memberships/MEMBERSHIP_ID 模式的識別資訊提供者。如要進一步瞭解 workload identity pool,請參閱「啟用 Fleet 的元件」。如以下範例所示,使用專案 ID 和成員 ID 撰寫這些名稱:

export PROJECT_ID=USER_PROJECT_NAME
export CLUSTER_MEMBERSHIP_ID=PROJECT_MEMBERSHIP_NAME
export IDP="https://gkehub.googleapis.com/projects/${PROJECT_ID}/locations/global/memberships/${CLUSTER_MEMBERSHIP_ID}"
export WI_POOL="${PROJECT_ID}.svc.id.goog"

更改下列內容:

  • USER_PROJECT_NAME,並使用使用者選擇的專案名稱
  • PROJECT_MEMBERSHIP_NAME,並將其替換為叢集的成員名稱

建立 IAM 政策繫結

建立政策繫結,允許 Kubernetes 服務帳戶 (KSA) 模擬 Google Cloud 服務帳戶 (GSA)。

export K8S_NAMESPACE=KUBERNETES_NAMESPACE
export KSA_NAME=KUBERNETES_SA_NAME
export GCP_SA_EMAIL="WORKLOAD_IDENTITY_TEST@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud iam service-accounts add-iam-policy-binding \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:$WI_POOL[$K8S_NAMESPACE/$KSA_NAME]" $GCP_SA_EMAIL

更改下列內容:

  • KUBERNETES_NAMESPACE,其中包含定義 Kubernetes 服務帳戶的 Kubernetes 命名空間
  • WORKLOAD_IDENTITY_TEST 改成您選擇的工作負載名稱
  • KUBERNETES_SA_NAME,其中包含附加至應用程式的 Kubernetes 服務帳戶名稱

建立 SDK 設定對應

執行下列殼層指令碼,將 Workload Identity 詳細資料儲存在 ConfigMap 中。當 Pod 掛接 ConfigMap 時,Google Cloud CLI 就能讀取工作負載身分詳細資料。

cat << EOF > cfmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  namespace: ${K8S_NAMESPACE}
  name: my-cloudsdk-config
data:
  config: |
    {
      "type": "external_account",
      "audience": "identitynamespace:${WI_POOL}:${IDP}",
      "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${GCP_SA_EMAIL}: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"
      }
    }
EOF

env HTTPS_PROXY=http://localhost:8118 \
  kubectl apply -f cfmap.yaml

建立 Kubernetes 服務帳戶

在使用者叢集上建立 KSA,並使用與 IAM 繫結中相同的名稱和命名空間。

cat << EOF > k8s-service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ${KSA_NAME}
  namespace: ${K8S_NAMESPACE}
EOF

env HTTPS_PROXY=http://localhost:8118 \
  kubectl apply -f k8s-service-account.yaml

建立 Pod

接著,使用服務帳戶權杖投影和上述建立的 ConfigMap 建立 Pod。

  1. 建立範例 Pod yaml 檔案。

    cat << EOF > sample-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
      namespace: ${K8S_NAMESPACE}
    spec:
      serviceAccountName: ${KSA_NAME}
      containers:
      - command:
        - /bin/bash
        - -c
        - while :; do echo '.'; sleep 500 ; done
        image: google/cloud-sdk
        name: cloud-sdk
        env:
          - name: GOOGLE_APPLICATION_CREDENTIALS
            value: /var/run/secrets/tokens/gcp-ksa/google-application-credentials.json
        volumeMounts:
        - name: gcp-ksa
          mountPath: /var/run/secrets/tokens/gcp-ksa
          readOnly: true
      volumes:
      - name: gcp-ksa
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              path: token
              audience: ${WI_POOL}
              expirationSeconds: 172800
          - configMap:
              name: my-cloudsdk-config
              optional: false
              items:
               - key: "config"
                 path: "google-application-credentials.json"
    EOF
    
  2. 將 Pod 的 YAML 套用至叢集。

    env HTTPS_PROXY=http://localhost:8118 \
     kubectl apply -f sample-pod.yaml
    

使用 Google Cloud 工作負載身分

支援的 SDK 版本

如要使用 Google Cloud Workload Identity 功能,您必須使用支援這項功能的 SDK 建構程式碼。如要查看支援 workload identity 的 SDK 版本清單,請參閱「Fleet Workload Identity」。Google Cloud

使用 Workload Identity 的程式碼範例

本節包含使用 Google Cloud 工作負載身分識別的 Python 程式碼範例。在本範例中,服務帳戶會使用具有「Cloud Storage 管理員」權限的身分,列出專案的所有 Cloud Storage 值區。 Google Cloud

  1. 在 Pod 中執行殼層。

    env HTTPS_PROXY=http://localhost:8118 \
    kubectl exec -it sample-pod -- bash
    
  2. 執行指令碼,列出專案的儲存空間 bucket。

    # execute these commands inside the Pod
    pip install --upgrade google-cloud-storage
    
    cat << EOF > sample-list-bucket.py
    from google.cloud import storage
    storage_client = storage.Client()
    buckets = storage_client.list_buckets()
    
    for bucket in buckets:
      print(bucket.name)
    EOF
    
    env GOOGLE_CLOUD_PROJECT=USER_PROJECT_NAME \
     python3 sample-list-bucket.py
    

    USER_PROJECT_NAME 替換為您的 Google Cloud 專案。

如需更多資訊