AKSとAzure Key VaultによるSecret管理
コンテナ化されたアプリケーションにおいて、データベースの接続文字列、APIキー、証明書などの機密情報(Secret)を安全に管理することは非常に重要です。Azure Kubernetes Service (AKS) では、Azure Key Vault と連携することで、堅牢かつスケーラブルなSecret管理を実現できます。
なぜAzure Key Vaultを使うのか?
Kubernetes標準の Secret リソースは、デフォルトではetcd内にBase64エンコードされた状態で保存されるだけです(暗号化設定も可能ですが、管理が必要です)。Azure Key Vaultを使用することで以下のメリットが得られます。
- 一元管理: アプリケーションの機密情報をAzureのマネージドサービスで集中管理できます。
- アクセス制御: Azure RBACやアクセスポリシーを使用して、誰が(どのアプリが)どのSecretにアクセスできるかを細かく制御できます。
- 監査ログ: Secretへのアクセス履歴をログとして記録・監視できます。
- ライフサイクル管理: 証明書の自動更新やSecretのローテーション機能を利用できます。
推奨される実装方法: Secrets Store CSI Driver
現在、AKSでAzure Key Vaultを利用する際の標準的かつ推奨される方法は、Azure Key Vault Provider for Secrets Store CSI Driver を使用することです。
仕組み
このドライバは、Azure Key Vault内のSecret、Key、CertificateをCSI(Container Storage Interface)ボリュームとしてPodにマウントします。
- マウント: Pod起動時にKey VaultからSecretを取得し、Pod内のファイルシステムにファイルとしてマウントします。
- 同期 (Sync): オプションで、マウントされたSecretをKubernetesのネイティブ
Secretリソースとして同期することも可能です(環境変数として利用したい場合などに有効)。
認証: Microsoft Entra Workload ID
Key Vaultへのアクセス認証には、Microsoft Entra Workload ID(旧称: Azure AD Workload Identity)の使用が強く推奨されます。これにより、KubernetesのService AccountとAzureのManaged Identityを連携させ、パスワードレスで安全にKey Vaultへアクセスできます。
実装ステップの概要
- AKSクラスタでCSI DriverとWorkload Identityを有効化:
az aks update -n <cluster-name> -g <resource-group> --enable-secret-rotation --enable-oidc-issuer --enable-workload-identity
- Azure Key VaultとSecretの作成: 必要な機密情報をKey Vaultに格納します。
- Managed Identityの作成と権限付与:
Key Vaultへのアクセス権(例:
Key Vault Secrets User)を持つManaged Identityを作成します。 - Service AccountとFederated Credentialの設定: KubernetesのService Accountを作成し、AzureのManaged Identityと紐付けます。
- SecretProviderClassの作成:
どのKey VaultからどのSecretを取得するかを定義するYAMLを作成します。
apiVersion: secrets-store.csi.x-k8s.io/v1kind: SecretProviderClassmetadata:name: azure-kv-namespec:provider: azureparameters:usePodIdentity: "false"useVMManagedIdentity: "false"clientID: "<managed-identity-client-id>"keyvaultName: "<key-vault-name>"objects: |array:- |objectName: db-passwordobjectType: secrettenantId: "<tenant-id>"
- Podへのマウント:
Deploymentのマニフェストで
volumesとvolumeMountsを定義し、SecretProviderClassを参照します。
ベストプラクティス
1. Workload Identityを使用する
従来のPod IdentityやService Principal(Client Secret)の使用は避け、Workload Identityを使用してください。これにより、クレデンシャルの管理負荷と漏洩リスクを最小限に抑えられます。
2. 最小権限の原則 (Least Privilege)
Managed Identityには、必要なKey Vaultに対する必要な権限(読み取り専用など)のみを付与してください。Azure RBACを使用する場合、Key Vault Secrets User ロールなどが適切です。
3. 自動ローテーションの有効化
Secrets Store CSI Driverの自動ローテーション機能(--enable-secret-rotation)を有効にすることで、Key Vault側でSecretが更新された際、定期的にPod内のマウント内容やKubernetes Secretを更新できます。
- 注意: 環境変数として読み込んでいる場合、Podの再起動が必要になることがあります(reloader などのツールと組み合わせると自動化可能です)。
4. GitOpsとの共存
Gitリポジトリ(Helmチャートやマニフェスト)には、機密情報そのものを絶対にコミットしないでください。代わりに SecretProviderClass の定義(Secretの名前やKey Vault名などのメタデータ)のみを管理します。これにより、GitOpsのプラクティスを守りつつ、機密情報を安全に分離できます。
5. Kubernetes Secretへの同期は必要最小限に
CSI Driverの secretObjects 機能を使ってKubernetes Secretに同期するのは、環境変数として利用する必要がある場合や、Ingressコントローラーで証明書を利用する場合などに限定することを推奨します。ファイルマウントだけで十分な場合は、同期しない方がetcdへの書き込みを減らし、セキュリティリスクを低減できます。