将工作负载身份与 Google Cloud 搭配使用

工作负载身份让您可以为集群中的每个应用分配不同的精细身份和授权。对于在 GKE on AWS 中运行的应用访问 Google Cloud 服务,建议使用工作负载身份。如需了解详情,请参阅工作负载身份

本主题介绍如何使用工作负载身份从工作负载连接到 Google Cloud 服务。

配置 Google Cloud 服务账号

在本部分中,您将创建一个 Google Cloud 服务账号 (GSA),该账号具有有限的访问 Google Cloud 服务的权限。

获取工作负载身份池和提供商

如需配置工作负载身份,您必须拥有集群的身份提供商 URI 和工作负载身份池的相关值。

  1. 确定集群的工作负载身份池

    所有 GKE 集群都在工作负载身份池 PROJECT_ID.svc.id.goog 中创建了身份提供方。如需获取集群的身份池名称,请使用 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. 确定集群的身份提供商。

    如需查找集群的身份提供商名称,请使用 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),为其授予权限并向 GSA 添加 IAM 政策绑定,请执行以下步骤:

  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
    • IAM_ROLE:为 GSA 授予的 IAM 角色

    在此示例中,我们将使用 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 计算 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

后续步骤