このドキュメントでは、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 Manager API と Google Kubernetes Engine API を有効にする。
API を有効にするために必要なロール
API を有効にするには、
serviceusage.services.enable権限が必要です。プロジェクトを作成した場合は、オーナーロール(roles/owner)を介してこの権限が付与されている可能性があります。それ以外の場合は、Service Usage 管理者ロール(roles/serviceusage.serviceUsageAdmin)を介してこの権限を取得できます。ロールを付与する方法をご覧ください。 インストールして初期化します。 gcloud CLIgcloud CLI をインストール済みの場合は、
gcloud components updateコマンドを実行して最新のバージョンを取得します。GKE クラスタが実行されていることを確認します。この機能には、GKE バージョン 1.33 以降が必要です。
GKE クラスタで Workload Identity Federation for GKE が有効になっていることを確認します。 これは認証に必要です。Workload Identity Federation for GKE は、Autopilot クラスタではデフォルトで有効になっています。
GKE クラスタと Secret Manager を管理するために必要な Identity and Access Management 権限があることを確認します。
GKE クラスタでシークレット同期を有効にする
新しいクラスタを作成するとき、または既存のクラスタを更新するときに、シークレット同期機能を有効にします。この機能は、Standard クラスタと Autopilot クラスタの両方で使用できます。
新しいクラスタでシークレット同期を有効にする
シークレット同期を使用して新しいクラスタを作成するには、次のいずれかの gcloud CLI コマンドを使用します。
Standard クラスタ
Secret Manager をコマンドラインで使用するには、まず Google Cloud CLI のバージョン 378.0.0 以降をインストールまたはアップグレードします。 Compute Engine または GKE では、 `cloud-platform` スコープを使用して認証する必要があります。
自動ローテーションなしでシークレット同期を有効にします。
gcloud container clusters create CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--workload-pool=PROJECT_ID.svc.id.goog \
--enable-secret-sync
自動ローテーションでシークレット同期を有効にします。デフォルトの間隔は 2 分です。
gcloud 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 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=60s
次のように置き換えます。
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 container clusters create-auto CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--enable-secret-sync
自動ローテーションでシークレット同期を有効にします。デフォルトの間隔は 2 分です。
gcloud container clusters create-auto CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--enable-secret-sync \
--enable-secret-sync-rotation
カスタム ローテーション間隔でシークレット同期を有効にします。最小間隔は 1 分です。
gcloud container clusters create-auto CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--enable-secret-sync \
--enable-secret-sync-rotation \
--secret-sync-rotation-interval=60s
次のように置き換えます。
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 container clusters update CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--enable-secret-sync
カスタム間隔でローテーションを有効にする
gcloud container clusters update CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--enable-secret-sync-rotation \
--secret-sync-rotation-interval=300s
ローテーションを無効にする
gcloud 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 にシークレットへのアクセス権を付与します。
gcloud
Secret Manager をコマンドラインで使用するには、まず Google Cloud CLI のバージョン 378.0.0 以降をインストールまたはアップグレードします。Compute Engine または GKE では、 `cloud-platform` スコープを使用して認証する必要があります。
gcloud secrets add-iam-policy-binding SECRET_NAME \ --role=roles/secretmanager.secretAccessor \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME
次のように置き換えます。
SECRET_NAME: Secret Manager でのシークレットの名前。PROJECT_NUMBER: プロジェクト番号 Google CloudPROJECT_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_1/versions/SECRET_VERSION_1" path: "FILENAME.txt" - resourceName: "projects/SECRET_PROJECT_ID/secrets/SECRET_NAME_2/versions/SECRET_VERSION_2" 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: シークレットが保存されている Google Cloud プロジェクト の ID。シークレットが GKE クラスタと同じプロジェクトに保存されている場合は、 PROJECT_ID と同じになります。SECRET_NAME: シークレット名。SECRET_VERSION: シークレットのバージョン。シークレットのバージョンは、クラスタと同じリージョンに存在する必要があります。
path: シークレット値が Kubernetes 環境内で公開されるローカル ファイル名またはエイリアス。これは、特定の Secret Manager バージョンをクラスタで使用されるローカル表現にリンクする一意の識別子です。SecretSync リソースを使用してシークレットが Kubernetes Secret に同期されると、このパスはsourcePathフィールドで参照され、同期するシークレット値が特定されます。 複数のシークレット(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 がシークレットのデータを処理する方法が決まります。sourcePath: 取得するシークレット データを識別するローカル ファイル名またはエイリアス(SecretProviderClass のpathフィールドの値)。SecretSync コントローラは、このsourcePathを使用して特定のシークレット コンテンツをリクエストし、新しい Kubernetes Secret に変換します。targetKey: 作成される新しい Kubernetes Secret のdataセクションで使用されるキー。これにより、sourcePathを使用して取得したシークレット コンテンツの名前と、最終的な Kubernetes Secret オブジェクトへの保存方法が定義されます。データ配列で複数のエントリを使用すると、同じターゲット Secret 内で複数のキーと値のペアを定義できます。
マニフェストを適用するには、次のコマンドを実行します。
kubectl apply -f secret-sync.yaml
同期コントローラは、指定された Namespace に Kubernetes Secret を作成します。この 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、同期コントローラは Secret Manager
で SecretProviderClass リソースで指定されたシークレットの新しいバージョンを定期的に確認します。--secret-sync-rotation-interval フラグは、コントローラが更新を確認する頻度を決定します。
コントローラが Secret Manager で新しいシークレット バージョンを検出すると、対応する Kubernetes Secret が更新されます。コントローラはシークレット コンテンツのハッシュを比較し、変更が発生した場合にのみシークレットを更新します。
これらのシークレットを使用するアプリケーションは、更新されたシークレット値を Kubernetes Secret から検出して再読み込みする必要があります。この処理方法は、アプリケーションの設計によって異なります。
シークレット同期を無効にする
シークレット同期を無効にするには、次の gcloud CLI コマンドを実行します。
gcloud
Secret Manager をコマンドラインで使用するには、まず Google Cloud CLI のバージョン 378.0.0 以降をインストールまたはアップグレードします。Compute Engine または GKE では、 `cloud-platform` スコープを使用して認証する必要があります。
gcloud 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 は、Secret Manager 内で保存時と転送時に暗号化されます。シークレットを Kubernetes Secret に同期する場合、クラスタ内のセキュリティは GKE クラスタの構成によって異なります。次の点を考慮してください。
ストレージ: Kubernetes Secret は、 GKE のプライマリ データストアである etcd に保存されます。デフォルトでは、GKE は保存データを暗号化します。セキュリティを強化するには、 アプリケーション レイヤで Kubernetes Secret を暗号化するには、 Cloud Key Management Service(Cloud KMS)で管理する鍵を使用します。 シークレットを暗号化すると、機密性の高いワークロードのセキュリティがさらに強化されます。
アクセス制御: GKE は、 ロールベースのアクセス制御(RBAC)を使用して、プロジェクトとクラスタ内のリソースへのアクセス権を 管理する複数のオプションをサポートしています。RBAC 権限が広すぎると、意図しないワークロードやユーザーにシークレットが公開される可能性があります。最小権限の原則に従ってアクセス権を付与し、Secret Manager と Kubernetes Secret の両方へのアクセスを定期的に監査します。
環境変数: セキュリティを強化するには、Kubernetes Secret を環境変数として使用するのではなく、 ボリュームとしてマウントします。これにより、誤ってログに記録されたり、他のプロセスに公開されたりするリスクを軽減できます。
次のステップ
- Kubernetes Secret について学習する。
- Workload Identity について学習する。