Kubernetes との Workload Identity 連携を構成する

このガイドでは、Workload Identity 連携を使用して、Azure Kubernetes Service(AKS)、Amazon Elastic Kubernetes Service、またはセルフホストの Kubernetes クラスタで実行されるワークロードを Google Cloud で認証できるようにする方法について説明します。

Kubernetes では、ワークロードが予測ボリュームから Kubernetes サービス アカウント トークンを取得できるように、クラスタを構成できます。Workload Identity 連携を設定すると、ワークロードはこれらの Kubernetes サービス アカウント トークンで Google Cloud への認証ができるようになります。

GKE を使用している場合は、Workload Identity 連携を構成する代わりに Workload Identity を使用します。

準備

Workload Identity 連携を構成する前に、Kubernetes クラスタが次の条件を満たしていることを確認してください。

AKS

クラスタが次の条件を満たしていることを確認します。

  • OIDC 発行者機能を有効にしている。

    Workload Identity 連携が OpenID Connect メタデータとクラスタの JSON Web Key Set(JWKS)にアクセスできるように、この機能を有効にする必要があります。

EKS

EKS 構成を変更する必要はありません。

Kubernetes

クラスタが次の条件を満たしていることを確認します。

  • Kubernetes 1.20 以降を実行している。

    以前のバージョンの Kubernetes では、このドキュメントの手順と互換性のない別のサービス アカウント トークン形式が使用されていました。

  • ServiceAccount トークン ボリュームの予測をサポートするように kube-apiserver を構成している。

クラスタにインターネット経由でアクセスできるようにする必要はありません。

Workload Identity 連携を構成する

この手順は、各 Kubernetes クラスタに対して 1 回ずつ実行すれば十分です。これにより、複数の Kubernetes Pod と複数の Google Cloud プロジェクトで同じ Workload Identity のプールとプロバイダを使用できます。

Workload Identity 連携の構成を開始するには、次の操作を行います。

  1. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  2. Workload Identity のプールとプロバイダの管理に専用のプロジェクトを使用することをおすすめします。
  3. Google Cloud プロジェクトで課金が有効になっていることを確認します

  4. IAM, Resource Manager, Service Account Credentials, and Security Token Service API を有効にします。

    API を有効にする

属性のマッピングと条件を定義する

Kubernetes サービス アカウント トークンには、次のような複数のクレームが含まれています。

  • sub: サービス アカウントの名前空間と名前(例: system:serviceaccount:NAMESPACE:KSA_NAME)が含まれます。ここで、NAMESPACE はサービス アカウントの名前空間、KSA_NAME はサービス アカウントの名前です。
  • "kubernetes.io".namespace: サービス アカウントの名前空間が含まれます。
  • "kubernetes.io".serviceaccount.name: サービス アカウントの名前が含まれます。
  • "kubernetes.io".pod.name: Pod の名前が含まれます。

Google Cloud で sub をサブジェクト識別子(google.subject)として使用するには、次のマッピングを使用します。

google.subject=assertion.sub

必要に応じて、追加の属性をマッピングできます。これにより、リソースへのアクセス権を付与する際にこれらの属性を参照できます。次に例を示します。

google.subject=assertion.sub,
attribute.namespace=assertion['kubernetes.io']['namespace'],
attribute.service_account_name=assertion['kubernetes.io']['serviceaccount']['name'],
attribute.pod=assertion['kubernetes.io']['pod']['name']

必要に応じて、属性条件を定義します。属性条件は、アサーション属性とターゲット属性をチェックする CEL 式です。特定の認証情報の属性条件が true と評価されると、認証情報が受け入れられます。それ以外の場合、認証情報は拒否されます。

属性条件を使用して、Workload Identity 連携で有効期間の短い Google Cloud トークンを取得できる Kubernetes サービス アカウントを制限できます。たとえば、次の条件は、backend 名前空間と monitoring 名前空間からの Kubernetes サービス アカウントへのアクセスを制限します。

assertion['kubernetes.io']['namespace'] in ['backend', 'monitoring']

Workload Identity のプールとプロバイダを作成する

必要なロール

Workload Identity 連携の構成に必要な権限を取得するには、プロジェクトに対して次の IAM ロールを付与するよう管理者に依頼してください。

ロールの付与の詳細については、アクセスの管理をご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

また、IAM オーナー(roles/owner)の基本ロールには ID 連携を構成する権限も含まれています。本番環境では基本ロールを付与すべきではありません。基本ロールは、開発環境またはテスト環境で付与してください。

Workload Identity のプールとプロバイダを作成する手順は次のとおりです。

