これまでこの機能はWorkload Identityと呼ばれており、Workload Identity Federation(WIF)は外部IDからGCP内のリソースへアクセスするための類似機能を指す名称でした。
このたびGCPは、Workload IdentityをWorkload Identity Federationの枠組みに統合することを決定しました。名称変更に加え、Kubernetesのエンティティ(クラスタ、サービスアカウント)をIAMプリンシパルとして直接指定できるようになりました。これにより、専用のGoogle Service Account(GSA)や追加のバインディングが不要となり、GKEでのWIFのセットアップが大きく簡素化されます。詳細は後述します。
本記事では、新たに名称が変わったWorkload Identity Federation for GKEの概要と、すでにWorkload Identityバインディングを利用しているワークロードへの影響について解説します。
Workload Identity Federationとは
WIFは、外部のIDシステムとGoogle Cloud IAMを橋渡しするための機能です。Active Directory、AWS、Oktaなど既存のID基盤を、シームレスにGoogle Cloudリソースまで拡張できます。
外部IDプロバイダ(IdP)とGoogle Cloud IAMの間に信頼関係を構築することで、GCP以外のシステムで認証されたユーザーやアプリケーションが、既存のIDのままGCPリソースへアクセスできるようになります。
この信頼関係を構築するには、まず外部IDを管理するWorkload Identity Poolを作成し、続いてIdPとGCPの関係を表すWorkload Identity Providerをプールに追加します。
これが確立されると、IdPの認証トークンはGoogleのSecurity Token Serviceで検証され、GCPへの認証に使うフェデレーショントークンと交換されます。
Workload Identity Federation for GKE(旧称:Workload Identity)では、プールとプロバイダはGoogleが管理してくれます。
各GCPプロジェクトには単一の固定プール(PROJECT_ID.svc.id.goog)が用意されており、GKEクラスタで有効化すると、そのクラスタはプール上のIDプロバイダとして登録されます。
同時にGKEメタデータサーバーがDaemonSetとしてクラスタの全ノードに自動デプロイされます。これは主に、ワークロードからのリクエストをインターセプトし、ワークロードがimpersonateするように設定されたサービスアカウントに対応する正しいトークンを返す役割を担います。
GKEワークロードへのIAM権限の付与
本機能の本質は、明示的な認証情報を渡したり、ノード側のIAMサービスアカウントを利用したりすることなく、GKEワークロードからGCPリソースへアクセスできるようにすることにあります。
まだの場合は、GKEクラスタとノードプールでWIFを有効化する必要がありますが、これは公式ドキュメントに詳しく記載されているため、本記事では扱いません。
有効化が済んだら、ワークロードが利用するKubernetes Service Account(KSA)を作成します(Pod specで指定)。
そのうえで、Workload Identity(WI)では次の2つの方法のいずれかでワークロードにGCP IAM権限を付与できます。
Google IAMサービスアカウントのimpersonationを使う方法
これは少し前までWIを設定する標準的かつ唯一の方法でしたが、現在は代替手段として位置付けられています。
簡単に言うと、Google Service Account(GSA)を作成し、ワークロードに必要なIAM権限を付与します。次に、KSAをそのGSAのroles/iam.workloadIdentityUserに設定してGSAとKSAの間にバインディングを作成し、KSAに対応するアノテーションを付与します。
IAMプリンシパル識別子を使う方法
これは冒頭で触れたとおり、最近追加された大きな機能変更です。KubernetesリソースをプリンシパルとしてIAMポリシーから直接参照できるようになりました。
KSAは名前で参照することも(identity samenessのため)、UIDで参照することもできます(UIDは作成後にKSAのspecから取得できます)。
ワークロード全体に共通して必要なIAM権限がある場合は、クラスタ内のすべてのPodを対象にすることも可能です。
GSA impersonationとIAMプリンシパル識別子の比較

