Workload Identityを試してみた
Workload Identity 概要
GKE上で実行されるワークロードが Google Cloud API を使用するためには認証を行う必要があります。従来はSecretsなどにクレデンシャルファイルを格納してGKEのワークロードがそれを読み込み、認証を行う必要がありました。Workload Identityを用いることでKubernetesサービスアカウントとGCPサービスアカウントを紐付けることができます。
以下の値を用いているので適宜読み替えてください。
GCP プロジェクトID: my-project
GCP サービスアカウント名: gsa-sample
Kubernetes サービスアカウント名: ksa-sample
Kubernetes ネームスペース: wi-sample-ns
クラスタ作成
Workload Identity (WI) を有効化したクラスタを作成
$ gcloud beta container clusters create wi-sample-cluster \
--cluster-version=1.12 \
--identity-namespace=my-project.svc.id.goog...kubeconfig entry generated for wi-sample-cluster.
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
wi-sample-cluster asia-northeast1-b 1.12.9-gke.7 35.194.109.1 n1-standard-1 1.12.9-gke.7 3 RUNNING
作成したクラスタのクレデンシャルを取得しコンテキストを設定
$ gcloud container clusters get-credentials wi-sample-cluster
Fetching cluster endpoint and auth data.
kubeconfig entry generated for wi-sample-cluster.$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
...
gke_my-project_asia-northeast1-b_wi-sample-cluster gke_my-project_asia-northeast1-b_wi-sample-cluster gke_my-project_asia-northeast1-b_wi-sample-cluster
...$ kubectl config use-context gke_my-project_asia-northeast1-b_wi-sample-cluster
Switched to context "gke_my-project_asia-northeast1-b_wi-sample-cluster".
Workload Identity 設定
GCPのサービスアカウントを作成
公式ドキュメントではGSA(Google Service Account)と表記されている
$ gcloud iam service-accounts create gsa-sample
Created service account [gsa-sample].
Kubernetesのネームスペースを作成
$ kubectl create namespace wi-sample-ns
namespace/wi-sample-ns created
Kubernetesのサービスアカウントを作成
公式ドキュメントではKSA(Kubernetes Service Account)と表記されている
$ kubectl create serviceaccount \
--namespace wi-sample-ns \
ksa-sample
serviceaccount/ksa-sample created
サービスアカウントのバインディング
WIのGCPサービスアカウントに roles/iam.workloadIdentityUser
のロールをバインディングします。roles/iam.workloadIdentityUser
は iam.serviceAccounts.get
, iam.serviceAccount.getAccessToken
, iam.serviceAccounts.list
で構成されており、WIが他のGSAとして振る舞うための権限みたいです。
https://cloud.google.com/iam/docs/understanding-roles#service-accounts-roles
$ gcloud iam service-accounts add-iam-policy-binding \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:my-project.svc.id.goog[wi-sample-ns/ksa-sample]" \
gsa-sample@my-project.iam.gserviceaccount.com
Updated IAM policy for serviceAccount [gsa-sample@my-project.iam.gserviceaccount.com].
bindings:
- members:
- serviceAccount:my-project.svc.id.goog[wi-sample-ns/ksa-sample]
role: roles/iam.workloadIdentityUser
etag: BwWP_oJJHts=
version: 1
アノテーション
作成したKSAに使用するGSAをアノテーションで指定します。
$ kubectl annotate serviceaccount \
--namespace wi-sample-ns \
ksa-sample \
iam.gke.io/gcp-service-account=gsa-sample@my-project.iam.gserviceaccount.com
serviceaccount/ksa-sample annotated
確認
gcloud-sdkが入っているコンテナイメージをデプロイしてみて権限を確認します。
$ kubectl run -it \
--generator=run-pod/v1 \
--image google/cloud-sdk \
--serviceaccount ksa-sample \
--namespace wi-sample-ns \
workload-identity-test
以下のように `Credentialed Accounts`が設定されていれば正常に動作しています。
# gcloud auth list
Credentialed Accounts
ACTIVE ACCOUNT
* gsa-sample@my-project.iam.gserviceaccount.com
【おまけ】YAMLでの記述
serviceAccountName
を指定するとコンテナ内でデフォルトクレデンシャルとして使用できます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
serviceAccountName: ksa-sample #this is our workload identity
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Clean up
クラスタ削除
$ gcloud beta container clusters delete wi-sample-cluster
GSA削除
$ gcloud beta iam service-accounts delete gsa-sample@my-project.iam.gserviceaccount.com
※ gcloud beta
じゃないと Permission denied
される。
参考
https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity