Workload Identity 集群身份验证

本文档介绍了如何为 Google Distributed Cloud connected 设置和使用 Workload Identity 集群身份验证。Workload Identity 集群身份验证使用 短期令牌和工作负载身份联合来允许工作负载 安全地访问 Google Cloud 资源,而不是使用服务帐号密钥。短期凭据是 OAuth 2.0 访问令牌。默认情况下,访问令牌会在 1 小时后过期。

借助 Workload Identity 集群身份验证,工作负载可以使用自己的 Kubernetes 身份来 访问 Google Cloud 资源,或模拟 Google 服务帐号。

与使用服务帐号密钥相比,Workload Identity 集群身份验证有以下两个主要优势:

  • 提高安全性:如果服务账号密钥管理不当,则会带来安全风险。OAuth 2.0 令牌和工作负载身份联合被视为服务帐号密钥的最佳实践替代方案。如需详细了解服务帐号令牌,请参阅短期有效的服务帐号。如需详细了解工作负载身份联合,请参阅 工作负载身份联合

  • 减少维护工作:服务账号密钥需要更多维护工作。 定期轮替和保护这些密钥可能会带来管理负担。

本页面适用于负责设置、监控和管理底层技术基础架构生命周期的管理员、架构师和运维人员。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和 任务

集群管理

本指南介绍了如何为应用使用工作负载身份联合。 对于 Distributed Cloud connected 集群,系统会自动管理集群级工作负载身份联合。

Distributed Cloud connected 集群由 Google 通过 Distributed Cloud Edge Container API创建和管理,方法是使用 gcloud edge-cloud container clusters create 命令或在 Google Cloud 控制台中进行操作。

Distributed Cloud connected 集群会自动注册到其创建所在的项目中的舰队。您无需执行任何手动舰队注册。工作负载身份联合池会自动提供,并 遵循格式 PROJECT_ID.svc.id.goog

准备工作

  • 如需设置工作负载身份联合,请先验证您的 Google Cloud 项目是否已启用以下 API。如需了解如何 启用 API,请参阅 启用服务

    • iam.googleapis.com
    • sts.googleapis.com
    • iamcredentials.googleapis.com
    • gkehub.googleapis.com
  • 确保您已安装以下命令行工具:

    • 最新版本的 Google Cloud CLI,其中 包含 gcloud,用于与交互的命令行工具 Google Cloud。
    • kubectl

    如果您使用 Cloud Shell 作为与 Google Cloud交互的 Shell 环境,则系统会为您安装这些工具。

  • 确保您已初始化用于您项目的 gcloud CLI。

  • 确保您拥有项目的以下 IAM 角色。 执行设置需要这些角色:

    • 所有者 (roles/owner) 或
    • IAM Security Admin (roles/iam.securityAdmin) 和 Service Account Admin (roles/iam.serviceAccountAdmin)

在以下部分中,您将创建服务账号并授予 Workload Identity 集群身份验证所需的角色。

推荐:工作负载身份联合直接资源访问权限

借助工作负载身份联合直接资源访问权限,您可以使用工作负载身份联合向 Kubernetes ServiceAccount 授予 IAM 角色,以便它可以直接访问 Google Cloud资源。

身份 用途 角色
Kubernetes ServiceAccount 工作负载使用的 Kubernetes 身份。向此身份授予访问所需 Google Cloud 资源所需的 角色。此示例授予了 roles/storage.objectViewer 角色和 roles/logging.admin 角色。 roles/storage.objectViewer
roles/logging.admin

替代方法:IAM 服务帐号模拟

或者,您可以配置 Kubernetes ServiceAccount 以使用 IAM 服务帐号模拟。

服务账号 用途 角色
Google 服务帐号 集群内工作负载模拟的 Google 服务帐号。向此服务帐号授予访问所需 Google Cloud 资源所需的角色。 取决于要访问的资源。
Kubernetes ServiceAccount 向此身份授予模拟 Google 服务帐号的权限。此授予使用 roles/iam.workloadIdentityUser 角色。 roles/iam.workloadIdentityUser

设置服务账号

以下部分包含有关如何创建所需的 Kubernetes ServiceAccount 以及如何使用工作负载身份联合直接资源访问权限或 Google 服务帐号模拟向其授予 Workload Identity 集群身份验证所需角色的说明。

创建 Kubernetes ServiceAccount

在集群中,使用 kubectl create 命令为 Pod 创建 Kubernetes ServiceAccount。您还可以使用任何现有的 ServiceAccount,包括命名空间中的默认 ServiceAccount

kubectl create serviceaccount KSA_NAME --namespace NAMESPACE

替换以下值:

  • KSA_NAME:Kubernetes ServiceAccount 的名称

  • NAMESPACE:集群的命名空间

使用工作负载身份联合授予直接资源访问权限

如需直接向 Kubernetes ServiceAccount 身份授予 Identity and Access Management 角色,请按以下步骤操作。

  1. 使用 gcloud projects describe 命令查找您的项目数字编号:

    gcloud projects describe PROJECT_ID --format="value(projectNumber)"
    

    PROJECT_ID 替换为您的项目 ID。

  2. 使用 gcloud projects add-iam-policy-binding 命令向 Kubernetes 身份正文授予所需的角色:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member="principal://iam.gserviceaccount.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME" \
        --role=roles/storage.objectViewer
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member="principal://iam.gserviceaccount.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME" \
        --role=roles/logging.admin
    

    替换以下值:

    • PROJECT_NUMBER:您的项目数字编号
    • NAMESPACE:集群的命名空间
    • KSA_NAME:Kubernetes ServiceAccount 的名称

