Verbinden Ihres Azure-Identitätsanbieters mit dem Azure Key Vault Secrets Store-CSI-Treiber in Azure Kubernetes Service (AKS)

Der Secrets Store Container Storage Interface (CSI)-Treiber auf Azure Kubernetes Service (AKS) bietet verschiedene Methoden des identitätsbasierten Zugriffs auf Ihren Azure Key Vault. In diesem Artikel werden diese Methoden und Best Practices für die Verwendung von rollenbasierten Zugriffssteuerungsmodellen (RBAC) oder OpenID Connect (OIDC)-Sicherheitsmodellen für den Zugriff auf Ihren Schlüsseltresor und den AKS-Cluster beschrieben.

Sie können eine der folgenden Zugriffsmethoden verwenden:

Voraussetzungen für CSI-Treiber

Zugriff mit einer Microsoft Entra-Workload-ID

Eine Microsoft Entra Workload-ID ist eine Identität, die eine Anwendung, die auf einem Pod ausgeführt wird, um sich bei anderen Azure-Diensten zu authentifizieren, z. B. Workloads in Software. Der Secret Store CSI Driver lässt sich in die nativen Kubernetes-Funktionen integrieren, um sich mit externen Identitätsanbietern zu verbinden.

In diesem Sicherheitsmodell fungiert der AKS-Cluster als Tokenaussteller. Microsoft Entra ID verwendet dann OIDC, um öffentliche Signierschlüssel zu ermitteln und die Authentizität des Dienstkontotokens zu überprüfen, bevor es gegen ein Microsoft Entra-Token ausgetauscht wird. Damit Ihr Workload ein auf sein Volume projiziertes Dienstkonto-Token gegen ein Microsoft Entra-Token austauschen kann, benötigen Sie die Azure Identity-Client-Bibliothek im Azure SDK oder die Microsoft Authentication Library (MSAL)

Hinweis

  • Diese Authentifizierungsmethode ersetzt die vom Pod verwaltete Microsoft Entra-Identität (Vorschau). Die vom Pod verwaltete Open-Source-Microsoft Entra-Identität (Vorschau) im Azure Kubernetes Service wurde zum 24.10.2022 als veraltet markiert.
  • Microsoft Entra Workload ID unterstützt sowohl Windows- als auch Linux-Cluster.