AKS

  1. AKS クラスタの発行元 URL を確認します。

    az aks show -n NAME -g RESOURCE_GROUP --query "oidcIssuerProfile.issuerUrl" -otsv
    

    次のように置き換えます。

    • NAME: クラスタの名前
    • RESOURCE_GROUP: クラスタのリソース グループ

    このコマンドによって発行元の URL が出力されます。次のいずれかの手順で発行元の URL が必要になります。

    コマンドで発行元の URL が返されない場合は、OIDC 発行者機能が有効になっていることを確認します。

  2. Workload Identity プールを新規作成します。

    gcloud iam workload-identity-pools create POOL_ID \
        --location="global" \
        --description="DESCRIPTION" \
        --display-name="DISPLAY_NAME"
    

    次のように置き換えます。

    • POOL_ID: プールの一意の ID。
    • DISPLAY_NAME: プールの名前。
    • DESCRIPTION: 選択したプールの説明。この説明は、プール ID へのアクセス権を付与するときに表示されます。
  3. AKS クラスタを Workload Identity プール プロバイダとして追加します。

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
    

    次のように置き換えます。

    • PROVIDER_ID: 一意の Workload Identity プール プロバイダ ID。
    • POOL_ID: 前に作成した Workload Identity プール ID。
    • ISSUER: 前に確認した発行元 URI。
    • MAPPINGS: このガイドの前半で作成した属性マッピングのカンマ区切りリスト。
    • CONDITIONS: このガイドの前半で作成した属性条件。属性条件がない場合は、パラメータを削除します。

EKS

  1. EKS クラスタの発行元 URL を確認します。

    aws eks describe-cluster --name NAME --query "cluster.identity.oidc.issuer" --output text
    

    NAME は、クラスタの名前に置き換えます。

    このコマンドによって発行元の URL が出力されます。次のいずれかの手順で発行元の URL が必要になります。

  2. Workload Identity プールを新規作成します。

    gcloud iam workload-identity-pools create POOL_ID \
        --location="global" \
        --description="DESCRIPTION" \
        --display-name="DISPLAY_NAME"
    

    次のように置き換えます。

    • POOL_ID: プールの一意の ID。
    • DISPLAY_NAME: プールの名前。
    • DESCRIPTION: 選択したプールの説明。この説明は、プール ID へのアクセス権を付与するときに表示されます。
  3. EKS クラスタを Workload Identity プール プロバイダとして追加します。

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
    

    次のように置き換えます。

    • PROVIDER_ID: 一意の Workload Identity プール プロバイダ ID。
    • POOL_ID: 前に作成した Workload Identity プール ID。
    • ISSUER: 前に確認した発行元 URI。
    • MAPPINGS: このガイドの前半で作成した属性マッピングのカンマ区切りリスト。
    • CONDITIONS: このガイドの前半で作成した属性条件。属性条件がない場合は、パラメータを削除します。

Kubernetes

  1. Kubernetes クラスタに接続し、kubectl を使用してクラスタの発行元 URL を確認します。

    kubectl get --raw /.well-known/openid-configuration | jq -r .issuer
    

    次のいずれかの手順で発行元の URL が必要になります。

  2. クラスタの JSON Web Key Set(JWKS)をダウンロードします。

    kubectl get --raw /openid/v1/jwks > cluster-jwks.json
    

    次のいずれかの手順で JWKS をアップロードして、Workload Identity 連携によりクラスタで発行された Kubernetes サービス アカウント トークンの信頼性を確認できるようにします。

  3. Workload Identity プールを新規作成します。

    gcloud iam workload-identity-pools create POOL_ID \
        --location="global" \
        --description="DESCRIPTION" \
        --display-name="DISPLAY_NAME"
    

    次のように置き換えます。

    • POOL_ID: プールの一意の ID。
    • DISPLAY_NAME: プールの名前。
    • DESCRIPTION: 選択したプールの説明。この説明は、プール ID へのアクセス権を付与するときに表示されます。
  4. Kubernetes クラスタを Workload Identity プールのプロバイダとして追加し、クラスタの JWKS をアップロードします。

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS" \
        --jwk-json-path="cluster-jwks.json"
    

    次のように置き換えます。

    • PROVIDER_ID: 一意の Workload Identity プール プロバイダ ID。
    • POOL_ID: 前に作成した Workload Identity プール ID。
    • ISSUER: 前に確認した発行元 URI。
    • MAPPINGS: このガイドの前半で作成した属性マッピングのカンマ区切りリスト。
    • CONDITIONS: このガイドの前半で作成した属性条件。属性条件がない場合は、パラメータを削除します。

Kubernetes ワークロードを認証する

このセクションでは、Workload Identity 連携を使用するように Kubernetes ワークロードを構成する方法について説明します。

この手順は、Google Cloud にアクセスする必要がある Kubernetes ワークロードごとに 1 回行う必要があります。

サービス アカウントのペアを作成する

