このページでは、フリート Workload Identity 連携を使用して、Compute Engine API や AI Platform API などの Google Cloud APIs に対して認証を行うようにアプリケーションを構成する方法について説明します。
フリート Workload Identity 連携とは
Workload Identity 連携を使用すると、認証情報のダウンロード、手動ローテーション、一般的な管理を行うことなく、Google Cloud に対してクラスタ内のワークロードの認証ができます。代わりに、ワークロードは Google Cloud によって生成される有効期間の短いトークンを使用して認証されます。
Workload Identity Federation for GKE はプロジェクト全体の Workload Identity プールを提供し、GKE クラスタで実行されているアプリケーションは、ここから ID を取得します。フリート Workload Identity 連携は、クラスタが別のプロジェクトにあるか、Google Cloud の外部にあるかにかかわらず、Workload Identity Federation for GKE をすべてのフリート メンバー クラスタに拡張します。フリート メンバーシップで Workload Identity 連携を有効にした登録済みクラスタは、フリート全体の Workload Identity プールを使用して ID を取得します。これにより、複数のプロジェクトにまたがって、フリート全体で Google Cloud APIs やその他のサービスに対する認証を構成できます。
一部のクラスタタイプでは、Connect Agent でフリート Workload Identity 連携を使用し、フリート メンバーシップの一部として Google Cloud に対して認証できます。また、Cloud Service Mesh など、プロジェクト間で機能する GKE Enterprise 機能を使用するときに必要になることがあります。
Workload Identity 連携プールと ID の同一性
フリート Workload Identity 連携を使用すると、フリート内の各アプリケーションに、Google Cloud や開発する別のサービスに対する認証に使用できる個別の連携 ID が付与されます。アプリケーションは、IAM が認識できるプリンシパル ID を取得します。この ID の構文は次のとおりです。
PREFIX://iam.googleapis.com/projects/FLEET_PROJECT_NUMBER/locations/global/workloadIdentityPools/FLEET_PROJECT_ID.svc.id.goog/SELECTOR
この構文には次のフィールドがあります。
PREFIX
: 選択したリソースに応じて IAMprincipal
またはprincipalSet
。FLEET_PROJECT_ID.svc.id.goog
: フリートの Workload Identity プール。フリートごとに、1 つの固定 Workload Identity プールが自動的に作成されます。FLEET_PROJECT_NUMBER
: フリート ホスト プロジェクトのプロジェクト番号。SELECTOR
: リソース セレクタ。サポートされているセレクタの一覧については、サポートされているプリンシパル ID をご覧ください。
フリート全体がフリートの Workload Identity プールを共有するため、クラスタごとにアクセスを管理することなく、他のプロジェクトやクラウドにあるものも含めて、フリート内の任意のアプリケーションに同じリソースへのアクセス権を付与できます。他のフリート対応の機能と同様に、フリート Workload Identity 連携は同一性の原則に従います。つまり、異なるクラスタで同じ名前と名前空間を持つ Kubernetes オブジェクトは同じものとして扱われます。
たとえば、同じフリート内の複数のクラスタにバックエンドがデプロイされたアプリケーションで Google Cloud API への認証が必要な場合、backend
Namespace 内のすべてのワークロードがその API にアクセスできるようにアプリケーションを構成できます。フリートにおける同一性(ID の同一性など)の利用方法の詳細については、フリートの仕組みをご覧ください。
フリート Workload Identity 連携を有効にすると、対応するプリンシパル ID を指定して、IAM 許可ポリシーでフリートのプリンシパルを参照できます。たとえば、許可ポリシーで特定の Kubernetes Namespace 内の特定の ServiceAccount を参照できます。その ServiceAccount を使用するすべてのアプリケーションは、IAM 許可ポリシーが適用される Google Cloud リソースにアクセスできます。
認証情報フロー
特定の Namespace 内のアプリケーションがフリート Workload Identity 連携を使用して認証できるようにするには、次の操作を行います。
次の情報が含まれる ConfigMap をその Namespace にデプロイします。
- Workload Identity プールとクラスタの ID プロバイダ。
- Kubernetes が ServiceAccount トークンをマウントする各 Pod 内のパス。このトークンは署名付き JSON Web Token(JWT)です。
この ConfigMap は、ワークロードのアプリケーションのデフォルト認証情報(ADC)ファイルとして機能します。
クラスタ内のプリンシパルのプリンシパル ID(Namespace 内の ServiceAccount など)に特定の Google Cloud リソースに対するアクセス権を付与する IAM 許可ポリシーを作成します。
Namespace 内のワークロードの Pod 仕様に、次の構成があることを確認します。
- Pod 内の ConfigMap のマウントパスに設定された
GOOGLE_APPLICATION_CREDENTIALS
環境変数。 GOOGLE_APPLICATION_CREDENTIALS
環境変数で指定したパスにマウントされている、ServiceAccount トークンと作成した ConfigMap を含む予測ボリューム。- 予測ボリュームを参照するコンテナ内のボリューム マウント。
- Pod 内の ConfigMap のマウントパスに設定された
ワークロードが Google Cloud API 呼び出しを行うと、次の処理が行われます。
- Google Cloud 認証ライブラリは、アプリケーションのデフォルト認証情報(ADC)を使用して認証情報を検索します。ADC は、
GOOGLE_APPLICATION_CREDENTIALS
環境変数で指定されたパスをチェックして、認証トークンを探します。 - ADC 認証ライブラリは、ConfigMap 内のデータを使用して、Pod にマウントされた ServiceAccount JWT をワークロードのプリンシパル ID を参照する Security Token Service の有効期間の短い連携トークンと交換します。
- ADC が、連携トークンを API リクエストに含めます。
- IAM 許可ポリシーは、Google Cloud リソースに対してリクエストされたオペレーションを実行することをプリンシパル ID に許可します。
フリート Workload Identity 連携でサポートされているプリンシパル ID
次の表に、IAM 許可ポリシーで使用することでフリート内のプリンシパルを参照できるセレクタを示します。
プリンシパル ID のタイプ | 構文 |
---|---|
特定の Kubernetes ServiceAccount を使用するすべての Pod | 名前で ServiceAccount を選択します。
principal://iam.googleapis.com/projects/ 次のように置き換えます。
UID で ServiceAccount を選択します。 principal://iam.googleapis.com/projects/ 次のように置き換えます。
|
始める前に
次のコマンドライン ツールがインストールされていることを確認します。
- 最新バージョンの Google Cloud CLI、Google Cloud とやり取りするためのコマンドライン ツールである
gcloud
が含まれています。 kubectl
Google Cloud を操作するシェル環境として Cloud Shell を使用する場合は、これらのツールがインストールされます。
- 最新バージョンの Google Cloud CLI、Google Cloud とやり取りするためのコマンドライン ツールである
プロジェクトで使用する gcloud CLI が初期化されていることを確認します。
クラスタを準備する
フリートのアプリケーションが連携 ID を受け取ることに先立ち、アプリケーションが実行されているクラスタは、フリートに登録され、フリート Workload Identity 連携を使用するように正しく構成されている必要があります。以降のセクションでは、さまざまなタイプのクラスタにフリート Workload Identity 連携を設定する方法について説明します。
GKE
GKE クラスタの場合は、次の操作を行います。
- Google Kubernetes Engine クラスタで Workload Identity Federation for GKE を有効にします(有効になっていない場合)。
- フリートにクラスタを登録します。
クラスタの作成プロセスとフリートの登録プロセスで、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 連携を使用するように登録済みクラスタ内のワークロードを構成する方法について説明します。
クラスタの 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
です。
Kubernetes Namespace を作成します。
default
Namespace など、既存の Namespace を使用することもできます。kubectl create namespace NAMESPACE
NAMESPACE
は Namespace の名前に置き換えます。Namespace に Kubernetes ServiceAccount を作成します。Namespace 内の
default
ServiceAccount など、既存の ServiceAccount を使用することもできます。kubectl create serviceaccount KSA_NAME \ --namespace=NAMESPACE
KSA_NAME
は、サービス アカウントの名前に置き換えます。次のマニフェストを
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" } }
ConfigMap をデプロイします。
kubectl create -f adc-config-map.yaml
次のマニフェストを
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
ボリュームに次のデータが含まれます。google-application-credentials.json
という名前のファイルとしてデプロイした ConfigMap 内のデータ。このファイルは ADC 認証情報構成ファイルです。- Kubernetes ServiceAccount トークン(
token
)。Kubernetes は、ServiceAccount の署名付き JWT を予測された ServiceAccount トークン ファイルとしてマウントします。
Pod 内のコンテナは、
gcp-ksa
ボリュームを/var/run/secrets/tokens/gcp-ksa
パスにマウントし、そのパスで認証情報構成 JSON ファイルを検索するように ADC を構成します。ワークロードをデプロイします。
kubectl apply -f workload-config.yaml
代替方法: IAM サービス アカウントの権限借用
または、クラスタ内の Kubernetes ServiceAccount を IAM サービス アカウントの権限を借用するように構成して、IAM サービス アカウントが実行できる承認済みアクションを実行することもできます。このアプローチでは、IAM と Kubernetes の両方でサービス アカウントのペアを管理する必要があるため、メンテナンスのオーバーヘッドが増える可能性があります。
ほとんどのシナリオでは、アプリケーションでフリート Workload Identity 連携を使用するの手順に沿って、IAM 許可ポリシーで Kubernetes プリンシパルを直接参照し、Google Cloud リソースへのアクセス権を付与することをおすすめします。
クラスタの 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
です。
アプリケーションが権限を借用できる 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。これはフリート ホスト プロジェクトとは異なる場合があります。
必要な IAM 許可ポリシーを追加して、Google Cloud APIs にアクセスするために必要な権限を IAM サービス アカウントに付与します。これは、
gcloud iam service-accounts add-iam-policy-binding
を使用するか、別の方法で行います。Google Cloud APIs の使用に必要な権限は各サービスのドキュメント、必要な権限を含む事前定義ロールの一覧はロールについてをご覧ください。Namespace に Kubernetes ServiceAccount を作成します。既存の Kubernetes ServiceAccount と任意の Namespace(
default
ServiceAccount とdefault
Namespace など)を使用することもできます。kubectl create serviceaccount KSA_NAME \ --namespace=NAMESPACE
次のように置き換えます。
KSA_NAME
: ServiceAccount の名前。NAMESPACE
: Namespace の名前。
クラスタ内の特定の Namespace の 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 プールの名前に置き換えます。次のマニフェストを
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。
次のマニフェストを
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
ボリュームに次のデータが含まれます。google-application-credentials.json
という名前のファイルとしてデプロイした ConfigMap 内のデータ。このファイルは ADC 認証情報構成ファイルです。- Kubernetes ServiceAccount トークン(
token
)。Kubernetes は、ServiceAccount の署名付き JWT を予測された ServiceAccount トークン ファイルとしてマウントします。
Pod 内のコンテナは、
gcp-ksa
ボリュームを/var/run/secrets/tokens/gcp-ksa
パスにマウントし、そのパスで認証情報構成 JSON ファイルを検索するように ADC を構成します。ワークロードをデプロイします。
kubectl apply -f workload-config.yaml
フリート Workload Identity 連携の設定を確認する
このセクションでは、Cloud Storage バケットを作成し、フリート Workload Identity 連携を使用する Pod からバケットにアクセスします。これらの手順を実行する前に、アプリケーションでフリート Workload Identity 連携を使用するセクションの手順に沿って Workload Identity 連携が構成されていることを確認します。
このセクションでは、IAM サービス アカウントの権限借用方法を使用して Workload Identity 連携を確認する方法については説明しません。
プロジェクト番号を確認します。
gcloud projects describe FLEET_PROJECT_ID \ --format="value(projectNumber)"
出力は次のようになります。
1234567890
Cloud Storage バケットを作成します。
gcloud storage buckets create gs://FLEET_PROJECT_ID-test-bucket \ --location=LOCATION
LOCATION
は、Google Cloud のロケーションに置き換えます。作成したサービス アカウントにバケットへのアクセスを許可する 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 Namespace の名前。KSA_NAME
: 前のセクションの Pod が使用する Kubernetes ServiceAccount の名前。
Pod でシェル セッションを作成します。
kubectl exec -it pods/my-pod --namespace=NAMESPACE -- /bin/bash
バケット内にあるオブジェクトを一覧表示してみます
curl -X GET -H "Authorization: Bearer $(gcloud auth print-access-token)" \ "https://storage.googleapis.com/storage/v1/b/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 連携を使用する際のフリート整理に関するベスト プラクティスを確認する。