Konfigurieren der Workloadidentität

  1. Legen Sie Ihr Abonnement mithilfe des Befehls az account set fest.

    export SUBSCRIPTION_ID=<subscription id>
    export RESOURCE_GROUP=<resource group name>
    export UAMI=<name for user assigned identity>
    export KEYVAULT_NAME=<existing keyvault name>
    export CLUSTER_NAME=<aks cluster name>
    
    az account set --subscription $SUBSCRIPTION_ID
    
  2. Erstellen Sie mithilfe des az identity create-Befehls eine verwaltete Identität.

    az identity create --name $UAMI --resource-group $RESOURCE_GROUP
    
    export USER_ASSIGNED_CLIENT_ID="$(az identity show -g $RESOURCE_GROUP --name $UAMI --query 'clientId' -o tsv)"
    export IDENTITY_TENANT=$(az aks show --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --query identity.tenantId -o tsv)
    
  3. Erstellen Sie eine Rollenzuweisung, die der Workloadidentität die Berechtigung erteilt, mithilfe des Befehls az role assignment create auf die Schlüsseltresorgeheimnisse, Zugriffsschlüssel und Zertifikate zuzugreifen.

    export KEYVAULT_SCOPE=$(az keyvault show --name $KEYVAULT_NAME --query id -o tsv)
    
    az role assignment create --role "Key Vault Administrator" --assignee $USER_ASSIGNED_CLIENT_ID --scope $KEYVAULT_SCOPE
    
  4. Rufen Sie die OIDC-Aussteller-URL des AKS-Clusters mit dem Befehl az aks show ab.

    Hinweis

    In diesem Schritt wird davon ausgegangen, dass Sie über einen vorhandenen AKS-Cluster mit aktivierter OIDC-Aussteller-URL verfügen. Wenn sie nicht aktiviert ist, lesen Sie Aktualisieren eines AKS-Clusters mit OIDC Issuer, um ihn zu aktivieren.

    export AKS_OIDC_ISSUER="$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "oidcIssuerProfile.issuerUrl" -o tsv)"
    echo $AKS_OIDC_ISSUER
    
  5. Erstellen Sie einen Verbundidentitätsnachweis zwischen der Microsoft Entra-Anwendung, dem Aussteller des Dienstkontos und dem Subjekt. Rufen Sie die Objekt-ID der Microsoft Entra-Anwendung mit den folgenden Befehlen ab. Aktualisieren Sie unbedingt die Werte für serviceAccountName und serviceAccountNamespace mit dem Namen des Kubernetes-Dienstkontos und seinem Namespace.

    export SERVICE_ACCOUNT_NAME="workload-identity-sa"  # sample name; can be changed
    export SERVICE_ACCOUNT_NAMESPACE="default" # can be changed to namespace of your workload
    
    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      annotations:
        azure.workload.identity/client-id: ${USER_ASSIGNED_CLIENT_ID}
      name: ${SERVICE_ACCOUNT_NAME}
      namespace: ${SERVICE_ACCOUNT_NAMESPACE}
    EOF
    
  6. Erstellen Sie die Verbundidentitäts-Anmeldeinformationen zwischen der verwalteten Identität, dem Dienstkontoaussteller und dem Antragsteller mithilfe des Befehls az identity federated-credential create.

    export FEDERATED_IDENTITY_NAME="aksfederatedidentity" # can be changed as needed
    
    az identity federated-credential create --name $FEDERATED_IDENTITY_NAME --identity-name $UAMI --resource-group $RESOURCE_GROUP --issuer ${AKS_OIDC_ISSUER} --subject system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}
    
  7. Stellen Sie eine SecretProviderClass mithilfe des Befehls kubectl apply und des folgenden YAML-Skripts bereit.

    cat <<EOF | kubectl apply -f -
    # This is a SecretProviderClass example using workload identity to access your key vault
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: azure-kvname-wi # needs to be unique per namespace
    spec:
      provider: azure
      parameters:
        usePodIdentity: "false"
        clientID: "${USER_ASSIGNED_CLIENT_ID}" # Setting this to use workload identity
        keyvaultName: ${KEYVAULT_NAME}       # Set to the name of your key vault
        cloudName: ""                         # [OPTIONAL for Azure] if not provided, the Azure environment defaults to AzurePublicCloud
        objects:  |
          array:
            - |
              objectName: secret1             # Set to the name of your secret
              objectType: secret              # object types: secret, key, or cert
              objectVersion: ""               # [OPTIONAL] object versions, default to latest if empty
            - |
              objectName: key1                # Set to the name of your key
              objectType: key
              objectVersion: ""
        tenantId: "${IDENTITY_TENANT}"        # The tenant ID of the key vault
    EOF
    

    Hinweis

    Wenn Sie objectAlias anstelle von objectName verwenden, aktualisieren Sie das YAML-Skript, um dies zu berücksichtigen.

    Hinweis

    Damit die SecretProviderClass Funktion ordnungsgemäß funktioniert, stellen Sie sicher, dass Sie Ihren Azure Key Vault mit geheimen Schlüsseln, Schlüsseln oder Zertifikaten auffüllen, bevor Sie sie im objects Abschnitt referenzieren.

  8. Stellen Sie einen Beispiel-Pod mithilfe des Befehls kubectl apply und des folgenden YAML-Skripts bereit.

    cat <<EOF | kubectl apply -f -
    # This is a sample pod definition for using SecretProviderClass and workload identity to access your key vault
    kind: Pod
    apiVersion: v1
    metadata:
      name: busybox-secrets-store-inline-wi
      labels:
        azure.workload.identity/use: "true"
    spec:
      serviceAccountName: "workload-identity-sa"
      containers:
        - name: busybox
          image: registry.k8s.io/e2e-test-images/busybox:1.29-4
          command:
            - "/bin/sleep"
            - "10000"
          volumeMounts:
          - name: secrets-store01-inline
            mountPath: "/mnt/secrets-store"
            readOnly: true
      volumes:
        - name: secrets-store01-inline
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: "azure-kvname-wi"
    EOF
    

Zugriff mit verwalteten Identitäten

Eine von Microsoft Entra verwaltete ID ist eine Identität, die ein Administrator zur Authentifizierung bei anderen Azure-Diensten verwendet. Die verwaltete Identität verwendet RBAC zum Verbund mit externen Identitätsanbietern.

