Azure Key Vault シークレット プロバイダー拡張機能を使用して、Azure Arc 対応 Kubernetes クラスターにシークレットをフェッチする

シークレット ストア CSI ドライバーに Azure Key Vault プロバイダーを使用すると、CSI ボリューム経由で Azure Key Vault をシークレット ストアとして Kubernetes クラスターと統合できます。 Azure Arc 対応 Kubernetes クラスターに対して、Azure Key Vault シークレット プロバイダー拡張機能をインストールしてシークレットをフェッチできます。

Azure Key Vault シークレット プロバイダー拡張機能の機能には、次のようなものがあります。

  • CSI Inline ボリュームを使用して、シークレット、キー、証明書がポッドにマウントされます
  • SecretProviderClass CRD によるポッド移植性がサポートされています
  • Linux および Windows コンテナーがサポートされています
  • Kubernetes シークレットとの同期がサポートされています
  • シークレットの自動ローテーションがサポートされています
  • 拡張機能コンポーネントは可用性ゾーンにデプロイされ、ゾーン冗長になります

前提条件

  • Azure Arc に既に接続されている、サポートされている Kubernetes ディストリビューションを持つクラスター。現在、このシナリオでは、次の Kubernetes ディストリビューションがサポートされています。
    • Cluster API Azure
    • Azure Stack HCI 上の Azure Kubernetes Service (AKS) クラスター
    • Azure Arc によって有効にされる AKS
    • Google Kubernetes Engine
    • OpenShift Kubernetes Distribution
    • Canonical Kubernetes Distribution
    • Elastic Kubernetes Service
    • Tanzu Kubernetes Grid
    • Azure Red Hat OpenShift
  • クラスター拡張機能の一般的な前提条件を満たしていることを確認します。 バージョン 0.4.0 以降の k8s-extension Azure CLI を使用する必要があります。

Arc 対応 Kubernetes クラスターに Azure Key Vault シークレット プロバイダー拡張機能をインストールする

Azure portal で、Azure CLI を使用して、または ARM テンプレートをデプロイすることで、接続されたクラスターに Azure Key Vault シークレット プロバイダー拡張機能をインストールできます。

Azure Arc 対応 Kubernetes クラスターごとにデプロイできる拡張機能のインスタンスは 1 つだけです。

ヒント

クラスターが送信プロキシ サーバーの背後にある場合は、拡張機能をインストールする前に、プロキシ構成オプションを使用して Azure Arc に接続してください。

Azure portal

  1. Azure portal で、[Kubernetes - Azure Arc] に移動し、クラスターを選択します。

  2. [拡張機能] ([設定] の下) を選択してから、[+ 追加] を選びます。

    Screenshot showing the Extensions page for an Arc-enabled Kubernetes cluster in the Azure portal.

  3. 使用可能な拡張機能の一覧から、Azure Key Vault シークレット プロバイダーを選択して、最新バージョンの拡張機能をデプロイします。

    Screenshot of the Azure Key Vault Secrets Provider extension in the Azure portal.

  4. プロンプトに従って、拡張機能をデプロイします。 必要に応じて、[構成] タブで既定のオプションを変更して、インストールをカスタマイズします。

Azure CLI

  1. 環境変数を設定します。

    export CLUSTER_NAME=<arc-cluster-name>
    export RESOURCE_GROUP=<resource-group-name>
    
  2. 次のコマンドを実行して、シークレット ストア CSI ドライバーと Azure Key Vault シークレット プロバイダー拡張機能をインストールします。

    az k8s-extension create --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --cluster-type connectedClusters --extension-type Microsoft.AzureKeyVaultSecretsProvider --name akvsecretsprovider
    

次の例のような出力が表示されます。 シークレット プロバイダーの Helm chart がクラスターにデプロイされるまでに数分かかる場合があります。

