AWS で Workload Identity を使用する

Workload Identity を使用すると、クラスタ内のアプリケーションごとにきめ細かい ID と認可を割り当てることができます。GKE on AWS 上で動作するアプリケーションが AWS やその他の Google Cloud サービスにアクセスするには、Workload Identity が推奨される方法です。詳細については、Workload Identity をご覧ください。

このトピックでは、OIDC プロバイダの作成、サービス アカウントのプロビジョニング、ワークロード ID を使用したサンプル ワークロードのテストを行う方法について説明します。このページは、ユーザー権限に関連するポリシーを作成および管理する ID とアカウントの管理者、運用者、開発者の方を対象としています。 Google Cloud のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。

クラスタに 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. 次に、信頼ポリシーを作成して、OIDC 認証情報を Kubernetes サービス アカウントに提供します。次の内容のファイルを 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 の Namespace、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 に置き換えます。

次のステップ