共有信頼フリート ワークロードから Google Cloud API に対する認証を行う

このページでは、フリート全体で信頼モデルを共有するフリートから Compute Engine API や AI Platform API などのGoogle Cloud  API に対して認証を行うようアプリケーションを構成する方法について説明します。フリート全体の信頼モデルが画一でない場合は、混合信頼モデルのフリート ワークロードから Google Cloud API に対する認証を行うプレビュー)をご覧ください。

このページは、フリート ワークロードから Google CloudAPI に対してプログラムで認証を行うプラットフォーム管理者や運用担当者、セキュリティ エンジニアを対象としています。 Google Cloudのドキュメントで使用されているユーザーロールとタスク例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。

このページを読む前に、次の内容をよく理解しておいてください。

共有信頼環境でのフリート Workload Identity 連携について

フリート Workload Identity 連携を使用すると、組み込みの Google Cloud と Kubernetes 認証メカニズムを使用して、フリート ワークロードからGoogle Cloud  API への認証を行うことができます。フリート Workload Identity 連携を使用すると、Pod にアクセス トークンをマウントしたり、長期間有効な認証情報を保存したりするなど、安全性の低い方法を使用する必要がなくなります。

デフォルトでは、フリートホスト プロジェクトは Google が管理する Workload Identity プールを使用して、フリート全体のエンティティの ID をプロビジョニングします。フリートまたはフリートホスト プロジェクト内のエンティティで、同じ IAM ID を持つエンティティは、IAM によって同じエンティティと見なされます。この暗黙的な ID の同一性は、シングルテナント フリートなどの共有信頼環境で大規模にアクセス権を付与する場合に便利です。この場合、他のエンティティがリソースに対して意図せず同様の権限を取得しても問題ありません。

始める前に

  • 次のコマンドライン ツールがインストールされていることを確認します。

    • 最新バージョンの Google Cloud CLI( Google Cloudとやり取りするためのコマンドライン ツールである gcloud が含まれる)。
    • kubectl

    Google Cloudを操作するシェル環境として Cloud Shell を使用する場合は、これらのツールがインストールされます。

  • プロジェクトで使用する gcloud CLI が初期化されていることを確認します。

クラスタを準備する

フリートのアプリケーションが連携 ID を受け取るためには、アプリケーションが実行されているクラスタがフリートに登録され、フリート Workload Identity 連携を使用できるように正しく構成されている必要があります。以降のセクションでは、さまざまなタイプのクラスタにフリート Workload Identity 連携を設定する方法について説明します。

GKE

GKE クラスタの場合は、次の操作を行います。

  1. Google Kubernetes Engine クラスタで Workload Identity Federation for GKE を有効にします(まだ有効になっていない場合)。
  2. フリートにクラスタを登録します。

クラスタの作成プロセスとフリートの登録プロセスで、Workload Identity Federation for GKE を有効にすることもできます。

Google Cloud外のクラスタ

次のタイプのクラスタでは、フリート Workload Identity 連携が自動的に有効になり、クラスタの作成時にフリートに登録されます。

  • Google Distributed Cloud on VMware(ソフトウェアのみ)
  • Google Distributed Cloud on Bare Metal(ソフトウェアのみ)
  • GKE on AWS
  • GKE on Azure

接続クラスタ

GKE Multi-Cloud API を使用して登録された EKS 接続クラスタおよび AKS 接続クラスタは、デフォルトで有効になっているフリート Workload Identity 連携に登録されています。必要な要件を満たしている場合、フリート Workload Identity 連携を有効にしてその他の接続クラスタを登録できます。クラスタの登録にあるクラスタタイプに応じた手順に沿います。

アプリケーションでフリート Workload Identity 連携を使用する

