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

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

本主题介绍了如何创建 OIDC 提供商、预配服务账号以及使用工作负载身份测试示例工作负载。

为您的集群创建 AWS IAM OIDC 提供商

如需将工作负载身份与您的集群搭配使用,请先创建一个引用您的集群的 AWS IAM OIDC 提供商。如果您的集群已有 IAM OIDC 提供商,则可以跳过本部分。

如需创建该提供商,请按照以下步骤操作:

  1. 确定您的集群的 OIDC 颁发者 URI:

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

    替换以下内容:

    • CLUSTER_NAME:您的集群的名称
    • GOOGLE_CLOUD_LOCATION:要在其中管理节点池的 Google Cloud 位置的名称,如 Google Cloud 管理区域中所定义

    输出包括集群的 OIDC 颁发者 URI。保存此值以供以下步骤使用。

  2. 接下来,使用以下命令创建一个引用您的集群的 AWS IAM OIDC 提供商:

    aws iam create-open-id-connect-provider \
        --url ISSUER_URI \
        --client-id-list sts.amazonaws.com \
        --thumbprint-list 08745487e891c19e3078c1f2a07e452950ef36f6
    

    ISSUER_URI 替换为上一步中的颁发者 URI。

    处理颁发者 URI 的 Google Cloud 服务的指纹始终为 08745487e891c19e3078c1f2a07e452950ef36f6

使用附加的 IAM 政策配置 AWS IAM 角色

如需配置 AWS IAM 角色并向其附加政策,请按照以下步骤操作:

  1. 通过从颁发者 URI 中移除 https:// 前缀来确定颁发者主机。例如,如果您的 URI 为 https://oidc-provider.com/v1/projects/pid/locations/us-west1/awsClusters/awscluster,则主机为 oidc-provider.com/v1/projects/pid/locations/us-west1/awsClusters/awscluster。保存此值。您之后会用到它。

  2. 通过运行以下命令确定提供商的 Amazon 资源名称 (ARN):

    aws iam list-open-id-connect-providers --output=text \
        --query 'OpenIDConnectProviderList[?ends_with(Arn, `ISSUER_HOST`) == `true`].Arn'
    

    ISSUER_HOST 替换为集群的颁发者 URI 中的主机名。

  3. 接下来,创建一项信任政策以向 Kubernetes 服务账号提供 OIDC 凭据。创建名为 trust-policy.json 且包含以下内容的文件:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "PROVIDER_ARN"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "ISSUER_HOST:sub": "system:serviceaccount:NAMESPACE:KSA_NAME"
            }
          }
        }
      ]
    }
    

    替换以下内容:

    • PROVIDER_ARN:集群的 IAM OIDC 提供商的 ARN
    • ISSUER_HOST:集群的颁发者 URI 中的主机名。
    • NAMESPACE:在其中运行应用的 Kubernetes 命名空间
    • KSA_NAME:用于应用的 Kubernetes 服务账号 (KSA)
  4. 创建 AWS IAM 角色:

    aws iam create-role --role-name=AWS_ROLE_NAME \
        --assume-role-policy-document file://trust-policy.json
    

    AWS_ROLE_NAME 替换为应用的 AWS IAM 角色名称。

  5. 向该角色附加 AWS IAM 政策:

    aws iam attach-role-policy --role-name=AWS_ROLE_NAME \
        --policy-arn=AWS_POLICY_ARN
    

    请替换以下内容:

    • AWS_ROLE_NAME:应用的 AWS IAM 角色名称

    例如,如需使用 arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess 政策创建名为 ec2-readonly 的角色,请运行以下命令:

    aws iam attach-role-policy --role-name=ec2-readonly \
        --policy-arn=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
    

部署一个示例应用

如需测试工作负载身份,请按照以下步骤部署示例应用:

  1. 确定角色的 ARN:

    aws iam get-role --role-name=AWS_ROLE_NAME --query 'Role.Arn'
    

    替换 AWS_ROLE_NAME

  2. 为 Kubernetes 命名空间、KSA 和 Pod 创建清单。将以下清单复制到名为 workload-identity-test.yaml 的文件中:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: NAMESPACE
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: KSA_NAME
      namespace: NAMESPACE
    automountServiceAccountToken: false
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: aws-cli-example
      namespace: NAMESPACE
    spec:
      serviceAccount: KSA_NAME
      containers:
      - name: aws-cli
        image: amazon/aws-cli:latest
        command:
        - /bin/bash
        - -c
        - "set -eu -o pipefail; while true; do aws ec2 describe-availability-zones; sleep 5; done"
        env:
        - name: AWS_ROLE_ARN
          value: AWS_ROLE_ARN
        - name: AWS_WEB_IDENTITY_TOKEN_FILE
          value: /var/run/secrets/aws-iam-token/serviceaccount/token
        - name: AWS_REGION
          value: AWS_REGION
        volumeMounts:
        - mountPath: /var/run/secrets/aws-iam-token/serviceaccount
          name: aws-iam-token
          readOnly: true
      volumes:
      - name: aws-iam-token
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              audience: sts.amazonaws.com
              expirationSeconds: 86400
              path: token
    

    替换以下内容:

    • NAMESPACE
    • KSA_NAME
    • AWS_ROLE_ARN:应用的 AWS IAM 角色的 ARN
    • AWS_REGION:集群的 AWS 区域
  3. 应用清单:

    kubectl apply -f workload-identity-test.yaml
    

    等待几分钟,让 Pod 启动,然后转到下一部分。

验证示例应用是否正常运行

如需验证示例应用是否可以访问 EC2 API,请查看 pod 的日志:

kubectl logs -f aws-cli-example -n NAMESPACE

如果 Pod 可以访问 EC2 API,则输出包含有关 EC2 可用区的信息,并且类似于以下内容:

-------------------------------------------------
|           DescribeAvailabilityZones           |
+-----------------------------------------------+
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az1             ||
||  ZoneName           |  us-west-2a           ||
|+---------------------+-----------------------+|
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az2             ||
||  ZoneName           |  us-west-2b           ||
|+---------------------+-----------------------+|
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az3             ||
||  ZoneName           |  us-west-2c           ||
|+---------------------+-----------------------+|
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az4             ||
||  ZoneName           |  us-west-2d           ||
|+---------------------+-----------------------+|

清理

如需移除示例应用,请按照以下步骤操作:

  1. 从集群中删除示例应用的清单:

    kubectl delete -f workload-identity-test.yaml
    
  2. 从角色中分离 AWS IAM 政策:

    aws iam detach-role-policy --role-name AWS_ROLE_NAME \
        --policy-arn arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
    

    AWS_ROLE_NAME 替换为应用的 AWS IAM 角色名称。

  3. 删除 AWS IAM 角色:

    aws iam delete-role --role-name AWS_ROLE_NAME
    

    AWS_ROLE_NAME 替换为应用的 AWS IAM 角色名称。

  4. 删除 AWS IAM OIDC 提供商:

    aws iam delete-open-id-connect-provider --open-id-connect-provider-arn PROVIDER_ARN
    

    PROVIDER_ARN 替换为集群的 IAM OIDC 提供商的 ARN。

后续步骤