G-gen の佐々木です。当記事では、GKE における Workload Identity Federation の、新しく追加された設定方法を解説します。
GKE における Workload Identity Federation
従来の方法
GKE クラスタ内の Pod 上で動作するアプリケーションから Google Cloud の API にアクセスする場合、認証方法として Workload Identity Federation の使用が推奨されています。
従来の Workload Identity Federation では、GKE クラスタ上に作成した ServiceAccount リソースと、Google Cloud の IAM サービスアカウントを紐づけることで利用できました。
これにより、ServiceAccount を使用する Pod が、それに紐づいた IAM サービスアカウントの権限を借用できるようになります。
従来の方法、また Workload Identity を使用せずに IAM 認証を行う方法の詳細は、以下の記事で解説しています。
新しい方法
新しい方法では、GKE クラスタ内の ServiceAccount リソースを IAM のプリンシパルとして設定することで、ServiceAccount に IAM ロールを直接紐づけることができます。
この方法では紐づけ先となる IAM サービスアカウントを作成しなくてもよいため、IAM サービスアカウントの管理負荷が軽減されるほか、設定の手順が簡略化されます。
新しい方法の制限事項
従来の方法では、GKE クラスタ内の ServiceAccount が IAM サービスアカウントの権限借用を行う、つまり IAM サービスアカウントになりすます(impersonate)ことで、Google Cloud の API にアクセスしていました。
新しい方法ではこの権限借用が行われず、あくまでも GKE クラスタ内の ServiceAccount をプリンシパルとして API へのアクセスが行われます。
この「権限借用が行われない」ことで制限がかかるケースとして、VPC Service Control でサービス境界を設定している場合があります。
サービス境界の上り(内向き)と下り(外向き)のルールでは、アクセスを許可する対象として GKE クラスタ内の ServiceAccount を指定することができません。
GKE 内のアプリケーションは、IAM サービスアカウントの権限借用を介してサービス境界内のリリースにアクセスする必要があります。
したがって、このようなケースでは従来の方法で Workload Identity Federation を設定します。
新しい Workload Identity Federation の設定手順
当記事で使用する GKE クラスタについて
当記事では Autopilot モードの GKE クラスタを使用します。
クラスタのコントロールプレーンとノードのバージョンは以下のようになっています。
MASTER_VERSION: 1.27.8-gke.1067004 NODE_VERSION: 1.27.8-gke.1067004
ServiceAccount リソースの作成
GKE クラスタに ServiceAccout リソースを作成します。
# GKE クラスタに ServiceAccount リソースを作成
$ kubectl create serviceaccount my-serviceaccount
Workload Identity Federation の設定
さきほど作成した ServiceAccout に対して IAM ロールを紐付けます。
IAM ロールの紐づけを行う際に、IAM プリンシパルとして Workload Identity Federation 特有の文字列を指定します。
当記事では、設定に必要な情報がわかりやすいように、以下のシェル変数を設定していきます。
# シェル変数の設定 PROJECT_ID={プロジェクトID} PROJECT_NUMBER={プロジェクト番号} SERVICE_ACCOUNT={GKEクラスタに作成したServiceAccountの名前} NAMESPACE=default
もし default
以外の Namespace を使用する場合は、NAMESPACE
変数の値も変更してください。
また、プロジェクト番号はコンソールのダッシュボード画面や、以下のコマンドを使用することで確認できます。
# プロジェクト番号を確認する $ gcloud projects describe ${PROJECT_ID} | grep projectNumber
以下のコマンドを実行し、GKE クラスタに作成した ServiceAccount に IAM ロールを紐づけます。
当記事では「Kubernetes Engine Cluster 閲覧者(roles/container.clusterViewer)」を設定します。
# ServiceAccout に IAM ロールを紐づけ $ gcloud projects add-iam-policy-binding projects/${PROJECT_ID} \ --role=roles/container.clusterViewer \ --member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${NAMESPACE}/sa/${SERVICE_ACCOUNT}
動作確認
GKE クラスタ内の Pod に ServiceAccount を紐付け、Google Cloud の API にアクセスしてみます。
以下のマニフェストファイルを使用して、gcloud コマンドがインストールされたコンテナを含む Pod をクラスタに作成します。
spec.serviceAccountName
に ServiceAccount の名前を設定します。
# pod.yaml apiVersion: v1 kind: Pod metadata: name: test-pod namespace: default spec: serviceAccountName: my-serviceaccount containers: - name: test-pod image: google/cloud-sdk:slim command: ["sleep","infinity"]
Standard クラスタを使用している場合は、マニフェストファイルに spec.nodeSelector
フィールドを記述し、Pod が Workload Identity Federation を使用できるノードプールに配置されるようにします。
# Standard クラスタの場合の追記内容 spec: nodeSelector: iam.gke.io/gke-metadata-server-enabled: "true"
Pod が実行状態になるのを待ってから、以下のコマンドで Pod 側から gcloud コマンドを実行してみます。
ここでは GKE クラスタの一覧を取得するコマンドを実行していますが、権限エラーが発生することなく GKE クラスタの一覧が取得できました。
# Pod 側で gcloud コマンドを実行 $ kubectl exec -it test-pod -- gcloud container clusters list # 出力例 $ kubectl exec -it test-pod -- gcloud container clusters list NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS cluster-sasashun-gke-public-autopilot asia-northeast1 1.27.8-gke.1067004 xx.xx.xxx.xxx e2-small 1.27.8-gke.1067004 1 RUNNING
参考手順
佐々木 駿太 (記事一覧)
G-gen最北端、北海道在住のクラウドソリューション部エンジニア
2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2025 Fellowに選出。好きなGoogle CloudプロダクトはCloud Run。
趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。
Follow @sasashun0805