搭配使用 Workload Identity 與 Google Cloud

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

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

總覽

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

必要條件

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

  • 如果 AWS 虛擬私有雲使用 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 模式的 ID 提供者。如要進一步瞭解 Workload Identity 集區,請參閱「啟用 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 設定對應

執行下列殼層指令碼,將工作負載身分識別詳細資料儲存在 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 版本清單,請參閱「機群 Workload Identity」。Google Cloud

使用 Workload Identity 的程式碼範例

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

  1. 在 Pod 中執行殼層。

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

    # 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 專案。

如需更多資訊