AWS で Workload Identity を使用する

Workload Identity を使用すると、クラスタ内のアプリケーションごとに詳細に設定した個別の ID と認証を割り当てることができます。Workload Identity は、GKE on AWS 内で実行されているアプリケーションで AWS と Google Cloud サービスにアクセスする場合に推奨される方法です。 詳細については、Workload Identity をご覧ください。

このトピックでは、OIDC プロバイダを作成して、サービス アカウントをプロビジョニングし、Workload Identity を使用してサンプル ワークロードをテストする方法について説明します。

クラスタの AWS IAM OIDC プロバイダを作成する

クラスタで Workload Identity を使用するには、まずクラスタを参照する 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 の Namespace
    • 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
    

サンプル アプリケーションをデプロイする

Workload Identity をテストするには、次の手順に従ってサンプル アプリケーションをデプロイします。

  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 に置き換えます。

次のステップ