次の手順では、フリート Workload Identity 連携を使用できるよう、登録済みクラスタ内のワークロードを構成する方法について説明します。

  1. クラスタの Workload Identity プールと ID プロバイダの名前を確認します。

    gcloud container fleet memberships describe MEMBERSHIP_ID \
        --project=FLEET_PROJECT_ID \
        --format="table(authority.identityProvider,authority.workloadIdentityPool,name)"
    

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

    • MEMBERSHIP_ID: クラスタのメンバーシップ名。多くの場合、これはクラスタの名前です。
    • FLEET_PROJECT_ID: フリート ホスト プロジェクトのプロジェクト ID。

    出力は次のようになります。

    IDENTITY_PROVIDER: IDENTITY_PROVIDER
    WORKLOAD_IDENTITY_POOL: WORKLOAD_IDENTITY_POOL
    NAME: projects/FLEET_PROJECT_ID/locations/MEMBERSHIP_LOCATION/memberships/MEMBERSHIP_ID
    

    この出力には次の情報が含まれます。

    • IDENTITY_PROVIDER: クラスタの ID プロバイダ。
    • MEMBERSHIP_LOCATION: フリート メンバーシップのロケーション。通常は、クラスタのロケーションと同じです。
    • WORKLOAD_IDENTITY_POOL: フリートに関連付けられている Workload Identity プールの名前。この値の構文は FLEET_PROJECT_ID.svc.id.goog です。
  2. Kubernetes 名前空間を作成します。default 名前空間など、既存の名前空間を使用することもできます。

    kubectl create namespace NAMESPACE
    

    NAMESPACE は名前空間の名前に置き換えます。

  3. 名前空間に Kubernetes ServiceAccount を作成します。名前空間内の default ServiceAccount など、既存の ServiceAccount を使用することもできます。

    kubectl create serviceaccount KSA_NAME \
        --namespace=NAMESPACE
    

    KSA_NAME は、サービス アカウントの名前に置き換えます。

  4. 次のマニフェストを adc-config-map.yaml として保存します。この ConfigMap には、ワークロードの ADC 構成が含まれています。

    kind: ConfigMap
    apiVersion: v1
    metadata:
      namespace: NAMESPACE
      name: my-cloudsdk-config
    data:
      config: |
        {
          "type": "external_account",
          "audience": "identitynamespace:WORKLOAD_IDENTITY_POOL:IDENTITY_PROVIDER",
          "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
          "token_url": "https://sts.googleapis.com/v1/token",
          "credential_source": {
            "file": "/var/run/secrets/tokens/gcp-ksa/token"
          }
        }
    
  5. ConfigMap をデプロイします。

    kubectl create -f adc-config-map.yaml
    
  6. 次のマニフェストを workload-config.yaml として保存します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
      namespace:  NAMESPACE
    spec:
      serviceAccountName: KSA_NAME
      containers:
      - name: sample-container
        image: google/cloud-sdk:slim
        command: ["sleep","infinity"]
        env:
        - name: GOOGLE_APPLICATION_CREDENTIALS
          value: /var/run/secrets/tokens/gcp-ksa/google-application-credentials.json
        volumeMounts:
        - name: gcp-ksa
          mountPath: /var/run/secrets/tokens/gcp-ksa
          readOnly: true
      volumes:
      - name: gcp-ksa
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              path: token
              audience: WORKLOAD_IDENTITY_POOL
              expirationSeconds: 172800
          - configMap:
              name: my-cloudsdk-config
              optional: false
              items:
              - key: "config"
                path: "google-application-credentials.json"
    

    このワークロードをデプロイすると、Pod の gcp-ksa ボリュームに次のデータが含まれます。

    Pod 内のコンテナは、gcp-ksa ボリュームを /var/run/secrets/tokens/gcp-ksa パスにマウントし、そのパスで認証情報構成 JSON ファイルを検索するように ADC を構成します。

  7. ワークロードをデプロイします。

    kubectl apply -f workload-config.yaml
    

代替方法: IAM サービス アカウントの権限借用

または、クラスタ内の Kubernetes ServiceAccount を IAM サービス アカウントの権限を借用するように構成して、IAM サービス アカウントが実行できる承認済みアクションを実行することもできます。このアプローチでは、IAM と Kubernetes の両方でサービス アカウントのペアを管理する必要があるため、メンテナンスのオーバーヘッドが増える可能性があります。

