Verwenden der Azure Key Vault-Erweiterung „Secrets Provider“ zum Abrufen von Geheimnissen in Azure Arc-fähige Kubernetes-Cluster

Der Secrets Store CSI-Treiber für Kubernetes ermöglicht, Azure Key Vault über ein CSI-Volume als Geheimnisspeicher in einen Kubernetes-Cluster zu integrieren. Für Azure Arc-fähige Kubernetes-Cluster können Sie die Azure Key Vault-Erweiterung „Secrets Provider“ installieren, um Geheimnisse abzurufen.

Funktionen der Azure Key Vault-Erweiterung „Secrets Provider“:

  • Einbinden von Geheimnissen/Schlüsseln/Zertifikaten in Pods mithilfe eines CSI-Inlinevolumes
  • Unterstützung der Podportabilität mit der SecretProviderClass-CRD
  • Unterstützt Linux- und Windows-Container.
  • Unterstützt Synchronisierung mit Kubernetes-Geheimnissen.
  • Unterstützt automatische Rotation von Geheimnissen.
  • Erweiterungskomponenten werden in Verfügbarkeitszonen bereitgestellt, wodurch diese zonenredundant werden.

Voraussetzungen

  • Ein Cluster mit einer unterstützten Kubernetes-Distribution, die bereits mit Azure Arc verbunden wurde. Derzeit werden für dieses Szenario die folgenden Kubernetes-Distributionen unterstützt:
    • Cluster API Azure
    • Azure Kubernetes Service-Cluster (AKS) unter Azure Stack HCI
    • AKS mit Azure Arc-Unterstützung
    • Google Kubernetes Engine
    • OpenShift Kubernetes-Verteilung
    • Canonical Kubernetes-Verteilung
    • Elastic Kubernetes Service (EKS)
    • Tanzu Kubernetes Grid
    • Azure Red Hat OpenShift
  • Stellen Sie sicher, dass Sie die allgemeinen Voraussetzungen für Clustererweiterungen erfüllt haben. Sie müssen mindestens Version 0.4.0 der Azure CLI-Erweiterung k8s-extension verwenden.

Installieren der Azure Key Vault-Erweiterung „Secrets Provider“ in einem Arc-fähigen Kubernetes-Cluster

Sie können die Azure Key Vault-Erweiterung „Secrets Provider“ in Ihrem verbundenen Cluster im Azure-Portal installieren, indem Sie die Azure CLI verwenden oder eine ARM-Vorlage bereitstellen.

In jedem Azure Arc-fähigen Kubernetes-Cluster kann nur eine Instanz der Erweiterung bereitgestellt werden.

Tipp

Wenn sich der Cluster hinter einem ausgehenden Proxyserver befindet, stellen Sie sicher, dass Sie ihn über die Option Proxykonfiguration mit Azure Arc verbinden, bevor Sie die Erweiterung installieren.

Azure-Portal

  1. Navigieren Sie im Azure-Portal zu Kubernetes – Azure Arc, und wählen Sie Ihren Cluster aus.

  2. Wählen Sie Erweiterungen unter Einstellungen und dann + Hinzufügen aus.

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

  3. Wählen Sie in der Liste der verfügbaren Erweiterungen den Azure Key Vault Secrets Provider aus, um die neueste Version der Erweiterung bereitzustellen.

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

  4. Befolgen Sie die Anweisungen zum Bereitstellen der Erweiterung. Passen Sie bei Bedarf die Installation an, indem Sie die Standardoptionen auf der Registerkarte Konfiguration ändern.

Azure CLI

  1. Legen Sie die folgenden Umgebungsvariablen fest:

    export CLUSTER_NAME=<arc-cluster-name>
    export RESOURCE_GROUP=<resource-group-name>
    
  2. Installieren Sie den Secrets Store CSI Driver und die Azure Key Vault-Erweiterung „Secrets Provider“, indem Sie den folgenden Befehl ausführen:

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

Die Ausgabe sollte folgendem Beispiel entsprechen. Es kann mehrere Minuten dauern, ehe das Helm-Diagramm von „Secrets Provider“ im Cluster bereitgestellt wird.

