🐥

GKEのSecretとSecret Managerの同期機能について

に公開

はじめに

どうもこんにちは。間瀬です。
本記事は Google Developer Experts Advent Calendar 2025 22日目の記事です。

今回は個人的にGKEで今年一番嬉しかったアップデートと言っても過言ではないのにあまり注目を浴びていない? Secret ManagerとGKE上で管理されるSecretを同期することができる機能について紹介したいと思います。
該当機能の公式ドキュメントはこちらです。

Secretを管理する上での課題

前提知識:SecretはKubernetesが提供する秘密情報を管理する機能

機能を説明する前に簡単にSecretを使用する際の注意点や課題について触れておきます。

GKE上で管理されるSecretとは、GKE個別機能ではなくKubernetesが提供する機能でパスワードなど一般的に秘密とされる情報をSecretオブジェクトとして登録することができます。
https://kubernetes.io/ja/docs/concepts/configuration/secret/

登録された情報はアプリケーションをPodとしてデプロイする時に環境変数やボリュームを通じて参照することができます。

情報が漏洩しないよう、Secretをどうやってデプロイするか

GKEをはじめKubernetesクラスタにSecret以外のオブジェクトをデプロイする際、多くのケースではyaml形式のマニフェストファイルを用いることになりますが、Secretを同様にマニフェストファイルで管理してしまうと、秘密情報がファイルやコードリポジトリを通じて漏洩してしまうリスクがあります。

risk

Secretを利用する際にはどのように資材を管理してデプロイしていくのか検討する必要があります。今回紹介する機能はこのようなSecretの管理課題の解決を助けるものになります。

Secret ManagerとGKEクラスタ上のSecretを同期する機能

Secret ManagerはGoogle Cloudが提供するサービスで、可用性やセキュリティを確保しながら秘密情報を管理することができます。
本機能を利用することで、Secret Managerでのみ秘密情報を管理して、指定する情報のみGKEクラスタ上のSecretオブジェクトとして情報を同期することができます。

Secret Store CSIドライバをベースとした機能が既に提供済み。

ご存知の方が多いかもしれませんが、類似機能としてSecret Managerで管理する秘密情報をGKEクラスタ上のPodにボリュームマウントすることができるGKEの機能が既に一般提供されています。

既存機能とは何が違うの?

既存機能ではPodに対してボリュームマウントすることができましたが、Secretオブジェクトを作成することはできません。

そのため、今回紹介する機能との違いはSecretオブジェクトが作成されるかどうかになります。
Secretオブジェクトとして作成されることで、既存機能のようにボリュームとしてマウントすることに加えて環境変数として参照させることも可能になります。

公式ドキュメントに詳しく仕組みが書かれておらず、妥当性に不安がありますが構成は恐らく以下のような感じになります。
同期機能は既存機能となるCSIの「SecretProviderClass」に依存しており、「SecretSync」というオブジェクトを通じてコントローラー経由でSecretオブジェクトとの同期を行っているようです。

vs

(*1):既存機能であるCSIによってPodへボリュームをマウントする機能を記載しています。新たな同期機能は既存機能に対してSecretSyncの仕組みを追加したような形になっています。

使ってみる

記事執筆時点はプレビューであるため、以下のコマンドによって有効化する必要があります。

  1. Secret Managerに秘密情報をシークレットとして登録する。
    公式ドキュメントに従って情報を登録します。
    今回は APP_PASSWORD という名前のシークレットを作成した前提で以降進めていきます。

  2. 同期機能を有効化したクラスタの作成
    作成済みのクラスタに対して同期機能を有効化することも可能です。

gcloud beta container clusters create my-cluster \
    --location=asia-northeast1 \
    --workload-pool=PROJECT_ID.svc.id.goog \
    --enable-secret-sync
  1. 同期する際に利用するサービスアカウントを作成する
    今回はsecret-accessorという名称でdefaultネームスペースに作成します。
kubectl create serviceaccount secret-accessor --namespace default
  1. サービスアカウントにSecret Managerにアクセスできる権限を付与する。
gcloud secrets add-iam-policy-binding secret-accessor \
   --role=roles/secretmanager.secretAccessor \
   --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/default/sa/secret-accessor
  1. SecretProviderClassを作成する。
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: app-secret-provider
  namespace: default
spec:
  provider: gke
  parameters:
    secrets: |
      -   resourceName: "projects/PROJECT_ID/secrets/APP_PASSWORD/versions/latest" # 手順1.で作成したシークレットを指定する
          path: "APP_PASSWORD" # この後作成するSecretSyncで指定する

  1. SecretSyncを作成する。
apiVersion: secret-sync.gke.io/v1
kind: SecretSync
metadata:
  name: app-secret
  namespace: default
spec:
  serviceAccountName: secret-accessor          # 手順3で作成したサービスアカウント名
  secretProviderClassName: app-secret-provider # 手順5で作成したSecretProviderClass名
  secretObject:
    type: Opaque                               # opaque,tls、docker-registry といった kubernetes secret のタイプを指定可能
    data:
      -   sourcePath: "APP_PASSWORD"           # 手順5で作成したSecretProviderClassのpath
          targetKey: "PASSWORD"                # Secretオブジェクトおけるキーを指定
  1. 同期結果の確認
    上記のSecretSyncを作成した時点で以下のようにGKEクラスタ上にSecretオブジェクトが作成されます。data内のキーがPASSWORDになっていることが分かります。
kubectl get secret app-secret -o yaml

apiVersion: v1
data:
  PASSWORD: SGF2ZSBhIGdyZWF0IE5ldyBZZWFyISA=
kind: Secret
metadata:
  annotations:
    secrets-store.sync.gke.io: ""
  creationTimestamp: "2025-12-21T16:21:24Z"
  labels:
    secrets-store.sync.gke.io: ""
  name: app-secret
  namespace: default
  ownerReferences:
  - apiVersion: secret-sync.gke.io/v1
    kind: SecretSync
    name: app-secret
    uid: e63f5f67-b0c0-48f2-a387-39a24aa90d1b
  resourceVersion: "1766334084802927017"
  uid: 803c9ac5-c4d8-40f7-b876-2b818e5a76d8
type: Opaque

補足情報

Secretの同期頻度はカスタマイズ可能

一度同期したきりにすることも、一定間隔で同期することも可能です。
自動同期の有無や間隔はクラスタの設定で行うことができます。詳細は公式ドキュメントを参照してください。

Secretオブジェクトは全然シークレットではないことに注意

Secretオブジェクトで管理されるデータはデフォルトだとbase64でエンコードされているだけなので、参照する権限さえあれば簡単にデコードすることが可能です。

echo 'SGF2ZSBhIGdyZWF0IE5ldyBZZWFyISA=' | base64 -d
Have a great New Year!

そのため、RBACによる権限制御や、こちらを利用してSecretのデータを暗号化するなどを検討してください。

さいごに

今回はSecret ManagerからGKE上のSecretオブジェクトへ同期する機能を紹介しました。
Google Cloudからはなるべく既存機能であるボリュームマウントによってSecretを参照させる形を推奨していますが、ボリュームマウントによる対応が困難なケースでは今回紹介したような機能を検討してみてください。
一早く一般提供されることを願っています。記事を閲覧いただきありがとうございました。

Have a great New Year!

参考文献

GKE でセキュアに秘匿情報を管理する: Secret Manager アドオンと External Secrets Operator

Discussion