本記事の目的
- Kubernetesのシークレット管理方法をまとめる
- Vaultを利用する場合のKubernetes(以降K8s)との統合方法をまとめる
出発点の課題 → 安全に Secret リソースを Kubernetes 上にデプロイするために「シークレット管理」が必要
K8sのSecretリソースを普通にManifestで管理しようとするとBase64でエンコードされただけの秘匿データもGitに含まれてしまう。
OSSの「シークレット管理」の仕組み
OSSとして以下のようなシークレット管理の仕組みが公開されている。
1. External Secrets Operator について
概要
AWS Secrets Manager や HashiCorp Vault などのexternal secret管理システムからデータを取得しK8s Secretリソースに入れ込む動きをする。
仕組み
K8sのカスタムリソースによって専用のリソースとして提供される。
リソースは、kind=ExternalSecret
はkind=SecretStore
の2つがある。
2つの役割はそれぞれExternalSecret
は何をフェッチするか、SecretStore
はどうやってアクセスするか、を指定するという分担になっている。
GitHub
図1
2. Secrets Store CSI Driver について
概要
Secretデータを保存するVolumeとそのVolumeへアクセスするインターフェースを提供する。AWS Secrets Manager や HashiCorp Vault などのexternal secret管理システムはそれぞれSecrets Store CSI Driverのインターフェースを利用するProviderを提供している。Volumeへ入ったデータはK8sクライアントがマウントすることで利用される。
仕組み
K8sのカスタムリソースとしてSecrets Store CSI DriverのVolume用Podとインターフェースは提供されている。
GitHub
図2
3. Sealed Secrets について
概要
Gitで管理するK8sのSecretリソースを公開鍵で暗号化する。秘密鍵を持ったK8sコントローラーのみが複合化でき実際のSecretリソースへ入れる。
仕組み
K8sのカスタムリソースとしてkind: SealedSecret
というリソースで暗号化してGit管理する。helmを使い専用のK8sコントローラーを動作させることで複合化しSecretリソースに入れるようになる。
GitHub
ref:
図3
VaultをK8sのExternal Secret管理システムとして利用するための実現方法3パターン
2023年4月の以下のVault公式記事で以下の3パターンの実装方法がK8sとVaultの統合にあると示された。
- The Vault Sidecar Agent Injector
- The Vault Container Storage Interface (CSI) provider
- The Vault Secrets Operator
記事ではそれぞれの比較について書かれている。結論の表だけ拝借すると以下とのこと4
1. Sidecar Agent Injector について
概要図が以下になる4
詳細なK8sとVaultとの全体シーケンス
Sider Agent InjectorによってVault AgentがサイドカーとしてPodに入るケースの全体シーケンス図として以下の図が理解しやすい5
上図のシーケンスの各ステップの詳細をまとめると以下になる。
- 1st Phase: VaultへK8s認証MethodのConfigurationを設定する
- Step1: K8s Pub CA Certを登録する
- これは2nd PhaseでのStep2でのVaultがK8s APIを叩く"TokenReview API Called"にて使うK8sサーバ側の証明書である。
- Step2: ロール設定
- K8s認証メソッド設定におけるK8sクライアントのService AccountとNamespaceを設定する。
- Step3: ポリシー設定
- Step2で設定したロールに対して設定するVaultポリシー
- Step1: K8s Pub CA Certを登録する
- 2nd Phase: Podをデプロイするとき、Vaultのトークンを取得する
- Step1: K8sクライアントのService AccountのJWTをVaultへ渡す
- Step2-3: Vaultが渡されたJWTを引数に K8sコントローラーのTokenReview APIを呼び 、データを受け取る。
- Step4: K8sコントローラーから渡された情報と1st Phaseで設定していたロール・ポリシー情報とで検証する。
- Step5: 認証OKならばK8sクライアントへVaultトークンを渡す。
- 3rd Phase: Vualtトークンを使ってK8sクライアントがVaultから必要なデータを取得する。
Vault Agent がやること
【実現したいこと】VaultのトークンのライフサイクルをK8sクライアントが専用ロジックを実装すること無く管理したい。
【ソリューション】Vault Agent というデーモンを立てることでロジックを吸収させる。
Vault Agent is a client daemon that provides the following features:
- Auto-Auth - Automatically authenticate to Vault and manage the token renewal process for locally-retrieved dynamic secrets.
- API Proxy - Allows Vault Agent to act as a proxy for Vault's API, optionally using (or forcing the use of) the Auto-Auth token.
- Caching - Allows client-side caching of responses containing newly created tokens and responses containing leased secrets generated off of these newly created tokens. The agent also manages the renewals of the cached tokens and leases.
- Windows Service - Allows running the Vault Agent as a Windows service.
- Templating - Allows rendering of user-supplied templates by Vault Agent, using the token generated by the Auto-Auth step.
vault-k8s がやること
【実現したいこと】Vault AgentをサイドカーとしてK8sクライアントのPodに注入する仕組みを持ちたい。
【ソリューション】Agent Sidecar Injector のリソースをK8sに持たせ、 Kubernetes Mutation Webhook ControllerのK8sの機能を利用することでInjectionを実現する。実装は vault-k8s である。
【仕組み概要】
The Vault Agent Injector works by intercepting pod CREATE and UPDATE events in Kubernetes. The controller parses the event and looks for the metadata annotation vault.hashicorp.com/agent-inject: true. If found, the controller will alter the pod specification based on other annotations present.
また、K8sクライアントManifestのAnnotationでのSecretデータ取得指定は以下のように特殊な記述方法になるので留意が必要。
vault.hashicorp.com/agent-inject-secret-<unique-name>: /path/to/secret
2. Container Storage Interface (CSI) provider について
上述のSecrets Store CSI DriverのVault側のProvider実装である。
GitHub: https://github.com/hashicorp/vault-csi-provider
概要図は以下4
3. Secrets Operator について
上述のExternal Secrets Operatorとは別の実装としてVault側が専用のOperatorとして提供しているもの、(のように見える)。
GitHub: https://github.com/hashicorp/vault-secrets-operator/
-
https://secrets-store-csi-driver.sigs.k8s.io/concepts.html ↩
-
https://aws.amazon.com/blogs/opensource/managing-secrets-deployment-in-kubernetes-using-sealed-secrets/ ↩
-
https://www.hashicorp.com/blog/kubernetes-vault-integration-via-sidecar-agent-injector-vs-csi-provider ↩ ↩2 ↩3
-
https://developer.hashicorp.com/vault/tutorials/kubernetes/agent-kubernetes#start-vault-agent-with-auto-auth ↩