【ITニュース解説】🔐Vault With Kubernetes

2025年09月04日に「Dev.to」が公開したITニュース「🔐Vault With Kubernetes」について初心者にもわかりやすいように丁寧に解説しています。

作成日: 更新日:

ITニュース概要

HashiCorp Vaultは、APIキーやパスワードなどの機密情報を安全に保存・管理するプラットフォームだ。Kubernetes上にデプロイし、Shamir分散法で保護されたUnsealキーを使って機密情報を復号する。PodはKubernetes認証でVaultと連携し、必要な機密データを安全に取得できる。

出典: 🔐Vault With Kubernetes | Dev.to公開日:

ITニュース解説

HashiCorp Vaultは、ソフトウェア開発や運用において非常に重要な「機密情報」を安全に管理するためのプラットフォームである。APIキー、データベースの認証情報、TLS証明書、トークンといった、もし外部に漏洩すれば重大な被害をもたらす可能性のあるデータを、安全に保管し、必要に応じて生成し、アクセスを厳密に制御する役割を担う。企業やチームは、これらの機密情報を一元的に管理することで、セキュリティを強化し、オンデマンドで有効期間の短い認証情報を発行したり、アプリケーション、CI/CDパイプライン、そしてインフラ全体にわたって「最小権限の原則」を適用したりする。これは、必要な最小限のアクセス権限のみを付与することで、セキュリティリスクを低減する考え方である。

VaultをKubernetes環境で利用することは一般的であり、Helmというツールを使うことで簡単にインストールできる。HelmはKubernetes上でアプリケーションを管理するためのパッケージマネージャーのようなもので、複雑なアプリケーションのデプロイを簡素化する。開発用途では、データストレージを持たない簡易的なVaultをデプロイすることも可能だが、これは永続的なデータの保存には向かない。本番環境でVaultを使う際には、Raftストレージといった永続的なデータ保存メカニズムを有効にする。Raftは分散システムにおける合意形成アルゴリズムの一種で、複数のVaultサーバー間でデータを同期させ、耐障害性を高めるために用いられる。これにより、たとえ一部のサーバーが停止しても、Vaultのサービスが継続できる。インストールの際には、values.yamlという設定ファイルを用いて、UIの有効化やストレージの指定など、詳細な設定を行う。

Vaultサーバーが起動すると、最初は「sealed(封印された)」状態となる。この状態では、Vaultは物理的なストレージにアクセスできるものの、そこに保存されているデータを解読することはできない。Vaultはデータを暗号化キー(キーリング内)で暗号化し、それをストレージバックエンドに保存する。この暗号化キー自体も、さらに「ルートキー」と呼ばれる別の暗号化キーで暗号化され、データと共に保存される。つまり、データを解読するには、まずルートキーを使って暗号化キーを解読する必要がある。

しかし、このルートキーも直接アクセスできる状態にはない。ルートキーは「アンシールキー」によって暗号化されており、アンシールキーがなければルートキーを解読できないようになっている。アンシールキーは、ユーザーがVaultを「unseal(開封)」するプロセスで提供される。この多重の暗号化は、最高レベルのセキュリティを確保するための仕組みである。

アンシールキーは通常、そのままの形で誰か一人に渡されるのではなく、「Shamirの秘密分散法」というアルゴリズムを用いて複数の「キーシェア」に分割される。例えば、5つのキーシェアに分割し、そのうち3つがあれば元のアンシールキーを再構築できる、といった設定が可能だ。これは、単一のキーが漏洩してもVaultが不正に開封されるリスクを防ぎ、複数の信頼できるオペレーターが協力しなければVaultを開封できないようにすることで、セキュリティ体制を強化する。Vaultの起動後、vault operator initコマンドを実行すると、このキーシェアと初期のルートトークンが生成される。Vaultは、指定された閾値分のキーシェアが入力されるまで、アンシール状態にはならない。各オペレーターは自分のキーシェアを一つずつ入力し、必要な数のシェアが揃うと、Vaultはアンシールキーをメモリ上で再構築し、それを使ってルートキーを解読し、最終的に暗号化キーを解読して、サービスを開始できる状態となる。この過程では、マスターキーがディスクに書き込まれることはなく、常にメモリ上で処理されるため、さらにセキュリティが高まる。

Vaultがアンシールされたら、次はKubernetesアプリケーションからのアクセスを構成する。まず、Kubernetes認証を有効にする必要がある。これは、KubernetesのPodが自分のサービスアカウントトークンを使って、安全にVaultに認証できるようにするための設定だ。この設定を行うことで、VaultはKubernetes APIサーバーと通信し、Podから送られてくるサービスアカウントトークンが正当なものかを検証できるようになる。

