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 からプロビジョニングされた 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 を使用する必要があります。

ヒント

Azure からプロビジョニングされた AKS ハイブリッド クラスターでこの拡張機能を使用する場合は、provisionedClusters を使用するように --cluster-type を設定し、また、--cluster-resource-provider microsoft.hybridcontainerservice をコマンドに追加する必要があります。 Azure からプロビジョニングされた AKS ハイブリッド クラスターへの Azure Arc 拡張機能のインストールは、現在プレビュー中です。

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

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

ヒント

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

ヒント

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

Azure portal

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

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

    Azure portal での Arc 対応 Kubernetes クラスターの [拡張機能] ページを示したスクリーンショット。

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

    Azure portal での Azure Key Vault シークレット プロバイダー拡張機能のスクリーンショット。

  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 がまだない場合は、次のコマンドを使用して新しく作成します。 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. こちらの手順に従って、作成したサービス プリンシパルに Azure Key Vault GET アクセス許可を付与します。

  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>
        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
    
  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 2m 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 シークレット プロバイダー拡張機能が表示されません。 クラスターにインストールされている拡張機能が他にない場合は、空の配列が表示されます。

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

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

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

次のステップ

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