In diesem Sicherheitsmodell können Sie den Zugriff auf Ihre Clusterressourcen für Teammitglieder oder Mandanten gewähren, die eine verwaltete Rolle teilen. Die Rolle wird auf den Bereich überprüft, um auf den KeyVault und andere Anmeldeinformationen zuzugreifen. Wenn Sie den Azure Key Vault Provider für den Secrets Store CSI-Treiber auf Ihrem AKS-Cluster aktiviert haben, wurde eine Benutzeridentität erstellt.

Konfigurieren einer verwalteten Identität

  1. Greifen Sie mithilfe des az aks show-Befehls und der vom Add-On erstellten vom Benutzer zugewiesenen verwalteten Identität auf Ihren Schlüsseltresor zu. Sie sollten auch die Identität clientId abrufen, die Sie bei der Erstellung einer SecretProviderClass-Identität in späteren Schritten verwenden werden.

    az aks show -g <resource-group> -n <cluster-name> --query addonProfiles.azureKeyvaultSecretsProvider.identity.objectId -o tsv
    az aks show -g <resource-group> -n <cluster-name> --query addonProfiles.azureKeyvaultSecretsProvider.identity.clientId -o tsv
    

    Alternativ können Sie mithilfe der folgenden Befehle eine neue verwaltete Identität erstellen und sie Ihrer VM-Skalierungsgruppen oder jeder VM-Instanz in Ihrer Verfügbarkeitsgruppen zuweisen.

    az identity create -g <resource-group> -n <identity-name>
    az vmss identity assign -g <resource-group> -n <agent-pool-vmss> --identities <identity-resource-id>
    az vm identity assign -g <resource-group> -n <agent-pool-vm> --identities <identity-resource-id>
    
    az identity show -g <resource-group> --name <identity-name> --query 'clientId' -o tsv
    
  2. Erstellen Sie eine Rollenzuweisung, die der Identitätsberechtigung Zugriff auf die Geheimnisse des Schlüsseltresors, die Zugriffsschlüssel und die Zertifikate gewährt, indem Sie den az role assignment create-Befehl verwenden.

    export IDENTITY_OBJECT_ID="$(az identity show -g <resource-group> --name <identity-name> --query 'principalId' -o tsv)"
    export KEYVAULT_SCOPE=$(az keyvault show --name <key-vault-name> --query id -o tsv)
    
    az role assignment create --role "Key Vault Administrator" --assignee $IDENTITY_OBJECT_ID --scope $KEYVAULT_SCOPE
    
  3. Erstellen Sie eine SecretProviderClass mit dem folgenden YAML-Code. Verwenden Sie unbedingt Ihre eigenen Werte für userAssignedIdentityID, keyvaultName, tenantId und die Objekte, die aus dem Schlüsseltresor abgerufen werden sollen.

    # This is a SecretProviderClass example using user-assigned identity to access your key vault
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: azure-kvname-user-msi
    spec:
      provider: azure
      parameters:
        usePodIdentity: "false"
        useVMManagedIdentity: "true"          # Set to true for using managed identity
        userAssignedIdentityID: <client-id>   # Set the clientID of the user-assigned managed identity to use
        keyvaultName: <key-vault-name>        # Set to the name of your key vault
        cloudName: ""                         # [OPTIONAL for Azure] if not provided, the Azure environment defaults to AzurePublicCloud
        objects:  |
          array:
            - |
              objectName: secret1
              objectType: secret              # object types: secret, key, or cert
              objectVersion: ""               # [OPTIONAL] object versions, default to latest if empty
            - |
              objectName: key1
              objectType: key
              objectVersion: ""
        tenantId: <tenant-id>                 # The tenant ID of the key vault
    

    Hinweis

    Wenn Sie objectAlias anstelle von objectName verwenden, müssen Sie das YAML-Skript aktualisieren.

    Hinweis

    Damit die SecretProviderClass Funktion ordnungsgemäß funktioniert, stellen Sie sicher, dass Sie Ihren Azure Key Vault mit geheimen Schlüsseln, Schlüsseln oder Zertifikaten auffüllen, bevor Sie sie im objects Abschnitt referenzieren.

  4. Wenden Sie die SecretProviderClass mithilfe des Befehls kubectl apply auf Ihren Cluster an.

    kubectl apply -f secretproviderclass.yaml
    
  5. Erstellen Sie einen Pod mithilfe des folgenden YAML-Codes.

    # This is a sample pod definition for using SecretProviderClass and the user-assigned identity to access your key vault
    kind: Pod
    apiVersion: v1
    metadata:
      name: busybox-secrets-store-inline-user-msi
    spec:
      containers:
        - name: busybox
          image: registry.k8s.io/e2e-test-images/busybox:1.29-4
          command:
            - "/bin/sleep"
            - "10000"
          volumeMounts:
          - name: secrets-store01-inline
            mountPath: "/mnt/secrets-store"
            readOnly: true
      volumes:
        - name: secrets-store01-inline
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: "azure-kvname-user-msi"
    
  6. Wenden Sie mithilfe des Befehls kubectl apply den Pod auf Ihren Cluster an.

    kubectl apply -f pod.yaml
    