出典: https://twitter.com/_techcet_/status/1773865010651173293
上の表のとおり、KubernetesリソースをIAMプリンシパルとして指定できるようになったことで、設定はかなり簡素化されました。
追加のGSAを管理し、KSAにimpersonate権限を付与するのを忘れない(よく抜け落ちるステップです)必要はなくなり、必要なIAMロールをKSAに直接付与できます。さらに、KSAにGSA名のアノテーションを付ける作業も不要になりました。これも誤設定や付け忘れが起きやすいポイントでした。
KSAを名前ではなくUIDで参照できるようになった点も大きな改善で、identity samenessによって意図しないワークロードに誤ってアクセス権を与えてしまうリスクを抑えられます。一方で、identity samenessは正しく使えば便利な機能でもあり、現状ではどちらの設定方式でも利用可能です。
加えて、クラスタ内のすべてのPodをIAMプリンシパルセットとして参照できるようになり、柔軟性も向上しました。今後数か月のうちに、より多くの種類のKubernetesリソース(namespaceが加わると非常に便利でしょう)がIAMプリンシパルとしてサポートされることが期待されます。
IAMプリンシパル方式の制約として、一部のサービスはまだ未対応もしくはプレビュー段階です。WIで該当サービスにアクセスしている場合は、設定の移行を見送る必要があります。
既存の設定をIAMプリンシパル方式へ移行する
朗報なのは、必ずしも移行する必要はないということです。GSA impersonation方式は引き続きサポートされており、近いうちに廃止される見込みもありません。
とはいえ、IAMプリンシパル方式は設定がシンプルで、前述のメリットもあるため、可能であれば採用をおすすめします。
では、現行の構成からIAMプリンシパル方式へ、できるだけスムーズにワークロードを切り替えるにはどうすればよいでしょうか。
現在Workload Identityを使ってGCPリソースにアクセスしている場合、必要なIAM権限を持つGSAと、そのGSAに対するWorkload Identity User IAMロールを持つKSAがある状態のはずです。
そして、KSAにはGSAを指すアノテーションが付与されているでしょう。例:
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
iam.gke.io/gcp-service-account: <GSA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com
...
WIの設定を「ゼロダウンタイム」で更新できるか試してみましょう。
まず、当該KSAを使うPodを起動してテストします。
$ echo 'apiVersion: v1
kind: Pod
metadata:
name: workload-identity-test
spec:
serviceAccountName: <KSA_NAME>
containers:
- image: google/cloud-sdk:slim
command: ["sleep","infinity"]
name: workload-identity-test' | kubectl apply -f -
Podが起動したら、execで入ります。
$ kubectl exec -ti token-test -- bash
Pod内からメタデータサーバーへリクエストを送り、Podがどのアイデンティティを使っているか確認します。
root@token-test:/# curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/?recursive=true
{"aliases":["default"],"email":"<GSA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com","scopes":["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email"]}
レスポンスのemailフィールドから、アイデンティティが(KSAのアノテーション経由で)KSAに紐付けられたGSAになっていることが分かります。
では、KSAからこのアノテーションを削除するとどうなるでしょうか。
# これはPodの外で実行します
$ kubectl annotate serviceaccount <KSA_NAME> iam.gke.io/gcp-service-account-
もう一度同じリクエストを試してみます。
root@token-test:/# curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/?recursive=true
{"aliases":["default"],"email":"<PROJECT_ID>.svc.id.goog","scopes":["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email"]}
このとおり、アイデンティティはすぐにプロジェクトのWorkload Identity Poolへ切り替わります。つまり、GSA impersonationからIAMプリンシパルバインディングへの切り替えはPodを再起動しなくても動作するということです(ただし、新しいアイデンティティを使い始めるのに再起動が必要なクライアントが一部存在する可能性はあります)。
KSAにGSAのアノテーションが残っていて、ワークロードが正常に動作している前提で、以下の手順を踏みます。
- 必要なIAMロールをKSAに直接付与するIAMポリシーを作成します(GSAに付与していたものと同じロール)。
- KSAからWIアノテーションを削除します。この時点でPodはKSAプリンシパルに付与された権限をすぐに使い始めるはずです(エラーが出る場合はPodを再起動すれば解消します)。
- すべて問題なく動作することを確認できたら、不要になったGSAを片付け、IaCやマニフェストが最新の状態になっているかをチェックします。
Workload IdentityからWorkload Identity Federation for GKEへの改称は、当初は少し分かりにくく感じられました。これまで両者は明確に区別されていたためです。しかし、IAMプリンシパルへの対応によって、WIF for GKEは他のWIFに歩み寄り、本機能の今後の方向性も見えてきました。
まだWIFを利用していない方にとって、GKEクラスタでの有効化と利用は以前よりずっとシンプルになりました。すでに利用している方も、既存の設定を新方式へ更新する作業はそれほど手間がかからず、不要なリソースの整理やIaCの設定行数の削減につながります。
WIの設定で困っている方は、GitHub上のworkload-identity-analyzerプロジェクト(IAMプリンシパル対応は現在進行中)をぜひご覧ください。