この設定にはいくつかの重要なパラメータがある。token_reviewer_jwtは、VaultがKubernetes APIサーバーに認証を行う際に使うサービスアカウントトークンである。Vault自身がKubernetes APIに問い合わせる際の「身分証明書」のようなものだ。kubernetes_hostは、Kubernetes APIサーバーのURLを指定する。VaultはこのURLを通じてKubernetes APIにアクセスし、Podの認証情報を検証する。kubernetes_ca_certは、KubernetesクラスターのCA証明書である。VaultがKubernetes APIサーバーとのTLS通信を行う際に、サーバーの証明書が本物であることを検証するために使われる。これにより、中間者攻撃を防ぎ、安全な通信を確立する。これらの設定により、PodがVaultにサービスアカウントトークンを提示すると、Vaultはtoken_reviewer_jwtを使ってKubernetes APIにそのトークンの有効性を問い合わせ、Kubernetes APIが「このトークンは有効で、サービスアカウントXと名前空間Yに属する」と返答することで、VaultはPodを認証し、Vaultのトークンを発行するという安全な認証フローが実現する。

認証が確立されたら、次に「Vaultポリシー」を定義する。ポリシーは、どのユーザーやアプリケーションがVault内のどのパスにある機密情報に対して、どのような操作(読み取り、書き込み、削除など)を許可されるかを定めるルールセットである。Vaultは「デフォルトで何も許可しない」という原則に基づいているため、明示的にポリシーで許可しなければ、どのような操作も実行できない。例えば、secret/data/mysqlというパスにあるデータベースの認証情報に対して、読み取り、書き込み、削除を許可するといったルールを設定する。

そして「ロール」を作成する。ロールは、Kubernetesの特定のサービスアカウントや名前空間を持つPodを、特定のVaultポリシーに紐付ける役割を果たす。例えば、webapps名前空間内のvault-authというサービスアカウントを持つPodに、先ほど定義したmyapp-policyを適用する、といった設定を行う。これにより、そのサービスアカウントを持つPodだけが、myapp-policyで許可された操作をVaultに対して行えるようになる。

Vaultに機密情報を保存するには、KV V2エンジンを有効にしてから、vault kv putコマンドでパスとキーバリュー形式でデータを保存する。例えば、secret/mysqlというパスにデータベースのユーザー名とパスワードを保存する。

最後に、KubernetesのPodがVaultからこれらの機密情報を実際に利用する方法について説明する。HashiCorp Vaultには「Vault Agent Injector」という機能があり、これを利用すると、PodのYAML定義に特定のアノテーションを追加するだけで、Vaultから自動的に機密情報を取得し、Pod内のファイルとして配置できる。例えば、vault.hashicorp.com/agent-inject: "true"はインジェクターを有効にし、vault.hashicorp.com/role: "vault-role"は、そのPodがvault-roleというVaultのロールを使って認証することを示す。vault.hashicorp.com/agent-inject-secret-MYSQL_ROOT_PASSWORD: "secret/mysql"というアノテーションは、secret/mysqlというパスからシークレットを取得し、MYSQL_ROOT_PASSWORDという名前のファイルとしてPod内に配置するよう指示する。さらに、vault.hashicorp.com/agent-inject-template-MYSQL_ROOT_PASSWORDというアノテーションでは、Goテンプレートを使って、そのファイルに書き込む内容を自由にカスタマイズできる。例えば、export MYSQL_ROOT_PASSWORD="{{ .Data.data.MYSQL_ROOT_PASSWORD }}"のように指定すれば、環境変数として設定するシェルスクリプトの形式で、Vaultから取得したパスワードをファイルに書き込むことができる。

このように設定されたPodが起動すると、サイドカーコンテナとして動作するVault Agentが、Podのサービスアカウントトークンを使ってVaultに認証し、指定された機密情報をフェッチし、Pod内の/vault/secrets/ディレクトリにファイルとして書き込む。アプリケーションは、このファイルから必要な機密情報を読み取ることで、安全にデータベースなどに接続できるようになる。

VaultとKubernetesを連携させることで、機密情報の管理が大幅に改善される。開発者はコード内に機密情報をハードコーディングするリスクから解放され、運用者は機密情報の一元的な管理と厳密なアクセス制御を実現できる。これは、現代のクラウドネイティブなアプリケーション開発において、セキュリティを確保するための非常に強力なソリューションとなる。

関連コンテンツ

【ITニュース解説】🔐Vault With Kubernetes | いっしー@Webエンジニア