Workload Identityを試してみた

kaito2
google-cloud-jp
Published in
8 min readAug 15, 2019

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.workloadIdentityUseriam.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

--

--