Kubernetes環境において、シークレットを安全に守ることは最重要課題です。従来、GKEでのシークレット管理は、環境変数やボリュームとしてPodに注入する方式が一般的でした。動作上は問題ないものの、この手法は煩雑で、セキュリティ面の懸念も残ります。そこでGoogle Cloudが提供するのが、GKE向けSecret Manager add-onという強力なソリューションです。
本記事では、GKE向けSecret Manager add-onを使い、Secret Managerに保管したシークレットをGKE Podにマウントしたボリュームとして利用する方法を解説します。
:: 2024年5月時点で、本機能は プレビュー 段階のため、利用には十分ご注意ください。
Secret Managerとは
Secret Managerは、APIキー・パスワード・証明書といった機密情報の保管と取得を目的に設計された、Google Cloud Platform(GCP)のマネージドサービスです。主なメリットは次のとおりです。
- 一元管理: シークレットを一箇所に集約することで、アクセス制御や監査がシンプルになります。
- セキュリティの強化: 保管時・転送時ともにシークレットを暗号化し、漏洩リスクを最小限に抑えます。
- Workload Identityの簡素化: 追加の認証情報を持たせずに、ワークロードからWorkload Identityを通じて安全にシークレットへアクセスできます。
Secret Manager add-onの概要
Google Kubernetes Engine(GKE)向けSecret Manager add-onは、Pod内でのシークレットの取得・管理を簡素化します。主な利点は次のとおりです。
- 手軽なアクセス: 独自コードを書くことなく、GKE PodからSecret Manager上のシークレットへ直接アクセスできます。
- 一元管理: すべてのシークレットをSecret Managerで保管・管理し、特定のシークレットへのアクセス権をGKE Podへ個別に付与できます。
- セキュリティの向上: 暗号化、アクセス制御、ローテーション、監査ログといったSecret Managerの機能と、Kubernetesのボリュームマウント機構を組み合わせて活用できます。
- 幅広い互換性: StandardとAutopilotの両方のGKEクラスタで動作し、AMD・ARMアーキテクチャへのデプロイにも対応します。
このAdd-onは、オープンソースのKubernetes Secrets Store CSI DriverとGoogle Secret Manager providerをベースとしています。すでにオープンソース版のSecrets Store CSI Driverを利用している場合は、Secret Manager add-onへ移行できます。詳しくはMigrate from the existing Secrets Store CSI Driverをご覧ください。
現時点ではプレビュー段階のため、本add-onでは以下の機能は未対応です。
External Secrets Operatorを使うべきでは?
結論から言えば、コンプライアンス上Kubernetesネイティブのシークレットをクラスタ内に持ちたくない場合は、Secrets Store CSI driverとGKE Secrets Add-Onの組み合わせを選び、Secrets Manager上のシークレットをそのままPodのボリュームとしてマウントするのが適しています。そうした制約がなければ、ESOを試してみるのもよいでしょう。
External Secrets OperatorとSecrets Store CSI driverの興味深い比較を、Lucasというユーザーがこちらのコメントで投稿しているので、本記事でも引用します。
ESOはクラウドプロバイダー側のシークレットをk8sのシークレットへ同期するため、これまでk8sシークレットを使ってきた方はそのまま継続して利用できます。
SSCSIDは外部シークレットをPodのボリュームとして直接マウントするため、k8sシークレットをクラスタ内に持つかどうかは任意です。
ESOはCRD上での設定を重視しており、プロバイダー側のシークレットストアに作成するのはシークレットの値そのものだけです。
SSCSIDではアプリケーションが利用する設定・シークレットの全体をプロバイダー側に保管しておく必要があります。一部にシークレットが埋め込まれた大規模な構成では、扱いづらくなることがあります。
ESOのシークレットは当然ながらk8s上のあらゆるリソースとネイティブに連携できますが、👇
SSCSIDをきちんと機能させるにはPod webhookが必要です。SSCSIDのシークレットをingressやイメージプル用のdockerconfigから参照することは容易ではありません。あくまでPodへのマウントを目的とした仕組みだからです。k8sシークレットへの同期を有効にする場合でも、まずシークレットをPodへマウントしてからでなければ同期できません。
ESOではk8sネイティブのシークレットへ同期するため、接続障害が起きてもクラスタ内のシークレットには引き続きアクセスでき、再接続後は自動的に再同期が継続されます。
SSCSIDの場合、接続が切れた状態で再起動などが発生すると、CSIドライバーのマウントが機能しなくなります。開発側でも対応を検討中ですが、進捗状況は不明です:doc。詳細は開発元に直接確認してください。
ESOはクラスタ内に1つのオペレーターをデプロイするだけで済みます。
SSCSIDの場合、Podへのマウントを担う特権付きプロバイダーDaemonSetが必要になります。
他の選択肢はあるのか?
Kubernetes Secrets Store CSI Driverを使わずに、シークレット管理サービスからボリュームへ直接シークレットを取得する代替手段をお探しなら、ぜひこちらを確認してみてください。
また、2001年にGoogleのDev AdvocateであるAbdellfetah SGHIOUAR氏が、GKEでのシークレット保管に関するその他の選択肢を紹介する興味深い記事を執筆しています。こちらからご覧いただけます。
**はじめに:** GKE向けSecret Manager Add-on
まずはクラスタでSecret Manager Add-onを有効化します。新規クラスタ作成時にこのフラグを指定することも可能です。CLUSTER_NAMEとREGION/ZONEは必ずご自身の環境に合わせて置き換えてください。
gcloud beta container clusters update <CLUSTER_NAME> \
--enable-secret-manager \
--location=<ZONE/REGION>
クラスタでWorkload Identity Federationが有効になっていることもあわせてご確認ください。
Secret Manager Add-Onを有効化すると、APIバージョンsecrets-store.csi.x-k8s.io/v1として2つの新しいAPIが利用可能になります。
$ kubectl api-resources | grep secrets-store
secretproviderclasses secrets-store.csi.x-k8s.io/v1 true SecretProviderClass
secretproviderclasspodstatuses secrets-store.csi.x-k8s.io/v1 true SecretProviderClassPodStatus
Secret Managerと通信するには、利用するKubernetesサービスアカウントに必要な権限を付与する必要があります。
まずは、クラスタで使用するk8s namespaceとサービスアカウントを作成しましょう。
kubectl create ns secret-manager-access
kubectl create sa secret-manager-access-sa
続いて、Workload Identity Federationを使ってK8sサービスアカウントに適切な権限を付与します。Project IDとProject Numberの変数は必ず置き換えてください。
PROJECT_NUMBER=<ADD_YOUR_PROJECT_NUMBER>
PROJECT_ID=<ADD_YOUR_PROJECT_ID>
NAMESPACE=secret-manager-access
gcloud projects add-iam-policy-binding projects/star-sorceress \
--role=roles/secretmanager.secretAccessor \
--member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${NAMESPACE}/sa/secret-manager-access-sa \
--condition=None
補足:Workload Identity Federationのセットアップ方法は最近変更されました。詳細を知りたい方は、DoiTのメンバーが詳しく解説しているこちらのブログ記事をご覧ください。
続いて、Google Secret Manager上にスーパーシークレットを作成し、最初のバージョンを登録します。
echo "This is my awesome secret, please don't share!" > super-secret.txt
gcloud secrets create super-secret --replication-policy="automatic" --data-file="super-secret.txt"
次に、SecretProviderClassカスタムリソースを作成します。これは先ほど作成したGCPシークレットに紐づきます。Project IDの記載をお忘れなく。
kubectl apply -f - <<EOF
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: super-secret
spec:
provider: gke
parameters:
secrets: |
- resourceName: "projects/<PROJECT_ID>/secrets/super-secret/versions/1"
path: "super-secret.txt"
EOF
Podボリュームの設定
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: secret-manager-access
spec:
serviceAccountName: secret-manager-access-sa
containers:
- name: test-pod
image: google/cloud-sdk:slim
command: ["sleep","infinity"]
volumeMounts:
- mountPath: "/var/secrets"
name: super-secret
volumes:
- name: super-secret
csi:
driver: secrets-store-gke.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: super-secret
EOF
シークレットが正しく配置されているか確認してみましょう。
kubectl exec -it test-pod -- cat /var/secrets/super-secret.txt
This is my awesome secret, please don't share
Secret Manager CSI Driverのメリット:
- セキュリティの強化: シークレットがPod内に保存されないため、攻撃対象領域を縮小できます。
- workloads管理の簡素化: Workload IdentityによりPod内で認証情報を管理する必要がなくなります。
- 柔軟な設定: シークレットへのアクセスを細かく制御でき、きめ細やかな権限付与が可能です。
- 監査ログの一元化: すべてのシークレットアクセス履歴がSecret Managerに記録され、監査がしやすくなります。
まとめ
GKE向けSecret Manager Add-Onを採用すれば、フルマネージドのSecret Manager CSI Driverの恩恵を受けられ、GKEのセキュリティ態勢を大幅に強化しつつ、アプリケーション内のシークレット管理をシンプルにできます。一元管理、自動マウント、堅牢なアクセス制御を備えたCSI Driverが、開発者を本来のアプリケーション構築・デプロイに集中させてくれます。
参考資料:
https://github.com/kubernetes-sigs/secrets-store-csi-driver
https://github.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp
https://cloud.google.com/secret-manager/docs/secret-manager-managed-csi-component#migrate
https://github.com/external-secrets/external-secrets/issues/478#issuecomment-964413129
https://medium.com/google-cloud/consuming-google-secret-manager-secrets-in-gke-911523207a79
https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity
https://github.com/doitintl/kube-secrets-init
本記事が皆さまのお役に立てば幸いです。ご質問があれば、ぜひ下のコメント欄までお寄せください。
DoiT Internationalをまだご存じでない方は、ぜひ一度チェックしてみてください。私たちは、お客様のクラウドエンジニアリング課題にじっくり向き合う体制を整えています。シニアクラスのEngineersのみで構成された当社は、高度なクラウドコンサルティング、アーキテクチャ設計、デバッグ支援を専門としています。お気軽にお問い合わせください!