ほとんどのシナリオでは、アプリケーションでフリート Workload Identity 連携を使用するの手順に沿って、IAM 許可ポリシーで Kubernetes プリンシパルを直接参照し、Google Cloud リソースへのアクセス権を付与することをおすすめします。

  1. クラスタの Workload Identity プールと ID プロバイダの名前を確認します。

    gcloud container fleet memberships describe MEMBERSHIP_ID \
        --project=FLEET_PROJECT_ID \
        --format="table(authority.identityProvider,authority.workloadIdentityPool,name)"
    

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

    • MEMBERSHIP_ID: クラスタのメンバーシップ名。多くの場合、これはクラスタの名前です。
    • FLEET_PROJECT_ID: フリート ホスト プロジェクトのプロジェクト ID。

    出力は次のようになります。

    IDENTITY_PROVIDER: IDENTITY_PROVIDER
    WORKLOAD_IDENTITY_POOL: WORKLOAD_IDENTITY_POOL
    NAME: projects/FLEET_PROJECT_ID/locations/MEMBERSHIP_LOCATION/memberships/MEMBERSHIP_ID
    

    この出力には次の情報が含まれます。

    • IDENTITY_PROVIDER: クラスタの ID プロバイダ。
    • MEMBERSHIP_LOCATION: メンバーシップのロケーション。通常は、クラスタのロケーションと同じです。
    • WORKLOAD_IDENTITY_POOL: フリートに関連付けられている Workload Identity プールの名前。この値の構文は FLEET_PROJECT_ID.svc.id.goog です。
  2. アプリケーションが権限を借用できる IAM サービス アカウントを作成します。既存の IAM サービス アカウントを使用することもできます。

    gcloud iam service-accounts create IAM_SA_NAME \
        --project=IAM_SA_PROJECT_ID
    

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

    • IAM_SA_NAME: IAM サービス アカウントの名前。
    • IAM_SA_PROJECT_ID: IAM サービス アカウントを含むプロジェクトのプロジェクト ID。これはフリートホスト プロジェクトとは異なる場合があります。
  3. 必要な IAM 許可ポリシーを追加して、 Google Cloud API にアクセスするために必要な権限を IAM サービス アカウントに付与します。これは、gcloud iam service-accounts add-iam-policy-binding を使用するか、別の方法で行います。 Google Cloud API の使用に必要な権限は各サービスのドキュメント、必要な権限を含む事前定義ロールの一覧はロールについてをご覧ください。

  4. 名前空間に Kubernetes ServiceAccount を作成します。既存の Kubernetes ServiceAccount と任意の名前空間(default ServiceAccount と default 名前空間など)を使用することもできます。

    kubectl create serviceaccount KSA_NAME \
        --namespace=NAMESPACE
    

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

    • KSA_NAME: ServiceAccount の名前。
    • NAMESPACE: 名前空間の名前。
  5. クラスタ内の特定の名前空間の Kubernetes ServiceAccount が IAM サービス アカウントの権限を借用できるようにする IAM 許可ポリシーを作成します。

    gcloud iam service-accounts add-iam-policy-binding IAM_SA_NAME@IAM_SA_PROJECT_ID.iam.gserviceaccount.com \
        --project=IAM_SA_PROJECT_ID \
        --role=roles/iam.workloadIdentityUser \
        --member="serviceAccount:WORKLOAD_IDENTITY_POOL[NAMESPACE/KSA_NAME]"
    

    WORKLOAD_IDENTITY_POOL は、Workload Identity プールの名前に置き換えます。

  6. 次のマニフェストを adc-config-map.yaml として保存します。この ConfigMap には、ワークロードの ADC 構成が含まれています。

    kind: ConfigMap
    apiVersion: v1
    metadata:
      namespace: K8S_NAMESPACE
      name: my-cloudsdk-config
    data:
      config: |
        {
          "type": "external_account",
          "audience": "identitynamespace:WORKLOAD_IDENTITY_POOL:IDENTITY_PROVIDER",
          "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/IAM_SA_NAME@GSA_PROJECT_ID.iam.gserviceaccount.com:generateAccessToken",
          "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
          "token_url": "https://sts.googleapis.com/v1/token",
          "credential_source": {
            "file": "/var/run/secrets/tokens/gcp-ksa/token"
          }
        }
    

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

    • IAM_SA_NAME: 権限を借用する IAM サービス アカウントの名前。
    • IAM_SA_PROJECT_ID: IAM サービス アカウントのプロジェクト ID。
  7. 次のマニフェストを workload-config.yaml として保存します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
      namespace:  K8S_NAMESPACE
    spec:
      serviceAccountName: KSA_NAME
      containers:
      - name: my-container
        image: my-image
        command: ["sleep","infinity"]
        env:
          - name: GOOGLE_APPLICATION_CREDENTIALS
            value: /var/run/secrets/tokens/gcp-ksa/google-application-credentials.json
        volumeMounts:
        - name: gcp-ksa
          mountPath: /var/run/secrets/tokens/gcp-ksa
          readOnly: true
      volumes:
      - name: gcp-ksa
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              path: token
              audience: WORKLOAD_IDENTITY_POOL
              expirationSeconds: 172800
          - configMap:
              name: my-cloudsdk-config
              optional: false
              items:
                - key: "config"
                  path: "google-application-credentials.json"
    
    

    このワークロードをデプロイすると、Pod の gcp-ksa ボリュームに次のデータが含まれます。

    Pod 内のコンテナは、gcp-ksa ボリュームを /var/run/secrets/tokens/gcp-ksa パスにマウントし、そのパスで認証情報構成 JSON ファイルを検索するように ADC を構成します。

  8. ワークロードをデプロイします。

    kubectl apply -f workload-config.yaml
    