{
  "aksAssignedIdentity": null,
  "autoUpgradeMinorVersion": true,
  "configurationProtectedSettings": {},
  "configurationSettings": {},
  "customLocationSettings": null,
  "errorInfo": null,
  "extensionType": "microsoft.azurekeyvaultsecretsprovider",
  "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Kubernetes/connectedClusters/$CLUSTER_NAME/providers/Microsoft.KubernetesConfiguration/extensions/akvsecretsprovider",
  "identity": {
    "principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "tenantId": null,
    "type": "SystemAssigned"
  },
  "location": null,
  "name": "akvsecretsprovider",
  "packageUri": null,
  "provisioningState": "Succeeded",
  "releaseTrain": "Stable",
  "resourceGroup": "$RESOURCE_GROUP",
  "scope": {
    "cluster": {
      "releaseNamespace": "kube-system"
    },
    "namespace": null
  },
  "statuses": [],
  "systemData": {
    "createdAt": "2022-05-12T18:35:56.552889+00:00",
    "createdBy": null,
    "createdByType": null,
    "lastModifiedAt": "2022-05-12T18:35:56.552889+00:00",
    "lastModifiedBy": null,
    "lastModifiedByType": null
  },
  "type": "Microsoft.KubernetesConfiguration/extensions",
  "version": "1.1.3"
}

ARM テンプレート

  1. 次の形式を使用して .json ファイルを作成します。 必ず <cluster-name> の値を更新して、お使いのクラスターを参照してください。

    {
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
            "ConnectedClusterName": {
                "defaultValue": "<cluster-name>",
                "type": "String",
                "metadata": {
                    "description": "The Connected Cluster name."
                }
            },
            "ExtensionInstanceName": {
                "defaultValue": "akvsecretsprovider",
                "type": "String",
                "metadata": {
                    "description": "The extension instance name."
                }
            },
            "ExtensionVersion": {
                "defaultValue": "",
                "type": "String",
                "metadata": {
                    "description": "The version of the extension type."
                }
            },
            "ExtensionType": {
                "defaultValue": "Microsoft.AzureKeyVaultSecretsProvider",
                "type": "String",
                "metadata": {
                    "description": "The extension type."
                }
            },
            "ReleaseTrain": {
                "defaultValue": "stable",
                "type": "String",
                "metadata": {
                    "description": "The release train."
                }
            }
        },
        "functions": [],
        "resources": [
            {
                "type": "Microsoft.KubernetesConfiguration/extensions",
                "apiVersion": "2021-09-01",
                "name": "[parameters('ExtensionInstanceName')]",
                "identity": {
                 "type": "SystemAssigned"
                },
                "properties": {
                    "extensionType": "[parameters('ExtensionType')]",
                    "releaseTrain": "[parameters('ReleaseTrain')]",
                    "version": "[parameters('ExtensionVersion')]"
                },
                "scope": "[concat('Microsoft.Kubernetes/connectedClusters/', parameters('ConnectedClusterName'))]"
            }
        ]
    }
    
  2. 次の Azure CLI コマンドを使用して環境変数を設定します。

    export TEMPLATE_FILE_NAME=<template-file-path>
    export DEPLOYMENT_NAME=<desired-deployment-name>
    
  3. 最後に、次の Azure CLI コマンドを実行して、Azure Key Vault シークレット プロバイダー拡張機能をインストールします。

    az deployment group create --name $DEPLOYMENT_NAME --resource-group $RESOURCE_GROUP --template-file $TEMPLATE_FILE_NAME
    

これで、シークレット プロバイダーのリソースを表示して、拡張機能をクラスターで使用できるようになります。

拡張機能のインストールを検証する

Azure Key Vault シークレット プロバイダー拡張機能の正常なインストールを確認するには、次のコマンドを実行します。

az k8s-extension show --cluster-type connectedClusters --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --name akvsecretsprovider

次の例のような出力が表示されます。

{
  "aksAssignedIdentity": null,
  "autoUpgradeMinorVersion": true,
  "configurationProtectedSettings": {},
  "configurationSettings": {},
  "customLocationSettings": null,
  "errorInfo": null,
  "extensionType": "microsoft.azurekeyvaultsecretsprovider",
  "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Kubernetes/connectedClusters/$CLUSTER_NAME/providers/Microsoft.KubernetesConfiguration/extensions/akvsecretsprovider",
  "identity": {
    "principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "tenantId": null,
    "type": "SystemAssigned"
  },
  "location": null,
  "name": "akvsecretsprovider",
  "packageUri": null,
  "provisioningState": "Succeeded",
  "releaseTrain": "Stable",
  "resourceGroup": "$RESOURCE_GROUP",
  "scope": {
    "cluster": {
      "releaseNamespace": "kube-system"
    },
    "namespace": null
  },
  "statuses": [],
  "systemData": {
    "createdAt": "2022-05-12T18:35:56.552889+00:00",
    "createdBy": null,
    "createdByType": null,
    "lastModifiedAt": "2022-05-12T18:35:56.552889+00:00",
    "lastModifiedBy": null,
    "lastModifiedByType": null
  },
  "type": "Microsoft.KubernetesConfiguration/extensions",
  "version": "1.1.3"
}

