だいぶニッチな記事です。
Agent Sidecar Injectorを使う際につまずいた点をいくつかまとめました。
HashiCorp Vaultとは
HashiCorp Vaultは、APIキー、パスワード、証明書などのシークレットを安全に保存、管理、アクセス制御、および監査するためのセキュリティプラットフォームです。
Agent Sidecar Injectorとは
Agent Sidecar Injectorは、vault-k8sに組み込まれた機能の一つで、Kubernetes上のPodにAgent Containerを自動的に追加する機能です。
Podに追加されたAgent Containerは、Vaultへの認証を行い、Podの環境変数やファイルに取得したシークレットを書き出します。
上記ドキュメントによると、Podへのコンテナの注入はKubernetesのMutating Admission Webhookという機能を利用しているようで、この機能を使えばK8s上のリソース(今回だとPod)作成時などのタイミングで、動的に内容を変更することができるようです。
Agent Sidecar Injectorでは、以下のような特定のannotationがPodに付与されている場合にAgentコンテナを追加します。
annotations:
"vault.hashicorp.com/agent-inject": "true"
Agent Sidecar Injectorのメリット
KubernetesのSecretをそのまま利用すると、単にBase64エンコードされた値をyamlに記述するだけなので、シークレットの管理に一手間かかります。
そこで、Vault経由でシークレットを差し込む事によって、シークレットの管理をVaultに任せることができ、手間をある程度削減しつつ、セキュアなシークレット管理が可能になります。
また、導入も簡単で、基本的な使い方であれば、公式が用意しているHelm Chartを使ってインストールし、いくつかの設定を行うだけで利用できます。
本題
本題に入ります。
Agent Sidecar Injectorを使う際いくつかつまずいた点があるため、以下でそれらを紹介します。
Job, CronJobの場合は常駐するSidecar Containerを無効にしなければ永遠に完了しない
Agent Sidecar Injectorを使うと、PodにAgent Containerを追加できますが、デフォルト設定ではInit ContainerとSidecar Containerが追加されます。
Init ContainerはPodの初期化時にシークレットを差し込むために一度だけ実行され、Sidecar ContainerはPodのライフサイクル中に常駐し、Vault側で更新があればそれらをPod側に反映してくれます。
ここで問題になるのは、Sidecar Containerの方で、KubernetesのJobは、すべてのコンテナが終了しないとJobが完了したことになりません。
そのため、Sidecar Containerが常駐してしまうと、永遠にJobが完了しないままになります。
解決方法
Jobの場合は、常駐するSidecar Containerを無効化するために、以下のような設定を行います。
vault.hashicorp.com/agent-pre-populate-only: "true"
この設定を行うことで、Sidecar Containerは常駐しなくなり、Init Containerのみが実行されます。
Jobにシークレットを差し込む場合は、この設定を行うことをおすすめします。
また、通常のPod(Deploymentなど)を利用している場合でも、アプリケーションへのシークレットの読み込みが初回のみで問題ない仕様であれば、この設定を行うことで、不要なリソースを消費しないようにできます。
Sidecar Containerは意外とリソースを食うので、必要ない場合は無効にすることを検討してみてください。
vault-agent-injectorより先にPodが作成されるとAgent Containerが追加されない
Agent Sidecar Injectorは、PodにAgent Containerを追加するためにvault-agent-injector
というDeploymentを作成します。
このDeploymentに属しているPodがシークレット差し込み先のPodより先に作成されないと、Podが作成されるタイミングでAgent Containerが追加されず、シークレットが取得できません。
私の環境だと、同一ノード上に該当するPodがある関係か、クラスターのアップデート時にこの問題が発生しました。アップデート時にすべてのPodが作り直されるため、起動順によって問題が発生したり、しなかったりという状況でした。
解決方法
以下のディスカッションで解決方法が紹介されていました。
以下の設定を行うことで、NotInに設定されたNamespace以外のPodは、vault-agent-injector
が起動するまでブロックされるようになります。
injector:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values: ["vault","kube-system","kube-public","kube-node-lease"]
ただし、このIssueによると、annotationがないPodも含め、NotInに指定されていないNamespaceのPodがすべてブロックされるようなので、注意が必要です。
まとめ
全体的にニッチな内容だと思っているのですが、Agent Sidecar Injectorに関しては日本語の情報が少ないと感じているので、誰かの助けになれば幸いです。
(試しにAgent Sidecar Injector
で検索してみると2件ぐらいしかありませんでした...HashiCorp Vault Kubernetes
などで検索するともう少しヒットすると思います)
また、Vaultに関しての公式ドキュメントはわかりにくい部分もありますが、かなり充実しているので、そちらも参考にしてみてください。