{
  "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-Vorlage

  1. Erstellen Sie eine JSON-Datei mit folgendem Format. Ändern Sie unbedingt den Wert <cluster-name> so, dass er auf Ihren Cluster verweist.

    {
        "$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. Legen Sie nun die Umgebungsvariablen mithilfe des folgenden Azure CLI-Befehls fest:

    export TEMPLATE_FILE_NAME=<template-file-path>
    export DEPLOYMENT_NAME=<desired-deployment-name>
    
  3. Führen Sie schließlich diesen Azure CLI-Befehl aus, um die Azure Key Vault-Erweiterung „Secrets Provider“ zu installieren:

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

Sie sollten nun in der Lage sein, die geheimen Ressourcen von „Secrets Provider“ anzuzeigen und die Erweiterung in Ihrem Cluster zu verwenden.

Überprüfen der Installation der Erweiterung

Führen Sie den folgenden Befehl aus, um die erfolgreiche Installation der Azure Key Vault-Erweiterung „Secrets Provider“ zu bestätigen.

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

Die Ausgabe sollte folgendem Beispiel entsprechen.

{
  "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"
}

Erstellen oder Auswählen einer Azure Key Vault-Instanz

Geben Sie als Nächstes die Azure Key Vault-Instanz an, die mit Ihrem verbundenen Cluster verwendet werden soll. Wenn Sie noch keine haben, erstellen Sie mithilfe der folgenden Befehle eine neue Key Vault-Instanz. Beachten Sie, dass der Name Ihrer Key Vault-Instanz global eindeutig sein muss.

Legen Sie die folgenden Umgebungsvariablen fest:

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

Führen Sie dann den folgenden Befehl aus:

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

Azure Key Vault kann Schlüssel, Geheimnisse und Zertifikate speichern. Für dieses Beispiel können Sie mit dem folgenden Befehl ein Geheimnis in Klartext namens DemoSecret festlegen:

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

Bevor Sie zum nächsten Abschnitt wechseln, beachten Sie die folgenden Eigenschaften:

  • Name des Geheimnisobjekts in Key Vault
  • Objekttyp (Geheimnis, Schlüssel oder Zertifikat)
  • Name Ihrer Key Vault-Ressource
  • Die Azure-Mandanten-ID des Abonnements, zu dem die Key Vault-Instanz gehört

Bereitstellen einer Identität für den Zugriff auf Azure Key Vault

Derzeit kann auf den Secrets Store CSI Driver in Arc-fähigen Clustern über einen Dienstprinzipal zugegriffen werden. Führen Sie diese Schritte aus, um eine Identität für den Zugriff auf Ihre Key Vault-Instanz anzugeben.

  1. Führen Sie diese Schritte aus, um einen Dienstprinzipal in Azure zu erstellen. Notieren Sie sich die Client-ID und den geheimen Clientschlüssel, die in diesem Schritt generiert werden.

  2. Stellen Sie als Nächstes sicher, dass Azure Key Vault über die Berechtigung GET f+r den erstellten Dienstprinzipal verfügt.

  3. Verwenden Sie die Client-ID und den geheimen Clientschlüssel aus dem ersten Schritt, um ein Kubernetes-Geheimnis im mit Arc verbundenen Cluster zu erstellen:

    kubectl create secret generic secrets-store-creds --from-literal clientid="<client-id>" --from-literal clientsecret="<client-secret>"
    
  4. Bezeichnen Sie das erstellte Geheimnis:

    kubectl label secret secrets-store-creds secrets-store.csi.k8s.io/used=true
    
  5. Erstellen Sie eine SecretProviderClass mit dem folgenden YAML-Code, und geben Sie die Werte für den Schlüsseltresornamen, die Mandanten-ID und die Objekte an, die Sie aus Ihrer AKV-Instanz abrufen möchten:

    # 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
    

    Für die Verwendung mit nationalen Clouds ändern Sie cloudName in AzureUSGovernmentCloud für Azure Government oder in AzureChinaCloud für Microsoft Azure, betrieben von 21Vianet.

  6. Wenden Sie die SecretProviderClass auf Ihren Cluster an:

    kubectl apply -f secretproviderclass.yaml
    
  7. Erstellen Sie einen Pod mit folgendem YAML-Code, und geben Sie dabei den Namen Ihrer Identität ein:

    # 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. Wenden Sie den Pod auf Ihren Cluster an:

    kubectl apply -f pod.yaml
    

Überprüfen der Geheimnisse

Nachdem der Pod gestartet wurde, ist der eingebundene Inhalt unter dem in Ihrer Bereitstellungs-YAML angegebenen Volumepfad verfügbar.

## 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

Zusätzliche Konfigurationsoptionen

Die Azure Key Vault Secrets Provider-Erweiterung unterstützt Helm-Diagrammkonfigurationen.

Die folgenden Konfigurationseinstellungen werden häufig für die Azure Key Vault-Erweiterung „Secrets Provider“ verwendet:

Konfigurationseinstellung Standard Beschreibung
enableSecretRotation false Boolescher Typ. Falls true, erfolgt ein regelmäßiges Aktualisieren der Einbindung des Pods und des Kubernetes-Geheimnisses mit dem neuesten Inhalt aus dem externen Geheimnisspeicher.
rotationPollInterval 2 m Diese Einstellung gibt die Dauer des Abrufintervalls für die Geheimnisrotation an, wenn enableSecretRotation gleich true ist. Diese Dauer kann basierend darauf angepasst werden, wie häufig die eingebundenen Inhalte für alle Pods und Kubernetes-Geheimnisse auf den neuesten Stand synchronisiert werden müssen.
syncSecret.enabled false Boolesche Eingabe. Unter Umständen können Sie ein Kubernetes-Geheimnis erstellen, um den bereitgestellten Inhalt zu spiegeln. Falls true, erlaubt SecretProviderClass dem Feld secretObjects, den gewünschten Status der synchronisierten Kubernetes-Geheimnisobjekte festzulegen.

Diese Einstellungen können bei Installation der Erweiterung mit dem Befehl az k8s-extension create festgelegt werden:

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

Sie können diese Einstellungen auch nach der Installation mit dem Befehl „az k8s-extension update“ ändern:

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

Sie können bei Bedarf andere Konfigurationseinstellungen für Ihre Bereitstellung verwenden. Um beispielsweise das Kubelet-Stammverzeichnis beim Erstellen eines Clusters zu ändern, ändern Sie den Befehl 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

Deinstallieren der Azure Key Vault-Erweiterung „Secrets Provider“

Führen Sie zum Deinstallieren der Erweiterung den folgenden Befehl aus:

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

Hinweis

Bei der Deinstallation der Erweiterung werden die benutzerdefinierten Ressourcendefinitionen (Custom Resource Definitions, CRDs), die bei Installation der Erweiterung erstellt wurden, nicht gelöscht.

Um zu bestätigen, dass die Erweiterungsinstanz gelöscht wurde, führen Sie den folgenden Befehl aus:

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

Wenn die Erweiterung erfolgreich entfernt wurde, wird die in der Ausgabe aufgeführte Azure Key Vault-Erweiterung „Secrets Provider“ nicht angezeigt. Wenn Sie keine anderen Erweiterungen in Ihrem Cluster installiert haben, sehen Sie nur ein leeres Array.

Wenn Sie das dem Dienstprinzipal zugeordnete Kubernetes-Geheimnis nicht mehr benötigen, müssen Sie es mit folgendem Befehl löschen:

kubectl delete secret secrets-store-creds

Zurücksetzung und Problembehandlung

Die Azure Key Vault-Erweiterung „Secrets Provider“ ist selbstreparierend. Wenn jemand versucht, eine Erweiterungskomponente zu ändern oder zu löschen, die bei der Installation der Erweiterung bereitgestellt war, wird diese Komponente in ihrem ursprünglichen Zustand zurückgesetzt. Die einzigen Ausnahmen gelten für benutzerdefinierte Ressourcendefinitionen (CRDs). Wenn CRDs gelöscht werden, werden sie nicht zurückgesetzt. Um gelöschte CRDs wiederherzustellen, führen Sie erneut den Befehl az k8s-extension create mit dem vorhandenen Instanznamen der Erweiterung aus.

Weitere Informationen zur Behebung gängiger Probleme finden Sie in den Open-Source-Anleitungen zur Problembehandlung für Azure Key Vault Provider for Secrets Store CSI Driver und Secrets Store CSI Driver.

Nächste Schritte