Azure Key Vault を作成または選択する

次に、接続されているクラスターで使用する Azure Key Vault を指定します。 Key Vault がまだない場合は、次のコマンドを使用して新しく作成します。 キー コンテナーの名前はグローバルに一意である必要があることに注意してください。

以下の環境変数を設定します。

export AKV_RESOURCE_GROUP=<resource-group-name>
export AZUREKEYVAULT_NAME=<AKV-name>
export AZUREKEYVAULT_LOCATION=<AKV-location>

次に、以下のコマンドを実行します。

az keyvault create -n $AZUREKEYVAULT_NAME -g $AKV_RESOURCE_GROUP -l $AZUREKEYVAULT_LOCATION

Azure Key Vault では、キー、シークレット、証明書を格納できます。 この例では、次のコマンドを使用して、DemoSecret という名前のプレーン テキスト シークレットを設定できます。

az keyvault secret set --vault-name $AZUREKEYVAULT_NAME -n DemoSecret --value MyExampleSecret

次のセクションに進む前に、次のプロパティをメモしておきます。

  • Key Vault 内のシークレット オブジェクトの名前
  • オブジェクトの種類 (シークレット、キー、または証明書)
  • Key Vault リソースの名前
  • Key Vault が属するサブスクリプションの Azure テナント ID

Azure Key Vault にアクセスするために ID を提供する

現時点では、Arc 対応クラスターのシークレット ストア CSI ドライバーには、サービス プリンシパルを介してアクセスできます。 次の手順に従って、Key Vault にアクセスできる ID を指定します。

  1. Azure 内でサービス プリンシパルを作成するための手順に従います。 この手順で生成されたクライアント ID とクライアント シークレットをメモしておきます。

  2. 次に、作成したサービス プリンシパルの GET アクセス許可が Azure Key Vault に付与されていることを確認します

  3. 最初の手順のクライアント ID とクライアント シークレットを使用して、接続されたクラスター上で Kubernetes シークレットを作成します。

    kubectl create secret generic secrets-store-creds --from-literal clientid="<client-id>" --from-literal clientsecret="<client-secret>"
    
  4. 作成したシークレットにラベルを付けます。

    kubectl label secret secrets-store-creds secrets-store.csi.k8s.io/used=true
    
  5. 次の YAML を使用して SecretProviderClass を作成し、AKV インスタンスから取得するキー コンテナー名、テナント ID、オブジェクトの値を入力します。

    # This is a SecretProviderClass example using service principal to access Keyvault
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: akvprovider-demo
    spec:
      provider: azure
      parameters:
        usePodIdentity: "false"
        keyvaultName: <key-vault-name>
        cloudName:                           # Defaults to AzurePublicCloud
        objects:  |
          array:
            - |
              objectName: DemoSecret
              objectType: secret             # object types: secret, key or cert
              objectVersion: ""              # [OPTIONAL] object versions, default to latest if empty
        tenantId: <tenant-Id>                # The tenant ID of the Azure Key Vault instance
    

    各国のクラウドを使用するには、cloudName を、Azure Government の場合は AzureUSGovernmentCloud に、21Vianet によって運営される Microsoft Azure の場合は AzureChinaCloud に変更します。

  6. クラスターに SecretProviderClass を適用します。

    kubectl apply -f secretproviderclass.yaml
    
  7. 次の YAML を使用してポッドを作成し、ID の名前を入力します。

    # This is a sample pod definition for using SecretProviderClass and service principal to access Keyvault
    kind: Pod
    apiVersion: v1
    metadata:
      name: busybox-secrets-store-inline
    spec:
      containers:
        - name: busybox
          image: k8s.gcr.io/e2e-test-images/busybox:1.29
          command:
            - "/bin/sleep"
            - "10000"
          volumeMounts:
          - name: secrets-store-inline
            mountPath: "/mnt/secrets-store"
            readOnly: true
      volumes:
        - name: secrets-store-inline
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: "akvprovider-demo"
            nodePublishSecretRef:                       
              name: secrets-store-creds
    
  8. ポッドをクラスターに適用します。

    kubectl apply -f pod.yaml
    

シークレットを検証する

ポッドが起動すると、デプロイ YAML で指定されたボリューム パスにマウントされたコンテンツが使用できるようになります。

