このチュートリアルでは、Google Kubernetes Engine(GKE)クラスタで使用される機密データを Secret Manager に保存する方法について説明します。Workload Identity Federation for GKE とGoogle Cloud クライアント ライブラリを使用して、Pod からデータに安全にアクセスする方法についても説明します。
クラスタ ストレージの外部にセンシティブ データを保存すると、攻撃が発生した場合に不正アクセスされるリスクが軽減されます。GKE 用 Workload Identity 連携を使用してデータにアクセスすると、有効期間の長いサービス アカウント キーの管理に伴うリスクを回避し、クラスタ内の RBAC ルールではなく、Identity and Access Management(IAM)を使用して Secret へのアクセスを制御できます。Secret Manager や HashiCorp Vault などの外部 Secret ストア プロバイダを使用できます。
このページは、クラスタ内のストレージから機密データを移動するセキュリティ スペシャリストを対象としています。 Google Cloud のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。
このチュートリアルでは、GKE Autopilot クラスタを使用します。この操作を GKE Standard で行う場合は、Workload Identity Federation for GKE を手動で有効にする必要があります。
Workload Identity Federation for GKE を使用すると、静的なサービス アカウント キー ファイルのような安全性の低い手段を使用することなく、GKE ワークロードから任意の Google Cloud API にアクセスできます。このチュートリアルでは Secret Manager を例として使用しますが、同じ手順で他の Google CloudAPIs にアクセスすることもできます。詳細については、Workload Identity Federation for GKE をご覧ください。
目標
- Google Cloud Secret Manager で Secret を作成します。
- GKE Autopilot クラスタ、Kubernetes Namespace、Kubernetes サービス アカウントを作成します。
- IAM 許可ポリシーを作成して、Secret の Kubernetes サービス アカウントへのアクセスを許可します。
- テスト アプリケーションを使用してサービス アカウントへのアクセスを確認します。
- Secret Manager API を使用して Secret にアクセスするサンプルアプリを実行します。
費用
このドキュメントでは、課金対象である次の Google Cloudコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソース������除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Kubernetes Engine and Secret Manager APIs:
gcloud services enable container.googleapis.com
secretmanager.googleapis.com - Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Kubernetes Engine and Secret Manager APIs:
gcloud services enable container.googleapis.com
secretmanager.googleapis.com -
Grant roles to your user account. Run the following command once for each of the following IAM roles:
roles/secretmanager.admin, roles/container.clusterAdmin
gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
- Replace
PROJECT_ID
with your project ID. -
Replace
USER_IDENTIFIER
with the identifier for your user account. For example,user:myemail@example.com
. - Replace
ROLE
with each individual role.
- Replace
環境を準備する
このチュートリアルのサンプル ファイルを含む GitHub リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd ~/kubernetes-engine-samples/security/wi-secrets
Secret Manager で Secret を作成する
次の例は、Secret の作成に使用するデータを示しています。
サンプルデータを格納する Secret を作成します。
gcloud secrets create bq-readonly-key \ --data-file=manifests/bq-readonly-key \ --ttl=3600s
このコマンドは次の処理を行います。
us-central1
Google Cloud リージョンでサンプルキーを使用して新しい Secret Manager Secret を作成します。- コマンドを実行してから 1 時間後に Secret を期限切れに設定します。
クラスタと Kubernetes リソースを作成する
GKE クラスタ、Kubernetes Namespace、Kubernetes サービス アカウントを作成します。2 つの Namespace を作成します(1 つは読み取り専用アクセス用、もう 1 つは Secret への読み取り / 書き込みアクセス用)。また、GKE 用 Workload Identity 連携で使用する Kubernetes サービス アカウントを各 Namespace に作成します。
GKE Autopilot クラスタを作成します。
gcloud container clusters create-auto secret-cluster \ --region=us-central1
クラスタのデプロイには 5 分ほどかかります。Autopilot クラスタでは常に GKE 用 Workload Identity 連携が有効になっています。GKE Standard クラスタを使用する場合は、続行する前に GKE 用 Workload Identity 連携を手動で有効にする必要があります。
readonly-ns
Namespace とadmin-ns
Namespace を作成します。kubectl create namespace readonly-ns kubectl create namespace admin-ns
readonly-sa
Kubernetes サービス アカウントとadmin-sa
Kubernetes サービス アカウントを作成します。kubectl create serviceaccount readonly-sa --namespace=readonly-ns kubectl create serviceaccount admin-sa --namespace=admin-ns
IAM 許可ポリシーを作成する
readonly-sa
サービス アカウントに、シークレットへの読み取り専用アクセス権を付与します。gcloud secrets add-iam-policy-binding bq-readonly-key \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/readonly-ns/sa/readonly-sa \ --role='roles/secretmanager.secretAccessor' \ --condition=None
次のように置き換えます。
PROJECT_NUMBER
: 数値の Google Cloudプロジェクト番号。PROJECT_ID
: 実際の Google Cloud プロジェクト ID。
admin-sa
サービス アカウントに、Secret への読み取り / 書き込みアクセス権を付与します。gcloud secrets add-iam-policy-binding bq-readonly-key \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/admin-ns/sa/admin-sa \ --role='roles/secretmanager.secretAccessor' \ --condition=None gcloud secrets add-iam-policy-binding bq-readonly-key \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/admin-ns/sa/admin-sa \ --role='roles/secretmanager.secretVersionAdder' \ --condition=None
Secret へのアクセスを確認する
各 Namespace にテスト Pod をデプロイして、読み取り専用アクセスと読み取り / 書き込みアクセスを確認します。
読み取り専用 Pod マニフェストを確認します。
この Pod は、
readonly-ns
Namespace 内のreadonly-sa
サービス アカウントを使用します。読み取り / 書き込み Pod マニフェストを確認します。
この Pod は、
admin-ns
Namespace 内のadmin-sa
サービス アカウントを使用します。テスト Pod をデプロイします。
kubectl apply -f manifests/admin-pod.yaml kubectl apply -f manifests/readonly-pod.yaml
Pod の実行が開始されるまでに数分かかることがあります。進捗状況をモニタリングするには、次のコマンドを実行し��す。
watch kubectl get pods -n readonly-ns
Pod のステータスが
RUNNING
に変わったら、Ctrl+C
を押してコマンドラインに戻ります。
読み取り専用アクセスをテストする
readonly-test
Pod でシェルを開きます。kubectl exec -it readonly-test --namespace=readonly-ns -- /bin/bash
Secret を読み取ります。
gcloud secrets versions access 1 --secret=bq-readonly-key
出力は
key=my-api-key
です。新しいデータを Secret に書き込みます。
printf "my-second-api-key" | gcloud secrets versions add bq-readonly-key --data-file=-
出力は次のようになります。
ERROR: (gcloud.secrets.versions.add) PERMISSION_DENIED: Permission 'secretmanager.versions.add' denied for resource 'projects/PROJECT_ID/secrets/bq-readonly-key' (or it may not exist).
読み取り専用サービス アカウントを使用する Pod は、Secret の読み取りのみ可能であり、新しいデータを書き込むことはできません。
Pod を終了します。
exit
読み取り / 書き込みアクセスをテストする
admin-test
Pod でシェルを開きます。kubectl exec -it admin-test --namespace=admin-ns -- /bin/bash
Secret を読み取ります。
gcloud secrets versions access 1 --secret=bq-readonly-key
出力は
key=my-api-key
です。新しいデータを Secret に書き込みます。
printf "my-second-api-key" | gcloud secrets versions add bq-readonly-key --data-file=-
出力は次のようになります。
Created version [2] of the secret [bq-readonly-key].
新しい Secret バージョンを確認します。
gcloud secrets versions access 2 --secret=bq-readonly-key
出力は
my-second-api-key
です。Pod を終了します。
exit
Pod には、Pod マニフェストで使用される Kubernetes サービス アカウントに付与されるアクセスレベルのみを取得します。admin-ns
Namespace の admin-sa
Kubernetes アカウントを使用する Pod は Secret の新しいバージョンを書き込むことができますが、readonly-sa
Kubernetes サービス アカウントを使用する readonly-ns
Namespace の Pod は Secret を読み取ることのみができます。
コードから Secret にアクセスする
このセクションでは、次の操作を行います。
クライアント ライブラリを使用して、Secret Manager で Secret を読み取るサンプル アプリケーションをデプロイします。
アプリケーションが Secret にアクセスできることを確認します。
可能な限り、Secret Manager API を使用して、アプリケーション コードから Secret Manager の Secret にアクセス��る必要があります。
サ������ ����リケーションのソースコードを確認します。
このアプリケーションは、Secret Manager API を呼び出して Secret を取得します。
サンプル アプリケーションの Pod マニフェストを確認します。
このマニフェストの内容は次のとおりです。
readonly-sa
サービス アカウントを使用するreadonly-ns
Namespace に Pod を作成します。- Google イメージ レジストリからサンプル アプリケーションを pull します。このアプリケーションは、Google Cloud クライアント ライブラリを使用して Secret Manager API を呼び出します。アプリケーション コードは、リポジトリ内の
/main.go
で確認できます。 - 使用するサンプル アプリケーションの環境変数を設定します。
サンプル アプリケーションの環境変数を置き換えます。
sed -i "s/YOUR_PROJECT_ID/PROJECT_ID/g" "manifests/secret-app.yaml"
サンプルアプリをデプロイします。
kubectl apply -f manifests/secret-app.yaml
Pod が機能し始めるまでに数分かかることがあります。Pod がクラスタに新しいノードを必要とする場合、GKE がノードのプロビジョニングしている間に
CrashLoopBackOff
タイプのイベントが発生することがあります。ノードが正常にプロビジョニングされると、クラッシュは停止します。Secret へのアクセスを確認します。
kubectl logs readonly-secret-test -n readonly-ns
出力は
my-second-api-key
です。出力が空白の場合、Pod がまだ実行されていない可能性があります。数分待ってから、もう一度お試しください。
その他の方法
機密データを Pod にマウントする必要がある場合は、GKE 用の Secret Manager アドオンを使用します。このアドオンは、GKE クラスタで Kubernetes Secret Store CSI ドライバの Google Cloud Secret Manager プロバイダをデプロイして管理します。手��については、GKE で Secret Manager アドオンを使用するをご覧ください。
マウントされたボリュームとして Secret を提供すると、次のようなリスクがあります。
- マウントされたボリュームは、ディレクトリ トラバーサル攻撃を受けやすくなります。
- デバッグ エンドポイントを開くなどの構成ミスによって、環境変数が不正使用される可能性があります。
可能な限り、Secret Manager API を使用してプログラムで Secret にアクセスすることをおすすめします。手順については、このチュートリアルのサンプル アプリケーションを使用するか、Secret Manager クライアント ライブラリをご覧ください。
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
リソースを個別に削除する
クラスタを削除します。
gcloud container clusters delete secret-cluster \ --region=us-central1
Secret Manager で Secret を削除します。
gcloud secrets delete bq-readonly-key
この手順を行わないと、作成時に
--ttl
フラグを設定したため、Secret は自動的に期限切れになります。
プロジェクトを削除する
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
次のステップ
- GKE 用 Workload Identity 連携の仕組みについて学習する。
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センターをご覧���ださい。