Kubernetes ワークロードを Google Cloud で認証できるようにするには、次のサービス アカウントのペアが必要です。

  • Kubernetes Pod に接続する Kubernetes サービス アカウント。
  • 接続された Kubernetes サービス アカウントを利用して Kubernetes ワークロードがその権限を借用できる IAM サービス アカウント。

サービス アカウントを作成するには、次の手順を行います。

  1. ワークロードを表す IAM サービス アカウントを作成します。

    サービス アカウントは、Workload Identity プールと同じプロジェクトにある必要はありません。

    gcloud iam service-accounts create SA_NAME
    

    次のように置き換えます。

    • SA_NAME: サービス アカウントの名前。
  2. Kubernetes サービス アカウントを作成します。

    kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
    

    次のように置き換えます。

    • KSA_NAME: サービス アカウントの名前。
    • NAMESPACE: サービス アカウントを作成する名前空間。
  3. Kubernetes ワークロードにアクセスを許可するリソースに対するアクセス権を IAM サービス アカウントに付与します。

  4. Kubernetes サービス アカウントの外部 ID に Workload Identity ユーザーロール(roles/iam.workloadIdentityUser)を付与します。

    gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \
        --role=roles/iam.workloadIdentityUser \
        --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT"
    

    次のように置き換えます。

    • SERVICE_ACCOUNT_EMAIL: サービス アカウントのメールアドレス。
    • PROJECT_NUMBER: Workload Identity プールを含むプロジェクトのプロジェクト番号
    • POOL_ID: Workload Identity プールのプール ID。
    • SUBJECT: google.subjectマッピングされている属性の想定値(例: system:serviceaccount:NAMESPACE:KSA_NAME)。

Kubernetes ワークロードをデプロイする