## show secrets held in secrets-store
kubectl exec busybox-secrets-store-inline -- ls /mnt/secrets-store/

## print a test secret 'DemoSecret' held in secrets-store
kubectl exec busybox-secrets-store-inline -- cat /mnt/secrets-store/DemoSecret

追加の構成オプション

Azure Key Vault シークレット プロバイダー拡張機能では、Helm チャートの構成がサポートされています。

Azure Key Vault シークレット プロバイダー拡張機能では、次の構成設定が頻繁に使われます。

構成設定 Default 説明
enableSecretRotation false ブール型。 true の場合、外部シークレット ストアからの最新のコンテンツを使用して、ポッド マウントと Kubernetes シークレットを定期的に更新します
rotationPollInterval 2 m enableSecretRotationtrue の場合、この設定は、シークレット ローテーションのポーリング間隔の期間を指定します。 この期間は、すべてのポッドのマウントされたコンテンツと Kubernetes シークレットを最新のものに再同期する必要がある頻度に基づいて調整できます。
syncSecret.enabled false ブール値の入力。 場合によっては、マウントされたコンテンツをミラー化するために Kubernetes シークレットを作成できます。 true の場合、SecretProviderClass では secretObjects フィールドで、同期された Kubernetes シークレット オブジェクトの目的の状態を定義できます。

これらの設定は、az k8s-extension create コマンドを使用して拡張機能をインストールするときに指定できます。

az k8s-extension create --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --cluster-type connectedClusters --extension-type Microsoft.AzureKeyVaultSecretsProvider --name akvsecretsprovider --configuration-settings secrets-store-csi-driver.enableSecretRotation=true secrets-store-csi-driver.rotationPollInterval=3m secrets-store-csi-driver.syncSecret.enabled=true

また az k8s-extension update コマンドを使用して、インストール後にこれらの設定を変更することもできます。

az k8s-extension update --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --cluster-type connectedClusters --name akvsecretsprovider --configuration-settings secrets-store-csi-driver.enableSecretRotation=true secrets-store-csi-driver.rotationPollInterval=3m secrets-store-csi-driver.syncSecret.enabled=true

デプロイには、必要に応じて他の構成設定を使用できます。 たとえば、クラスターの作成時に kubelet ルート ディレクトリを変更するには、az k8s-extension create コマンドを変更します。

az k8s-extension create --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --cluster-type connectedClusters --extension-type Microsoft.AzureKeyVaultSecretsProvider --name akvsecretsprovider --configuration-settings linux.kubeletRootDir=/path/to/kubelet secrets-store-csi-driver.linux.kubeletRootDir=/path/to/kubelet

Azure Key Vault シークレット プロバイダー拡張機能をアンインストールする

拡張機能をアンインストールするには、次のコマンドを実行します。

az k8s-extension delete --cluster-type connectedClusters --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --name akvsecretsprovider

注意

拡張機能をアンインストールしても、拡張機能のインストール時に作成されたカスタム リソース定義 (CRD) は削除されません。

拡張機能インスタンスが削除されたことを確認するには、次のコマンドを実行します。

az k8s-extension list --cluster-type connectedClusters --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP

拡張機能が正常に削除されている場合、出力に Azure Key Vault シークレット プロバイダー拡張機能が表示されません。 クラスターにインストールされている拡張機能が他にない場合は、空の配列が表示されます。

不要になった場合は、次のコマンドを実行して、サービス プリンシパルに関連付けられている Kubernetes シークレットを確実に削除してください。

kubectl delete secret secrets-store-creds

調整とトラブルシューティング

Azure Key Vault シークレット プロバイダー拡張機能は自己復旧します。 拡張機能のインストール時にデプロイされた拡張機能コンポーネントを変更または削除しようとすると、そのコンポーネントは元の状態に調整されます。 唯一の例外は、カスタム リソース定義 (CRD) です。 CRD が削除された場合、それらは調整されません。 削除された CRD を復元するには、既存の拡張機能インスタンス名で az k8s-extension create コマンドをもう一度使用します。

一般的な問題の解決の詳細については、シークレット ストア CSI ドライバー用の Azure Key Vault プロバイダーシークレット ストア CSI ドライバーのオープンソース トラブルシューティング ガイドを参照してください。

次のステップ

  • さっそく試してみましょう。 Azure Arc Jumpstart の使用パターン (scenario) を参考に、Cluster API を使用して、すぐに作業を開始できます。
  • Azure Key Vault の詳細はこちらです。