Geheimnisse des Schlüsseltresors validieren

Nachdem der Pod gestartet wurde, ist der eingebundene Inhalt unter dem in Ihrer Bereitstellungs-YAML angegebenen Volumepfad verfügbar. Verwenden Sie die folgenden Befehle, um Ihre Geheimnisse zu überprüfen und ein Testgeheimnis auszudrucken.

  1. Zeigen Sie mit dem folgenden Befehl Geheimnisse im Geheimnisspeicher an.

    kubectl exec busybox-secrets-store-inline-user-msi -- ls /mnt/secrets-store/
    
  2. Zeigen Sie mit dem folgenden Befehl ein Geheimnis im Speicher an. Mit diesem Beispielbefehl wird das Testgeheimnis ExampleSecret angezeigt.

    kubectl exec busybox-secrets-store-inline-user-msi -- cat /mnt/secrets-store/ExampleSecret
    

Zertifikate und Schlüssel abrufen

Azure Key Vault unterscheidet streng zwischen Schlüsseln, Geheimnissen und Zertifikaten. Die Zertifikatsfunktionen des Schlüsseltresordiensts sind so konzipiert, dass sie die Fähigkeiten von Schlüssel und Geheimnis nutzen. Wenn Sie ein Key Vault-Zertifikat erstellen, werden ein adressierbarer Schlüssel und ein Geheimnis gleichen Namens erstellt. Dieser Schlüssel ermöglicht Authentifizierungsvorgänge und das Geheimnis ermöglicht den Abruf des Zertifikatswerts als Geheimnis.

Ein Key Vault-Zertifikat enthält auch öffentliche X509-Zertifikatmetadaten. Der Schlüsseltresor speichert sowohl die öffentliche als auch die private Komponente Ihres Zertifikats in einem Geheimnis. Sie können die jeweilige Komponente abrufen, indem Sie den objectType in SecretProviderClass angeben. Die folgende Tabelle zeigt, welche Objekte den verschiedenen Ressourcen Ihres Zertifikats zugeordnet sind:

Object Rückgabewert Zeigt die gesamte Zertifikatskette an
key Der öffentliche Schlüssel im PEM-Format (Privacy Enhanced Mail). Nicht zutreffend
cert Das Zertifikat im PEM-Format Nein
secret Der private Schlüssel und das Zertifikat im PEM-Format Ja

Deaktivieren des Add-Ons auf vorhandenen Clustern

Hinweis

Stellen Sie vor dem Deaktivieren des Add-Ons sicher, dass keineSecretProviderClass verwendet wird. Der Versuch, das Add-On zu deaktivieren, während eine SecretProviderClass vorhanden ist, führt zu einem Fehler.

  • Verwenden Sie den Befehl az aks disable-addons mit dem Add-On azure-keyvault-secrets-provider, um die Funktionen des Azure Key Vault Provider for Secrets Store CSI-Treibers in einem vorhandenen Cluster zu deaktivieren.

    az aks disable-addons --addons azure-keyvault-secrets-provider -g myResourceGroup -n myAKSCluster
    

Hinweis

Wenn Sie das Add-On deaktivieren, sollten bei vorhandenen Workloads keine Probleme auftreten und keine Aktualisierungen in den eingebundenen Geheimnissen angezeigt werden. Wenn der Pod neu gestartet werden soll oder ein neuer Pod im Rahmen des Hochskalierungsereignisses erstellt wird, tritt beim Starten des Pods ein Fehler auf, da der Treiber nicht mehr ausgeführt wird.

Nächste Schritte

In diesem Artikel haben Sie erfahren, wie Sie eine Identität für den Zugriff auf Ihren Azure Key Vault erstellen und bereitstellen. Wenn Sie zusätzliche Konfigurationsoptionen konfigurieren oder eine Problembehandlung durchführen möchten, fahren Sie mit dem nächsten Artikel fort.