メインコンテンツまでスキップ

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にマウントします。

  1. マウント: Pod起動時にKey VaultからSecretを取得し、Pod内のファイルシステムにファイルとしてマウントします。
  2. 同期 (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へアクセスできます。

実装ステップの概要

  1. AKSクラスタでCSI DriverとWorkload Identityを有効化:
    az aks update -n <cluster-name> -g <resource-group> --enable-secret-rotation --enable-oidc-issuer --enable-workload-identity
  2. Azure Key VaultとSecretの作成: 必要な機密情報をKey Vaultに格納します。
  3. Managed Identityの作成と権限付与: Key Vaultへのアクセス権(例: Key Vault Secrets User)を持つManaged Identityを作成します。
  4. Service AccountとFederated Credentialの設定: KubernetesのService Accountを作成し、AzureのManaged Identityと紐付けます。
  5. SecretProviderClassの作成: どのKey VaultからどのSecretを取得するかを定義するYAMLを作成します。
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
    name: azure-kv-name
    spec:
    provider: azure
    parameters:
    usePodIdentity: "false"
    useVMManagedIdentity: "false"
    clientID: "<managed-identity-client-id>"
    keyvaultName: "<key-vault-name>"
    objects: |
    array:
    - |
    objectName: db-password
    objectType: secret
    tenantId: "<tenant-id>"
  6. Podへのマウント: Deploymentのマニフェストで volumesvolumeMounts を定義し、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への書き込みを減らし、セキュリティリスクを低減できます。