Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Kubernetes GKE Workload Identity

By Ami MahloofOct 11, 20193 min read

このページはEnglishDeutschEspañolFrançaisItalianoPortuguêsでもご覧いただけます。

1 1f14dqe9np6kalf53ha4kq

Kubernetes サービスを特定の Google サービスアカウントで実行したい場面は多くあります(kube2iam プロジェクトと同様の用途です)。

1 9i9730xcxt2drqhbkrszcw

これは、Kubernetes サービスアカウントを Google サービスアカウントとして振る舞うように構成することで実現できます。つまり、次の指定で動作する Pod は、

ServiceAccountName: <kubernetes_service_account>

すべて Google サービスアカウントを用いて gcloud サービスへの認証が行われます。

注: 本機能はベータ版のため、今後仕様が変更される可能性があります。

概要

Workload Identity は、GKE から gcloud サービスにアクセスする際の推奨方式です。Kubernetes サービスアカウントと Google サービスアカウントの紐付けを一度設定すれば、その Kubernetes サービスアカウントで動作する workload は、Google Cloud API へのアクセス時に自動的に Google サービスアカウントとして認証されます。

クラスタ横断の Identity: IAM はプロジェクト単位でグローバルに管理されるため、Identity Namespace は同一プロジェクト内のすべてのクラスタで共有されます。この点を踏まえ、クラスタはプロジェクト単位で分離することが推奨されます。

例:

次のコマンドは、デフォルトのサービスアカウントと Namespace を使用し、かつ Workload Identity が有効化されているプロジェクト内のすべてのクラスタに同じアクセス権を付与します。

gcloud iam service-accounts add-iam-policy-binding \
— role roles/iam.workloadIdentityUser \
— member "serviceAccount:[PROJECT_ID].svc.id.goog[default/default]"
[GOOGLE_SERVICE_ACCOUNT_NAME]@[PROJECT_ID].iam.gserviceaccount.com

制限事項

  • Workload Identity は GKE バージョン 1.12 以上のクラスタで利用できます。
  • Workload Identity を有効化すると、Compute Engine のデフォルトサービスアカウントは使用できなくなります。
  • ホストネットワーク上で動作する Pod では Workload Identity を利用できません。
  • Istio の Namespace インジェクションは Workload Identity と併用できません。Metadata Server が GKE ではなく GCE のものに切り替わってしまい、結果として GCE Compute サービスアカウントが使用されてしまうためです。

新規クラスタで Workload Identity を有効化する

  1. IAM Credentials API が有効になっていることを確認します
  2. プロジェクト ID とクラスタ名を設定します
export PROJECT_ID=<project_ID>
export CLUSTER_NAME=<cluster_name>
export CLUSTER_VERSION=<cluster_version>

3. Workload Identity を有効化した新規クラスタを作成するか、

gcloud beta container clusters create ${CLUSTER_NAME} \
--cluster-version=${CLUSTER_VERSION} \

--identity-namespace=${PROJECT_ID}.svc.id.goog

既存のクラスタを更新します。

gcloud beta container clusters update ${CLUSTER_NAME} \
--identity-namespace=${PROJECT_ID}.svc.id.goog

Metadata Server を有効化する

Metadata Server は各 GKE ノード上で動作し、メタデータエンドポイントの挙動を変更します。あわせてメタデータエンドポイントのセキュリティも強化されるため、メタデータの隠蔽(metadata concealment)は不要になります。デフォルトのノードプールで Metadata Server を有効化しましょう。

gcloud beta container node-pools update default-pool \
— cluster=workload-identity-test \
— workload-metadata-from-node=GKE_METADATA_SERVER \
— zone=us-central1-b

4. クラスタ用に kubectl を構成します。

gcloud container clusters get-credentials ${CLUSTER_NAME}

5. 他の多くのリソースと同様に、Kubernetes サービスアカウントは Namespace 内に存在します。Kubernetes サービスアカウント用の Namespace を作成します。

kubectl create namespace <namespace>

6. Kubernetes サービスアカウント名、Namespace、Google サービスアカウント名を設定します。

export K8S_NAMESPACE=<kubernetes_service_account_namespace>
export KSA_NAME=<kubernetes_service_account>
export GSA_NAME=<google_service_account>

7. Kubernetes サービスアカウントを作成します。

kubectl create serviceaccount \
--namespace ${K8S_NAMESPACE} ${KSA_NAME}

8. Google サービスアカウントを作成します。

gcloud iam service-accounts create ${GSA_NAME}

9. Kubernetes サービスアカウントと Google サービスアカウントを紐付けるバインディングを作成します。

gcloud iam service-accounts add-iam-policy-binding \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:${PROJECT_ID}.svc.id.goog[${K8S_NAMESPACE}/${KSA_NAME}]" \
${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com

10. Google サービスアカウントのメールアドレスを使い、Kubernetes サービスアカウントに iam.gke.io/gcp-service-account=[GSA_NAME]@[PROJECT_ID] アノテーションを付与します。

kubectl annotate serviceaccount \
--namespace ${K8S_NAMESPACE} \
${KSA_NAME} \
iam.gke.io/gcp-service-account=${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com

11. テスト用 Pod を起動します。

kubectl run -it \
--generator=run-pod/v1 \
--image google/cloud-sdk \
--serviceaccount ${KSA_NAME} \
--namespace ${K8S_NAMESPACE} \
workload-identity-test

12. サービスアカウントが意図したものになっているかを確認します。

gcloud auth list

アクセスを取り消す

アクセスの取り消しは即時には反映されず、キャッシュされたトークンが失効するまで最大 30 分かかる場合がある点に注意してください。

アクセスを取り消すには、バインディングを削除するだけです。

gcloud iam service-accounts remove-iam-policy-binding \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:${PROJECT_ID}.svc.id.goog[${K8S_NAMESPACE}/${KSA_NAME}]" \
${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com

YAML ファイルや Helm チャートで Pod にサービスアカウントを適用する

Google サービスアカウントとして実行するには、バインディングで指定した Kubernetes サービスアカウントを serviceAccountName スタンザに記述してください。