Kubernetes ワークロードをデプロイし、サービス アカウントのペアを使用できるようにします。

  1. 認証情報構成ファイルを作成します。

    gcloud iam workload-identity-pools create-cred-config \
        projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \
        --service-account=SERVICE_ACCOUNT_EMAIL \
        --credential-source-file=/var/run/service-account/token \
        --credential-source-type=text \
        --output-file=credential-configuration.json
    

    次のように置き換えます。

    • PROJECT_NUMBER: Workload Identity プールを含むプロジェクトのプロジェクト番号
    • POOL_ID: Workload Identity プールの ID
    • PROVIDER_ID: Workload Identity プール プロバイダの ID
    • SERVICE_ACCOUNT_EMAIL: サービス アカウントのメールアドレス。

    認証情報の構成ファイルを使用すると、Cloud クライアント ライブラリ、gcloud CLI、Terraform で次の情報を確認できます。

    • 外部認証情報の取得元
    • 使用する Workload Identity プールとプロバイダ
    • 権限を借用するサービス アカウント
  2. 認証情報構成ファイルを ConfigMap としてインポートします。

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

    次のように置き換えます。

    • CONFIGMAP_NAME: ConfigMap の名前。
    • NAMESPACE: ConfigMap を作成する名前空間。
  3. ワークロードをデプロイして、Kubernetes サービス アカウントと ConfigMap を使用できるようにします。

    マニフェストを作成して次のように構成します。

    • ワークロードがローカル ファイルから Kubernetes サービス アカウント トークンを取得できるように、予測されたトークン ボリュームをマウントします。Kubernetes サービス アカウント トークンが、Workload Identity 連携プールのプロバイダが想定するオーディエンスを使用するように、ボリュームを構成します。
    • ワークロードが Workload Identity 連携を使用するために必要な構成にアクセスできるように、認証情報の構成ファイルを含む ConfigMap をマウントします。
    • ワークロードがファイルを検出できるように、認証情報の構成ファイルのパスを含む環境変数 GOOGLE_APPLICATION_CREDENTIALS を追加します。

    Kubernetes サービス アカウントと ConfigMap を使用して Google Cloud CLI が Google Cloud に対して認証されるようにするマニフェストの例を次に示します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: example
      namespace: NAMESPACE
    spec:
      containers:
      - name: example
        image: google/cloud-sdk:alpine
        command: ["/bin/sh", "-c", "gcloud auth login --cred-file $GOOGLE_APPLICATION_CREDENTIALS && gcloud auth list && sleep 600"]
        volumeMounts:
        - name: token
          mountPath: "/var/run/service-account"
          readOnly: true
        - name: workload-identity-credential-configuration
          mountPath: "/etc/workload-identity"
          readOnly: true
        env:
        - name: GOOGLE_APPLICATION_CREDENTIALS
          value: "/etc/workload-identity/credential-configuration.json"
    
      serviceAccountName: KSA_NAME
      volumes:
      - name: token
        projected:
          sources:
          - serviceAccountToken:
              audience: https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID
              expirationSeconds: 3600
              path: token
      - name: workload-identity-credential-configuration
        configMap:
          name: CONFIGMAP_NAME
    

    同じ方法で、次のいずれかのクライアント ライブラリを使用するツールとワークロードで認証情報を自動的に検索できます。

    C++

    C++ 用 Google Cloud クライアント ライブラリは、バージョン v2.6.0 から Workload Identity 連携をサポートしています。Workload Identity 連携を使用するには、バージョン 1.36.0 以降の gRPC でクライアント ライブラリをビルドする必要があります。

    Go

    Go 用クライアント ライブラリは、golang.org/x/oauth2 モジュールのバージョン v0.0.0-20210218202405-ba52d332ba99 以降を使用している場合、ID 連携をサポートします。

    クライアント ライブラリが使用しているこのモジュールのバージョンを確認するには、次のコマンドを実行します。

    cd $GOPATH/src/cloud.google.com/go
    go list -m golang.org/x/oauth2
    

    Java

    Java 用クライアント ライブラリは、com.google.auth:google-auth-library-oauth2-http アーティファクトのバージョン 0.24.0 以降を使用している場合、ID 連携をサポートします。

    クライアント ライブラリで使用しているこのアーティファクトのバージョンを確認するには、アプリケーション ディレクトリで次の Maven コマンドを実行します。

    mvn dependency:list -DincludeArtifactIds=google-auth-library-oauth2-http
    

    Node.js

    Node.js 用クライアント ライブラリは、google-auth-library パッケージのバージョン 7.0.2 以降を使用している場合、Workload Identity 連携をサポートします。

    クライアント ライブラリで使用されているこのパッケージのバージョンを確認するには、アプリケーション ディレクトリで次のコマンドを実行します。

    npm list google-auth-library
    

    GoogleAuth オブジェクトを作成するときに、プロジェクト ID を指定できます。また、GoogleAuth で自動的にプロジェクト ID を検出することもできます。プロジェクト ID を自動的に検出するには、構成ファイルのサービス アカウントに、プロジェクト上でブラウザのロール(roles/browser)または同等の権限を持つロールが付与されている必要があります。詳細については、google-auth-library パッケージの README をご覧ください。

    Python

    Python 用クライアント ライブラリは、google-auth パッケージのバージョン 1.27.0 以降を使用している場合、ID 連携をサポートします。

    クライアント ライブラリで使用されているこのパッケージのバージョンを確認するには、パッケージがインストールされている環境で次のコマンドを実行します。

    pip show google-auth
    

    認証クライアントのプロジェクト ID を指定するには、GOOGLE_CLOUD_PROJECT 環境変数を設定するか、クライアントがプロジェクト ID を自動的に検出するようにします。プロジェクト ID を自動的に検出するには、構成ファイルのサービス アカウントに、プロジェクト上でブラウザのロール(roles/browser)または同等の権限を持つロールが付与されている必要があります。詳細については、google-auth パッケージのユーザーガイドをご覧ください。

    gcloud

    Workload Identity 連携を使用して認証するには、gcloud auth login コマンドを使用します。

    gcloud auth login --cred-file=FILEPATH.json
    

    FILEPATH は、認証情報の構成ファイルのパスに置き換えます。

    gcloud CLI での Workload Identity 連携は、gcloud CLI のバージョン 363.0.0 以降でサポートされています。

    Terraform

    バージョン 3.61.0 以降を使用している場合、Google Cloud プロバイダは Workload Identity 連携をサポートしています。

    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
          version = "~> 3.61.0"
        }
      }
    }
    

    gsutil

    Workload Identity 連携を使用して認証を行うには、次のいずれかの方法を使用します。

    gsutil と gcloud を併用する場合は、通常どおりログインします。

    gcloud auth login --cred-file=FILEPATH.json
    

    gsutil をスタンドアロン コマンドライン アプリケーションとして使用する場合は、.boto ファイルを編集して次のセクションを含めます。

    [Credentials]
    gs_external_account_file = FILEPATH
    

    いずれの場合も、FILEPATH を認証情報の構成ファイルのパスに置き換えます。

    gsutil での Workload Identity 連携は、gcloud CLI のバージョン 379.0.0 以降でサポートされています。

    bq

    Workload Identity 連携を使用して認証するには、次のように gcloud auth login コマンドを使用します。

    gcloud auth login --cred-file=FILEPATH.json
    

    FILEPATH は、認証情報の構成ファイルのパスに置き換えます。

    bq での Workload Identity 連携は、gcloud CLI のバージョン 390.0.0 以降でサポートされています。

  4. 必要に応じて、次のコマンドを実行して、認証が正しく機能することを確認します。

    kubectl exec example --namespace NAMESPACE -- gcloud auth print-access-token
    

次のステップ