はじめに
Google Cloud セキュリティ強化施策として GKE クラスタへの Workload Identity Federation for GKE (以下、Workload Identity)の概要と導入方法について紹介します。
Workload Identity とは
Workload Identity は、GKE(Google Kubernetes Engine)上の Pod に対して Google Cloud の IAM(Identity and Access Management)権限を付与するための推奨される方法です。従来は、Google Cloud のサービスアカウントキーを直接利用してアクセスする方法が一般的でしたが、鍵の管理やセキュリティリスクの観点から、Workload Identity を利用することでより安全な認証方式を実現できます。
Workload Identity を利用して、Pod に権限を付与する方法は以下の 2 つがあります。
- Pod へ直接権限を付与する方法
- Google Cloud のサービスアカウント(GSA)の権限を借用する方法
Podへ直接権限を付与する方法は細かい権限の指定がしやすいですが、一方でコンソール上でPodへ付与された権限の一覧を確認することができず不便です。
GSAと紐づけることで、コンソール上からそのPodに付与された権限が確認できることで保守運用が楽になります。また、Pod と GSA の対応関係はマニフェストファイルへ明記できるので安心です。
ただし、Pod と GSA を紐づける方法に一部対応していないサービスや制限事項があるので、気を付けてください。
導入方法
1. Workload Identity を有効化
まず、対象の GKE クラスタに対して Workload Identity を有効化します。GKE クラスタを作成する際に --workload-pool オプションを指定することで有効化できます。
PROJECT_ID="your-gcp-project-id" # GKE クラスタを構築する Google Cloud のプロジェクト ID
CLUSTER_NAME="your-gke-cluster" # 新しく作成するクラスタ名
LOCATION="asia-northwest1-a" # クラスタで使用するインスタンスのロケーション
# Workload Identity を有効化したクラスタを作成
gcloud container clusters create $CLUSTER_NAME \
--location=$LOCATION \
--workload-pool=$PROJECT_ID.svc.id.goog
既存のクラスタで Workload Identity を有効化する場合は、以下のコマンドを使用します。
gcloud container clusters update $CLUSTER_NAME \
--location=$LOCATION \
--workload-pool=$PROJECT_ID.svc.id.goog
2. GSA の作成
クラスタの構築が完了したら、先に Pod と紐づける GSA を作成しておきましょう。
# GCP サービスアカウントの作成
gcloud iam service-accounts create sample-gsa \
--display-name "My GCP Service Account"
作成した GCP サービスアカウントに必要な IAM 権限を付与します。
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member "serviceAccount:sample-gsa@$PROJECT_ID.iam.gserviceaccount.com" \
--role "roles/storage.objectViewer"
今回はGCSのオブジェクト閲覧者のロールを付与します。
3. Kubernetes ServiceAccount(KSA) の作成と GSA の紐付け
Workload Identity を GKE で利用する際に Pod と GSA を直接紐づけるのはなく、 Pod と紐づけた KSA に GSA を紐づけることになります。そのため、名前空間内で GSA と紐づけた KSA を1つ作成しておくだけで任意の Pod へ権限を付与することが可能です。
下記のマニフェストを使って名前空間、KSA、Pod をデプロイしましょう。PodにはGCS上のファイルの内容を出力するコマンドが設定されています。
apiVersion: v1
kind: Namespace
metadata:
name: sample-namespace
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: sample-ksa
namespace: sample-namespace
annotations:
iam.gke.io/gcp-service-account: "sample-gsa@$PROJECT_ID.iam.gserviceaccount.com"
---
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
namespace: sample-namespace
spec:
serviceAccountName: sample-ksa
containers:
- name: sample-container
image: google/cloud-sdk:stable
command: ["gsutil", "cat", "gs://sample-bucket/example.txt"]
kubectl apply -f sample.yaml
上記のkubernetesリソースを作成した後、下記のコマンドでGSAとKSAの紐づけ(KSAにGSAの権限借用の許可をする)を行いましょう。
gcloud iam service-accounts add-iam-policy-binding \
sample-gsa@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:$PROJECT_ID.svc.id.goog[sample-namespace/sample-ksa]"
4. Kubernetes の Pod で Workload Identity を利用
GKEのコンソール画面からログを確認し、本当にファイルの内容が出力されているか確認してみましょう。Workload Identityの連携に成功していたらファイルの内容が出力されているはずです。
もしファイルの内容が表示されていない場合はもう一度手順を見直してみてください。
まとめ
クラウド上でのセキュリティインシデントの原因の大半は鍵の流出による不正アクセスです。Google Cloud上ではWorkload Identityを導入することで鍵の管理が不要になるため、鍵流出のリスクを回避できます。今回はその一例としてWorkload IdentityをGKEに導入する方法を紹介しました。今後もクラウドやAIに関する最新技術を紹介しますので、ぜひご覧ください。