このドキュメントでは、Secret Manager に保存されているシークレットを Google Kubernetes Engine(GKE)クラスタ内の Kubernetes Secret に同期する方法について説明します。
同期プロセスにより、GKE で実行されているアプリケーションは、環境変数やボリューム マウントなどの標準の Kubernetes メソッドを使用して、Secret Manager のシークレットにアクセスできます。これは、Secret Manager に直接アクセスするように更新する必要がなく、Kubernetes Secret オブジェクトからシークレットを読み取るようにすでに設計されているアプリケーションに役立ちます。
推奨事項: シークレット同期機能は、シークレットをインメモリ ファイルとして Pod に直接マウントする Secret Manager アドオンの代替機能です。アプリケーションがサポートしている場合は、Secret Manager アドオンを使用します。これは、GKE の Secret Manager から Secret にアクセスするためのより安全な方法です。
始める前に
シークレットを同期する前に、次の前提条件を満たしてください。
-
Enable the Secret Manager and Google Kubernetes Engine APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin
), which contains theserviceusage.services.enable
permission. Learn how to grant roles. gcloud CLI をインストールして初期化します。すでに gcloud CLI をインストールしている場合は、
gcloud components update
コマンドを実行して最新バージョンを取得します。GKE クラスタが実行されていることを確認します。この機能には、GKE バージョン 1.34 以降が必要です。
GKE クラスタで Workload Identity Federation for GKE が有効になっていることを確認します。これは認証に必要です。Workload Identity Federation for GKE は、Autopilot クラスタではデフォルトで有効になっています。
GKE クラスタと Secret Manager を管理するために必要な Identity and Access Management 権限があることを確認します。
GKE クラスタでシークレットの同期を有効にする
新しいクラスタを作成するか、既存のクラスタを更新するときに、シークレット同期機能を有効にします。この機能は、Standard クラスタと Autopilot クラスタの両方で使用できます。
新しいクラスタで Secret の同期を有効にする
シークレット同期を使用して新しいクラスタを作成するには、次のいずれかの gcloud CLI コマンドを使用します。
Standard クラスタ
Secret Manager をコマンドラインで使用するには、まず Google Cloud CLI のバージョン 378.0.0 以降をインストールまたはアップグレードします。 Compute Engine または GKE では、cloud-platform スコープを使用して認証する必要があります。
自動ローテーションなしでシークレットの同期を有効にします。
gcloud beta container clusters create CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-secret-sync
自動ローテーションでシークレットの同期を有効にします。デフォルトの間隔は 2 分です。
gcloud beta container clusters create CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-secret-sync \ --enable-secret-sync-rotation
カスタム ローテーション間隔でシークレットの同期を有効にします。最小間隔は 1 分です。
gcloud beta container clusters create CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-secret-sync \ --enable-secret-sync-rotation \ --secret-sync-rotation-interval=1m
次のように置き換えます。
CLUSTER_NAME
: GKE クラスタの名前CONTROL_PLANE_LOCATION
: クラスタ コントロール プレーンのリージョンまたはゾーン(us-central1
、us-east1-a
など)PROJECT_ID
: 実際の Google Cloud プロジェクト ID
Autopilot クラスタ
Secret Manager をコマンドラインで使用するには、まず Google Cloud CLI のバージョン 378.0.0 以降をインストールまたはアップグレードします。 Compute Engine または GKE では、cloud-platform スコープを使用して認証する必要があります。
自動ローテーションなしでシークレットの同期を有効にします。
gcloud beta container clusters create-auto CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --enable-secret-sync
自動ローテーションでシークレットの同期を有効にします。デフォルトの間隔は 2 分です。
gcloud beta container clusters create-auto CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --enable-secret-sync \ --enable-secret-sync-rotation
カスタム ローテーション間隔でシークレットの同期を有効にします。最小間隔は 1 分です。
gcloud beta container clusters create-auto CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --enable-secret-sync \ --enable-secret-sync-rotation \ --secret-sync-rotation-interval=1m
次のように置き換えます。
CLUSTER_NAME
: GKE クラスタの名前CONTROL_PLANE_LOCATION
: クラスタ コントロール プレーンのリージョンまたはゾーン(us-central1
、us-east1-a
など)
既存のクラスタでシークレットの同期を有効にする
シークレット同期を使用して既存のクラスタを更新するには、次のいずれかの gcloud CLI コマンドを使用します。
gcloud
Secret Manager をコマンドラインで使用するには、まず Google Cloud CLI のバージョン 378.0.0 以降をインストールまたはアップグレードします。Compute Engine または GKE では、cloud-platform スコープを使用して認証する必要があります。
既存のクラスタでシークレットの同期を有効にする
gcloud beta container clusters update CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --enable-secret-sync
カスタムの間隔でローテーションを有効にする
gcloud beta container clusters update CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --enable-secret-sync-rotation \ --secret-sync-rotation-interval=5m
ローテーションを無効にする
gcloud beta container clusters update CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --no-enable-secret-sync-rotation
次のように置き換えます。
CLUSTER_NAME
: GKE クラスタの名前CONTROL_PLANE_LOCATION
: クラスタ コントロール プレーンのリージョンまたはゾーン(us-central1
、us-east1-a
など)
シークレットの同期を構成する
シークレットを同期するには、次の操作を行います。
次のコマンドを使用して Kubernetes ServiceAccount を作成します。
kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
次のように置き換えます。
KSA_NAME
: Kubernetes ServiceAccount の名前NAMESPACE
: ServiceAccount を作成する Kubernetes Namespace
新しい Kubernetes ServiceAccount を参照する IAM 許可ポリシーを作成し、ServiceAccount に Secret へのアクセス権を付与します。
gcloud
Secret Manager をコマンドラインで使用するには、まず Google Cloud CLI のバージョン 378.0.0 以降をインストールまたはアップグレードします。Compute Engine または GKE では、cloud-platform スコープを使用して認証する必要があります。
gcloud secrets add-iam-policy-binding SECRET_PROJECT_ID \ --role=roles/secretmanager.secretAccessor \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_IDsvc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME
次のように置き換えます。
SECRET_PROJECT_ID
: シークレットが保存されているプロジェクトの ID。シークレットが GKE クラスタと同じプロジェクトに保存されている場合は、PROJECT_ID と同じにできます。PROJECT_NUMBER
: Google Cloud プロジェクト番号。PROJECT_ID
: 実際の Google Cloud プロジェクト IDNAMESPACE
: Kubernetes NamespaceKSA_NAME
: Kubernetes ServiceAccount の名前
YAML マニフェストを使用して SecretProviderClass カスタム リソースを作成します。SecretProviderClass リソースは、リソース名やパスなど、Secret Manager から取得する特定のシークレットを定義します。Secret Manager アドオンは、SecretProviderClass リソースを使用して、マウントするシークレットとマウントする際のファイル名を一覧表示します。
次の内容の
spc.yaml
ファイルを作成します。apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: SECRET_PROVIDER_CLASS_NAME namespace: NAMESPACE spec: provider: gke parameters: secrets: | - resourceName: "projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION" path: "FILENAME.txt" - resourceName: "projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION" path: "FILENAME1.txt"
次のように置き換えます。
SECRET_PROVIDER_CLASS_NAME
: SecretProviderClass オブジェクトの名前。NAMESPACE
: このリソースを作成する Kubernetes Namespace。resourceName
: Secret Manager のシークレットの完全なリソース識別子。これには、projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION の形式でプロジェクト ID、シークレット名、バージョンを含める必要があります。SECRET_PROJECT_ID
: シークレットが保存されているプロジェクトの ID。 Google Cloud Secret が GKE クラスタと同じプロジェクトに保存されている場合は、PROJECT_ID と同じにできます。SECRET_NAME
: シークレット名SECRET_VERSION
: シークレットのバージョン。シークレット バージョンは、クラスタと同じリージョンに存在する必要があります。
path
: Secret 値が Kubernetes 環境内で公開されるローカル ファイル名またはエイリアス。これは、特定の Secret Manager バージョンをクラスタで使用されるローカル表現にリンクする一意の識別子です。SecretSync リソースを使用して Secret が Kubernetes Secret に同期されると、このパスはsourcePath
フィールドによって参照され、同期する Secret 値が特定されます。複数のシークレット(resourceName
で定義)を同じ SecretProviderClass 内の異なるパス名にマッピングできます。
マニフェストを適用するには、次のコマンドを実行します。
kubectl apply -f spc.yaml
YAML マニフェストを使用して SecretSync カスタム リソースを作成します。このリソースは、SecretProviderClass で定義されたコンテンツに基づいて Kubernetes Secret を作成または更新するように同期コントローラに指示します。
次の内容の
secret-sync.yaml
ファイルを作成します。apiVersion: secret-sync.gke.io/v1 kind: SecretSync metadata: name: KUBERNETES_SECRET_NAME namespace: NAMESPACE spec: serviceAccountName: KSA_NAME secretProviderClassName: SECRET_PROVIDER_CLASS_NAME secretObject: type: KUBERNETES_SECRET_TYPE data: - sourcePath: "FILENAME.txt" targetKey: "TARGET_KEY1" - sourcePath: "FILENAME1.txt" targetKey: "TARGET_KEY2"
次のように置き換えます。
KUBERNETES_SECRET_NAME
: SecretSync リソースによって作成される新しい Kubernetes Secret に付ける名前。NAMESPACE
: 新しいリソースが作成される Kubernetes Namespace。SecretProviderClass と同じ Namespace にする必要があります。KSA_NAME
: SecretSync コントローラがターゲット Kubernetes Secret の作成と更新に使用する Kubernetes ServiceAccount の名前。この ServiceAccount には、Secret Manager から外部シークレットにアクセスするために必要な権限が必要です。SECRET_PROVIDER_CLASS_NAME
: 前の手順で作成した SecretProviderClass オブジェクトの名前。SecretSync リソースは、これを使用してシークレットの正しい構成を見つけます。KUBERNETES_SECRET_TYPE
: 作成する Kubernetes Secret のタイプ(Opaque
、tls
、docker-registry
など)。これにより、Kubernetes が Secret のデータを処理する方法が決まります。sourcePath
: 取得する Secret データを識別するローカル ファイル名またはエイリアス(SecretProviderClass のpath
フィールドの値)。SecretSync コントローラは、このsourcePath
を使用して特定のシークレット コンテンツをリクエストし、新しい Kubernetes Secret に変換します。targetKey
: 作成される新しい Kubernetes Secret のdata
セクションで使用されるキー。これは、sourcePath
を使用して取得した Secret コンテンツに名前を付け、最終的な Kubernetes Secret オブジェクトに保存する方法を定義します。データ配列で複数のエントリを使用すると、同じターゲット Secret 内で複数の Key-Value ペアを定義できます。
マニフェストを適用するには、次のコマンドを実行します。
kubectl apply -f secret-sync.yaml
同期コントローラは、指定された Namespace に Kubernetes Secret を作成します。このシークレットには、Secret Manager からマッピングされたデータが含まれています。
Kubernetes Secret が作成されていることを確認します。
kubectl get secret KUBERNETES_SECRET_NAME -n NAMESPACE -o yaml
次のように置き換えます。
KUBERNETES_SECRET_NAME
: 新しい Kubernetes Secret の名前NAMESPACE
: 新しい Secret が作成される Kubernetes Namespace
同期の問題をトラブルシューティングするには、次のコマンドを使用します。
kubectl describe secretSync KUBERNETES_SECRET_NAME -n NAMESPACE
次のように置き換えます。
KUBERNETES_SECRET_NAME
: 新しい Kubernetes Secret の名前NAMESPACE
: 新しい Secret が存在する Kubernetes Namespace
シークレットのローテーションを管理する
クラスタで --enable-secret-sync-rotation
フラグを有効にすると、同期コントローラは SecretManager を定期的にチェックして、SecretProviderClass リソースで指定されたシークレットの新しいバージョンを探します。--secret-sync-rotation-interval
フラグは、コントローラが更新を確認する頻度を決定します。
コントローラが Secret Manager で新しいシークレット バージョンを検出すると、対応する Kubernetes Secret が更新されます。コントローラは、シークレット コンテンツのハッシュを比較し、変更が発生した場合にのみシークレットを更新します。
これらの Secret を使用するアプリケーションは、更新された Secret 値を Kubernetes Secret から検出して再読み込みする必要があります。この処理方法は、アプリケーションの設計によって決まります。
シークレットの同期を無効にする
シークレットの同期を無効にするには、次の gcloud CLI コマンドを実行します。
gcloud
Secret Manager をコマンドラインで使用するには、まず Google Cloud CLI のバージョン 378.0.0 以降をインストールまたはアップグレードします。Compute Engine または GKE では、cloud-platform スコープを使用して認証する必要があります。
gcloud beta container clusters update CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --no-enable-secret-sync
次のように置き換えます。
CLUSTER_NAME
: GKE クラスタの名前CONTROL_PLANE_LOCATION
: クラスタ コントロール プレーンのリージョンまたはゾーン(us-central1
、us-east1-a
など)
このコマンドは、同期コントローラを停止します。すでに作成されている Kubernetes Secret は削除されません。同期された Kubernetes Secret が不要になった場合は、手動で削除する必要があります。
同期されたシークレットを削除する
同期された Kubernetes Secret を削除するには、次のコマンドを使用して SecretSync
リソースを削除します。
kubectl delete secretsync KUBERNETES_SECRET_NAME --namespace NAMESPACE
次のように置き換えます。
KUBERNETES_SECRET_NAME
: Kubernetes Secret の名前NAMESPACE
: Secret が存在する Kubernetes Namespace
既存の Secrets Store CSI ドライバから移行する
Secrets Store CSI ドライバの既存のインストールから移行する場合は、次の操作を行います。
SecretProviderClass の
provider
フィールドをgcp
からgke
に更新します。次の例は、provider
フィールドを更新する方法を示しています。apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: app-secrets-gke spec: provider: gke parameters: secrets: | - resourceName: "projects/87654321/secrets/api-key-secret/versions/2" path: "good1.txt"
SecretSync リソースを作成します。次の構成例を使用します。
apiVersion: secret-sync.gke.io/v1 kind: SecretSync metadata: name: my-kube-secret namespace: NAMESPACE spec: serviceAccountName: KSA_NAME secretProviderClassName: my-app-secrets secretObject: type: Opaque # Or other Kubernetes Secret types data: - sourcePath: "my-secret.txt" targetKey: "USERNAME" - sourcePath: "another-secret.txt" targetKey: "PASSWORD"
セキュリティ上の考慮事項
Secret Manager には、IAM によるアクセス制御、顧客管理の暗号鍵(CMEK)、監査ロギングなどのセキュリティ機能が用意されています。シークレットは、Secret Manager 内で保存時と転送時に暗号化されます。シークレットを Kubernetes シークレットに同期すると、クラスタ内のセキュリティは GKE クラスタの構成によって異なります。次の点を考慮してください。
ストレージ: Kubernetes Secret は、GKE のプライマリ データストアである etcd に保存されます。デフォルトでは、GKE は保存データを暗号化します。セキュリティを強化するには、Cloud Key Management Service(Cloud KMS)で管理する鍵を使用して、アプリケーション レイヤで Kubernetes Secret を暗号化します。Secret を暗号化すると、機密性の高いワークロードのセキュリティがさらに強化されます。
アクセス制御: GKE は、ロールベース アクセス制御(RBAC)を使用して、プロジェクトとクラスタ内のリソースへのアクセス権を管理するための複数のオプションをサポートしています。RBAC 権限が広すぎると、意図しないワークロードやユーザーにシークレットが公開される可能性があります。最小権限の原則に従ってアクセス権を付与し、Secret Manager と Kubernetes Secret の両方へのアクセスを定期的に監査します。
環境変数: セキュリティを強化するには、Kubernetes Secret を環境変数として使用するのではなく、ボリュームとしてマウントします。これにより、誤ってロギングされたり、他のプロセスに公開されたりするリスクを軽減できます。
次のステップ
- Kubernetes Secret を確認します。
- Workload Identity について理解する。