替代方法:使用 IAM 服务帐号模拟来授予访问权限

如果您希望工作负载模拟 Google 服务帐号,请按以下步骤操作。

  1. 使用 gcloud iam service-accounts create 命令创建 Google 服务帐号:

    gcloud iam service-accounts create my-app-sa \
        --project=PROJECT_ID
    

    PROJECT_ID 替换为您的项目 ID。

  2. 使用 gcloud projects add-iam-policy-binding 命令向 Google 服务帐号授予所需的角色:

    gcloud projects add-iam-policy-binding PROJECT_ID \
    --member=serviceAccount:my-app-sa@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/storage.objectViewer
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
    --member=serviceAccount:my-app-sa@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/logging.admin
    
  3. 使用 gcloud iam service-accounts add-iam-policy-binding 命令向 Kubernetes ServiceAccount 授予模拟 Google 服务帐号的权限:

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

    替换以下值:

    • NAMESPACE:集群的命名空间
    • KSA_NAME:Kubernetes ServiceAccount 的名称
  4. 使用 kubectl annotate 命令为 Kubernetes ServiceAccount 添加注解,以将其与 Google 服务帐号相关联:

    kubectl annotate serviceaccount \
        --namespace NAMESPACE KSA_NAME \
        iam.gke.io/gcp-service-account=my-app-sa@PROJECT_ID.iam.gserviceaccount.com
    

配置工作负载

更新 Pod 规范以使用 Kubernetes ServiceAccount 并挂载投影的令牌卷。由于 Distributed Cloud connected 集群位于 Google Cloud之外,因此您还必须提供凭据配置文件,并将 GOOGLE_APPLICATION_CREDENTIALS 环境变量设置为指向该文件。 Google Cloud Pod 中的客户端库使用这些凭据通过 Security Token Service API 将 Kubernetes 令牌交换为 Google Cloud 访问令牌。

  1. 生成 credential-configuration.json 文件。根据您使用的是工作负载身份联合直接资源访问权限还是 IAM 服务帐号模拟,选择相应的命令。

    工作负载身份联合直接资源访问权限

    使用 gcloud iam workload-identity-pools create-cred-config 命令:

    gcloud iam workload-identity-pools create-cred-config \
        projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/providers/attestor \
        --credential-source-file=/var/run/secrets/tokens/gcp-ksa/token \
        --credential-source-type=text \
        --output-file=credential-configuration.json
    

    使用 IAM 服务帐号模拟来授予访问权限

    使用 gcloud iam workload-identity-pools create-cred-config 命令:

    gcloud iam workload-identity-pools create-cred-config \
        projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/providers/attestor \
        --service-account=my-app-sa@PROJECT_ID.iam.gserviceaccount.com \
        --credential-source-file=/var/run/secrets/tokens/gcp-ksa/token \
        --credential-source-type=text \
        --output-file=credential-configuration.json
    

    PROJECT_NUMBER 替换为您的 Google Cloud 项目 编号。您可以通过运行 gcloud projects describe PROJECT_ID --format="value(projectNumber)" 找到项目编号。

  2. 使用 kubectl create configmap 命令创建 Kubernetes ConfigMap 以存储配置文件:

    kubectl create configmap CREDENTIAL_CONFIG_MAP \
        --namespace NAMESPACE \
        --from-file=credential-configuration.json
    

    替换以下值:

    • CREDENTIAL_CONFIG_MAPConfigMap 的名称,其中包含凭据配置文件

    • NAMESPACE:集群的命名空间

  3. 使用以下 YAML 内容更新 Pod 规范:

    spec:
      serviceAccountName: KSA_NAME
      containers:
      - name: MY_CONTAINER
        image: MY_IMAGE
        env:
        - name: GOOGLE_APPLICATION_CREDENTIALS
          value: /var/run/secrets/tokens/gcp-creds/credential-configuration.json
        volumeMounts:
        - mountPath: /var/run/secrets/tokens/gcp-ksa
          name: gcp-ksa
        - mountPath: /var/run/secrets/tokens/gcp-creds
          name: gcp-creds
          readOnly: true
      volumes:
      - name: gcp-ksa
        projected:
          defaultMode: 0420
          sources:
          - serviceAccountToken:
              path: token
              audience: PROJECT_ID.svc.id.goog
              expirationSeconds: 3600
      - name: gcp-creds
        configMap:
          name: CREDENTIAL_CONFIG_MAP
    

    替换以下值:

    • KSA_NAME:Kubernetes ServiceAccount 的名称

    • MY_CONTAINER:容器的名称

    • MY_IMAGE:映像的名称

限制

当您为 Distributed Cloud connected 使用工作负载身份联合时,不支持以下功能:

  • 在令牌交换过程中使用代理服务器

如需了解如何将工作负载身份联合与 VPC Service Controls 结合使用, 请参阅 配置 VPC Service Controls 集成

后续步骤