フリート Workload Identity 連携の設定を確認する

このセクションでは、Cloud Storage バケットを作成し、フリート Workload Identity 連携を使用する Pod からバケットにアクセスします。これらの手順を実行する前に、アプリケーションでフリート Workload Identity 連携を使用するセクションの手順に沿って Workload Identity 連携が構成されていることを確認します。

このセクションでは、IAM サービス アカウントの権限借用方法を使用して Workload Identity 連携を確認する方法については説明しません。

  1. プロジェクト番号を確認します。

    gcloud projects describe FLEET_PROJECT_ID \
        --format="value(projectNumber)"
    

    出力は次のようになります。

    1234567890
    
  2. Cloud Storage バケットを作成します。

    gcloud storage buckets create gs://FLEET_PROJECT_ID-test-bucket \
        --location=LOCATION
    

    LOCATION は、 Google Cloudロケーションに置き換えます。

  3. 作成したサービス アカウントにバケットへのアクセスを許可する IAM 許可ポリシーを作成します。

    gcloud storage buckets add-iam-policy-binding gs://FLEET_PROJECT_ID-test-bucket \
        --condition=None \
        --role=roles/storage.objectViewer \
        --member=principal://iam.googleapis.com/projects/FLEET_PROJECT_NUMBER/locations/global/workloadIdentityPools/FLEET_PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME
    

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

    • FLEET_PROJECT_NUMBER: 数値のプロジェクト番号。
    • FLEET_PROJECT_ID: 実際のプロジェクト ID。
    • NAMESPACE: 前のセクションの Pod を実行する Kubernetes 名前空間の名前。
    • KSA_NAME: 前のセクションの Pod が使用する Kubernetes ServiceAccount の名前。
  4. Pod でシェル セッションを作成します。

    kubectl exec -it pods/my-pod --namespace=NAMESPACE -- /bin/bash
    
  5. バケット内にあるオブジェクトを一覧表示してみます。

    curl -X GET -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://storage.googleapis.com/storage/v1/b/FLEET_PROJECT_ID-test-bucket/o"
    

    次のような出力が表示されます。

    {
      "kind": "storage#objects"
    }
    

コードからの認証

Cloud クライアント ライブラリを使用する場合、認証ライブラリは ADC を使用して、 Google Cloud サービスへの認証に使用する認証情報を自動的に検索します。Workload Identity 連携をサポートする Cloud クライアント ライブラリを使用する必要があります。以下に、Cloud クライアント ライブラリの必要な最小バージョンと、現在のバージョンを確認する手順を示します。

C++

C++ 用Google Cloud クライアント ライブラリのほとんどは、grpc::GoogleDefaultCredentials() を呼び出して作成される ChannelCredentials オブジェクトを使用して ID 連携をサポートしています。この認証情報を初期化するには、バージョン 1.36.0 以降の gRPC でクライアント ライブラリを構築する必要があります。

C++ 用 Cloud Storage クライアント ライブラリは、gRPC ではなく REST API を使用するため、ID 連携をサポートしていません。

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 以降を使用している場合、ID 連携をサポートします。

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

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 パッケージのユーザーガイドをご覧ください。

次のステップ

フリート Workload Identity 連携を使用する際のフリート整理に関するベスト プラクティスを確認する。