Freigeben über


Verwenden der Geheimnisspeichererweiterung zum Abrufen von Geheimnissen für den Offlinezugriff in Azure Arc-fähigen Kubernetes-Clustern

Die Azure Key Vault Secret Store-Erweiterung für Kubernetes (SSE) synchronisiert geheime Schlüssel aus einem Azure Key Vault automatisch mit einem Azure Arc-fähigen Kubernetes-Cluster für den Offlinezugriff. Das bedeutet, dass Sie Azure Key Vault verwenden können, um Ihre Geheimnisse zu speichern, zu verwalten und zu rotieren, auch wenn Sie Ihren Kubernetes-Cluster in einem teilweise getrennten Zustand ausführen. Synchronisierte Geheimnisse werden im Geheimnisspeicher des Clusters gespeichert, sodass sie als Kubernetes-Geheimnisse verfügbar sind und wie gewohnt verwendet werden können: als Datenvolumes eingebunden oder als Umgebungsvariablen für einen Container in einem Pod verfügbar gemacht.

Synchronisierte geheime Schlüssel sind wichtige Geschäftsressourcen, sodass sie vom SSE über isolierte Namespaces, rollenbasierte Zugriffssteuerungsrichtlinien (RBAC) und eingeschränkte Berechtigungen für den Synchronisierungscontroller gesichert werden. Um zusätzlichen Schutz zu gewährleisten, verschlüsseln Sie den Kubernetes-Geheimnisspeicher in Ihrem Cluster.

In diesem Artikel erfahren Sie, wie Sie die SSE als Azure Arc-fähige Kubernetes-Erweiterung installieren und konfigurieren.

Tipp

Der SSE wird für Cluster außerhalb der Azure-Cloud empfohlen, bei denen die Konnektivität mit Azure Key Vault möglicherweise nicht perfekt ist. SSE erstellt von Natur aus Kopien Ihrer geheimen Daten im Kubernetes Secret-Speicher. Wenn Sie es vorziehen, lokale Kopien von Geheimnissen zu vermeiden, und Ihr Cluster über eine perfekte Verbindung zu Azure Key Vault verfügt, können Sie die ausschließlich online verfügbare Azure Key Vault Secrets Provider-Erweiterung für den Zugriff auf Geheimnisse in Ihren Arc-fähigen Kubernetes-Clustern verwenden. Es wird nicht empfohlen, sowohl die Onlineerweiterung Azure Key Vault Secrets Provider als auch die Offline-SSE nebeneinander im selben Cluster auszuführen.

Voraussetzungen

  • Ein Arc-fähiger Cluster. Dies kann ein Cluster sein, das Sie selbst verbunden haben (in diesem Handbuch wird ein K3s-Cluster vorausgesetzt und enthält Anleitungen zur Aktivierung von Arc.) oder ein von Microsoft verwaltetes von Azure Arc aktiviertes AKS-Cluster. Der Cluster muss Kubernetes, Version 1.27 oder höher, ausführen.
  • Stellen Sie sicher, dass Sie die allgemeinen Voraussetzungen für Clustererweiterungen erfüllen und u. a. die aktuelle Version der Azure CLI-Erweiterung k8s-extension nutzen.
  • Zur Unterstützung von TLS für die clusterinterne Protokollkommunikation ist cert-manager erforderlich. Die Beispiele weiter unten in diesem Handbuch leiten Sie durch die Installation. Weitere Informationen zu cert-manager finden Sie unter cert-manager.io.

Installieren Sie die Azure CLI, und melden Sie sich an, sofern noch nicht geschehen:

az login

Bevor Sie beginnen, legen Sie Umgebungsvariablen fest, die zum Konfigurieren von Azure und Clusterressourcen verwendet werden sollen. Wenn Sie bereits über eine verwaltete Identität, eine Azure Key Vault-Instanz oder eine andere hier aufgelistete Ressource verfügen, aktualisieren Sie die Namen in den Umgebungsvariablen so, dass sie diese Ressourcen widerspiegeln. Beachten Sie, dass der KEYVAULT_NAME global eindeutig sein muss; die Erstellung des Keyvault wird später fehlschlagen, wenn dieser Name bereits innerhalb von Azure verwendet wird.

export RESOURCE_GROUP="AzureArcTest"
export CLUSTER_NAME="AzureArcTest1"
export LOCATION="EastUS"
export SUBSCRIPTION="$(az account show --query id --output tsv)"
export AZURE_TENANT_ID="$(az account show -s $SUBSCRIPTION --query tenantId --output tsv)"
export CURRENT_USER="$(az ad signed-in-user show --query userPrincipalName --output tsv)"
export KEYVAULT_NAME="my-UNIQUE-kv-name"
export KEYVAULT_SECRET_NAME="my-secret"
export USER_ASSIGNED_IDENTITY_NAME="my-identity"
export FEDERATED_IDENTITY_CREDENTIAL_NAME="my-credential"
export KUBERNETES_NAMESPACE="my-namespace"
export SERVICE_ACCOUNT_NAME="my-service-account"

Erstellen Sie die Ressourcengruppe bei Bedarf:

az group create --name ${RESOURCE_GROUP}  --___location ${LOCATION}

Aktivieren des Workload-Identitätsverbunds in Ihrem Cluster

Die SSE verwendet ein Feature mit dem Namen Workload-Identitätsverbund, um auf Azure Key Vault-Geheimnisse zuzugreifen und diese zu synchronisieren. In diesem Abschnitt wird beschrieben, wie Sie das Feature einrichten. In den folgenden Abschnitten wird erläutert, wie sie ausführlich verwendet wird.

Tipp

Die folgenden Schritte basieren auf der Schrittanleitung zum Konfigurieren von Arc-fähigem Kubernetes mit dem Workload-Identitätsverbund. Weitere Unterstützung finden Sie in dieser Dokumentation.

Wenn Ihr Cluster noch nicht mit Azure Arc verbunden ist, führen Sie diese Schritte aus. Aktivieren Sie während der Schritte den Workload-Identitätsverbund als Teil des Befehls connect:

az connectedk8s connect --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --enable-oidc-issuer

Wenn Ihr Cluster bereits mit Azure Arc verbunden ist, aktivieren Sie die Workloadidentität mithilfe des Befehls update:

az connectedk8s update --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --enable-oidc-issuer

Konfigurieren Sie Ihren Cluster nun so, dass Dienstkontotoken mit einer neuen Aussteller-URL (service-account-issuer) ausgegeben werden, mit der Microsoft Entra ID die für die Überprüfung dieser Token erforderlichen öffentlichen Schlüssel finden kann. Diese öffentlichen Schlüssel gelten für den eigenen Dienstkonto-Tokenherausgeber des Clusters, und sie wurden aufgrund der zuvor Option --enable-oidc-issuer unter dieser URL abgerufen und in der Cloud gehostet.

Optional können Sie auch Grenzwerte für die eigenen Berechtigungen der SSE als privilegierte Ressource konfigurieren, die auf der Steuerungsebene ausgeführt wird, indem Sie den OwnerReferencesPermissionEnforcement-Zugangssteuerungscontroller konfigurieren. Dieser Zugangssteuerungscontroller schränkt ein, in welchem Maß die SSE andere Objekte im Cluster ändern kann.

  1. Konfigurieren Sie kube-apiserver mit dem Feld für die Aussteller-URL und der Berechtigungserzwingung. Das folgende Beispiel ist für einen k3s-Cluster. Ihr Cluster verfügt möglicherweise über andere Mittel zur Änderung der API-Serverargumente: --kube-apiserver-arg="--service-account-issuer=${SERVICE_ACCOUNT_ISSUER}", "--kube-apiserver-arg=service-account-max-token-expiration=24h" and --kube-apiserver-arg="--enable-admission-plugins=OwnerReferencesPermissionEnforcement".

    • Rufen Sie die Dienstkontoaussteller-URL ab.

      export SERVICE_ACCOUNT_ISSUER="$(az connectedk8s show --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --query "oidcIssuerProfile.issuerUrl" --output tsv)"
      echo $SERVICE_ACCOUNT_ISSUER
      
    • Aktualisieren Sie die API-Serverargumente in der Konfigurationsdatei des K3s-Clusters.

      cat <<EOF > /tmp/k3s-config.yaml
      kube-apiserver-arg:
          - 'service-account-issuer=${SERVICE_ACCOUNT_ISSUER}'
          - 'service-account-max-token-expiration=24h'
          - 'enable-admission-plugins=OwnerReferencesPermissionEnforcement'
      EOF
      sudo mv /tmp/k3s-config.yaml /etc/rancher/k3s/config.yaml
      
  2. Starten Sie „kube-apiserver“ neu.

    sudo systemctl restart k3s
    
  3. (optional) Überprüfen Sie, ob der Aussteller des Dienstkontos ordnungsgemäß konfiguriert wurde:

    kubectl cluster-info dump | grep service-account-issuer
    

Erstellen eines Geheimnisses und Konfigurieren einer Identität für den Zugriff auf das Geheimnis

Um auf ein bestimmtes Azure Key Vault-Geheimnis zuzugreifen und dieses zu synchronisieren, benötigt die SSE Zugriff auf eine verwaltete Azure-Identität mit entsprechenden Azure-Berechtigungen für den Zugriff auf dieses Geheimnis. Die verwaltete Identität muss mit einem Kubernetes-Dienstkonto verknüpft werden, indem Sie das Zuvor aktivierte Workload-Identitätsfeature verwenden. Die SSE verwendet die zugeordnete verwaltete Azure-Verbundidentität, um Geheimnisse aus Azure Key Vault in Ihren Kubernetes-Geheimnisspeicher zu pullen. In den folgenden Abschnitten wird die Vorgehensweise zur Einrichtung beschrieben.

Erstellen einer Azure Key Vault-Instanz

Erstellen Sie eine Azure Key Vault-Instanz, und fügen Sie ein Geheimnis hinzu. Wenn Sie bereits über eine Azure Key Vault-Instanz und ein Geheimnis verfügen, können Sie diesen Abschnitt überspringen.

  1. Erstellen einer Azure Key Vault-Instanz:

    az keyvault create --resource-group "${RESOURCE_GROUP}" --___location "${LOCATION}" --name "${KEYVAULT_NAME}" --enable-rbac-authorization
    
  2. Erteilen Sie sich selbst die Berechtigung „Für Geheimnis beauftragte Person“ für den Tresor, damit Sie ein Geheimnis erstellen können:

    az role assignment create --role "Key Vault Secrets Officer" --assignee ${CURRENT_USER} --scope /subscriptions/${SUBSCRIPTION}/resourcegroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}
    
  3. Erstellen Sie ein Geheimnis, und aktualisieren Sie es, damit Sie zwei Versionen haben:

    az keyvault secret set --vault-name "${KEYVAULT_NAME}" --name "${KEYVAULT_SECRET_NAME}" --value 'Hello!'
    az keyvault secret set --vault-name "${KEYVAULT_NAME}" --name "${KEYVAULT_SECRET_NAME}" --value 'Hello2'
    

Erstellen einer benutzerseitig zugewiesenen verwalteten Identität

Erstellen Sie als Nächstes eine benutzerseitig zugewiesene verwaltete Identität, und erteilen Sie ihr Berechtigungen für den Zugriff auf Azure Key Vault. Wenn Sie bereits über eine verwaltete Identität mit den Berechtigungen „Key Vault-Leseberechtigter“ und „Key Vault-Geheimnisbenutzer“ für Azure Key Vault verfügen, können Sie diesen Abschnitt überspringen. Weitere Informationen finden Sie unter Erstellen Sie eine vom Benutzer zugewiesene verwaltete Identität und Verwenden von Azure RBAC-Geheimnis-, Schlüssel- und Zertifikatsberechtigungen mit Key Vault.

  1. Erstellen Sie die benutzerseitig zugewiesene verwaltete Identität:

    az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --___location "${LOCATION}" --subscription "${SUBSCRIPTION}"
    
  2. Erteilen Sie der Identität Berechtigungen vom Typ „Key Vault-Leseberechtigter“ und „Key Vault-Geheimnisbenutzer“. Möglicherweise müssen Sie einen Moment auf die Replikation der Identitätserstellung warten, bevor diese Befehle erfolgreich sind:

    export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -otsv)"
    az role assignment create --role "Key Vault Reader" --assignee "${USER_ASSIGNED_CLIENT_ID}" --scope /subscriptions/${SUBSCRIPTION}/resourcegroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}
    az role assignment create --role "Key Vault Secrets User" --assignee "${USER_ASSIGNED_CLIENT_ID}" --scope /subscriptions/${SUBSCRIPTION}/resourcegroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}
    

Erstellen von Anmeldeinformationen für eine Verbundidentität

Erstellen Sie ein Kubernetes-Dienstkonto für die Workload, die Zugriff auf Geheimnisse benötigt. Erstellen Sie dann Anmeldeinformationen für eine Verbundidentität, um eine Verknüpfung zwischen der verwalteten Identität, dem OIDC-Dienstkontoaussteller und dem Kubernetes-Dienstkonto herzustellen.

  1. Erstellen Sie ein Kubernetes-Dienstkonto, das im Verbund mit der verwalteten Identität verwendet wird. Kommentieren Sie es mit Details der zugeordneten benutzerseitig zugewiesenen verwalteten Identität.

    kubectl create ns ${KUBERNETES_NAMESPACE}
    
    cat <<EOF | kubectl apply -f -
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: ${SERVICE_ACCOUNT_NAME}
        namespace: ${KUBERNETES_NAMESPACE}
    EOF
    
  2. Erstellen Sie Anmeldeinformationen für eine Verbundidentität:

    az identity federated-credential create --name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} --identity-name ${USER_ASSIGNED_IDENTITY_NAME} --resource-group ${RESOURCE_GROUP} --issuer ${SERVICE_ACCOUNT_ISSUER} --subject system:serviceaccount:${KUBERNETES_NAMESPACE}:${SERVICE_ACCOUNT_NAME} --audience api://AzureADTokenExchange
    

Installieren der SSE

Die SSE ist als Azure Arc-Erweiterung verfügbar. Ein Azure Arc-fähiger Kubernetes-Cluster kann mit Azure Arc-fähigen Kubernetes-Erweiterungen erweitert werden. Erweiterungen ermöglichen die Verwendung von Azure-Funktionen in Ihren verbundenen Clustern und bieten eine von Azure Resource Manager unterstützte Benutzeroberfläche für die Installation und Lebenszyklusverwaltung von Erweiterungen.

cert-manager und trust-manager sind auch für die sichere Kommunikation von Protokollen zwischen Clusterdiensten erforderlich und müssen vor der Arc-Erweiterung installiert werden.

  1. Installieren Sie cert-manager.

    helm repo add jetstack https://charts.jetstack.io/ --force-update
    helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set crds.enabled=true 
    
  2. Installieren Sie trust-manager.

    helm upgrade trust-manager jetstack/trust-manager --install --namespace cert-manager --wait
    
  3. Installieren Sie die SSE mit dem folgenden Befehl in Ihrem Arc-fähigen Cluster:

    az k8s-extension create \
      --cluster-name ${CLUSTER_NAME} \
      --cluster-type connectedClusters \
      --extension-type microsoft.azure.secretstore \
      --resource-group ${RESOURCE_GROUP} \
      --name ssarcextension \
      --scope cluster
    

    Wenn gewünscht, können Sie optional das Standardmäßige Drehungsabfragungsintervall ändern, indem Sie es hinzufügen --configuration-settings rotationPollIntervalInSeconds=<time_in_seconds> (siehe Konfigurationsreferenz).

Konfigurieren der SSE

Konfigurieren Sie die installierte Erweiterung mit Informationen zu Ihrer Azure Key Vault-Instanz und den Geheimnissen, die mit Ihrem Cluster synchronisiert werden sollen, indem Sie Instanzen von benutzerdefinierten Kubernetes-Ressourcen definieren. Sie erstellen zwei Arten von benutzerdefinierten Ressourcen:

  • Ein SecretProviderClass-Objekt zum Definieren der Verbindung mit Key Vault
  • Ein SecretSync-Objekt für jedes Geheimnis, das synchronisiert werden soll

Erstellen einer SecretProviderClass-Ressource

Die SecretProviderClass-Ressource wird verwendet, um die Verbindung mit Azure Key Vault und die Identität zu definieren, die für den Zugriff auf den Tresor verwendet werden soll. Außerdem werden die Geheimnisse, die synchronisiert werden sollen, und die Anzahl der Versionen aller Geheimnisse festgelegt, die lokal aufbewahrt werden sollen.

Sie benötigen eine separate SecretProviderClass-Ressource für jede Azure Key Vault-Instanz, die Sie synchronisieren möchten, für jede Identität, die für den Zugriff auf eine Azure Key Vault-Instanz verwendet wird, und für jeden Kubernetes-Zielnamespace.

Erstellen Sie anhand des folgenden Beispiels eine oder mehrere SecretProviderClass-YAML-Dateien mit den entsprechenden Werten für Ihre Key Vault-Instanz und Geheimnisse:

cat <<EOF > spc.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: secret-provider-class-name                       # Name of the class; must be unique per Kubernetes namespace
  namespace: ${KUBERNETES_NAMESPACE}                     # Kubernetes namespace to make the secrets accessible in
spec:
  provider: azure
  parameters:
    clientID: "${USER_ASSIGNED_CLIENT_ID}"               # Managed Identity Client ID for accessing the Azure Key Vault with.
    keyvaultName: ${KEYVAULT_NAME}                       # The name of the Azure Key Vault to synchronize secrets from.
    objects: |
      array:
        - |
          objectName: ${KEYVAULT_SECRET_NAME}            # The name of the secret to synchronize.
          objectType: secret
          objectVersionHistory: 2                        # [optional] The number of versions to synchronize, starting from latest.
    tenantID: "${AZURE_TENANT_ID}"                       # The tenant ID of the Key Vault 
EOF

Weitere Konfigurationsanleitungen finden Sie in der Referenz zu SecretProviderClass.

Erstellen eines SecretSync-Objekts

Ein SecretSync Objekt wird benötigt, um zu definieren, wie elemente, die von den SecretsProviderClass Objekten abgerufen werden, in Kubernetes gespeichert werden. Kubernetes-Geheimnisse sind Schlüssel-Wert-Zuordnungen, genau wie ConfigMaps. Das SecretSync-Objekt gibt SSE an, wie die im verknüpften SecretsProviderClass definierten Elemente in Schlüssel im Kubernetes-Geheimnis umgewandelt werden sollen. SSE wird ein Kubernetes Secret mit demselben Namen erstellen, wie der SecretSync, der es beschreibt.

Erstellen Sie nach dieser Vorlage eine SecretSync YAML-Objektdatei für jeden kubernetes Geheimschlüssel. Der Kubernetes-Namespace sollte mit dem Namespace der SecretProviderClass übereinstimmen.

cat <<EOF > ss.yaml
apiVersion: secret-sync.x-k8s.io/v1alpha1
kind: SecretSync
metadata:
  name: secret-sync-name                                   # Name of the object; must be unique per Kubernetes namespace
  namespace: ${KUBERNETES_NAMESPACE}                       # Kubernetes namespace
spec:
  serviceAccountName: ${SERVICE_ACCOUNT_NAME}              # The Kubernetes service account to be given permissions to access the secret.
  secretProviderClassName: secret-provider-class-name      # The name of the matching SecretProviderClass with the configuration to access the AKV storing this secret
  secretObject:
    type: Opaque
    data:
    - sourcePath: ${KEYVAULT_SECRET_NAME}/0                # Name of the secret in Azure Key Vault with an optional version number (defaults to latest)
      targetKey: ${KEYVAULT_SECRET_NAME}-data-key0         # Target name of the secret in the Kubernetes secret store (must be unique)
    - sourcePath: ${KEYVAULT_SECRET_NAME}/1                # [optional] Next version of the AKV secret. Note that versions of the secret must match the configured objectVersionHistory in the secrets provider class 
      targetKey: ${KEYVAULT_SECRET_NAME}-data-key1         # [optional] Next target name of the secret in the K8s secret store
EOF

Tipp

Schließen Sie „/0“ nicht ein, wenn Sie auf einen geheimen Schlüssel des SecretProviderClass verweisen, in dem objectVersionHistory< 2 angegeben ist. Die neueste Version wird implizit verwendet.

Weitere Konfigurationsanleitungen finden Sie in der SecretSync-Referenz .

Anwenden der benutzerdefinierten Ressourcen der Konfiguration

Wenden Sie die benutzerdefinierten Ressourcen der Konfiguration mithilfe des Befehls kubectl apply an:

kubectl apply -f ./spc.yaml
kubectl apply -f ./ss.yaml

Die SSE sucht automatisch nach den Geheimnissen und beginnt, sie mit dem Cluster zu synchronisieren.

Beobachten von Geheimnissen, die mit dem Cluster synchronisiert werden

Sobald die Konfiguration angewendet wurde, beginnt automatisch die Synchronisierung der Geheimnisse mit dem Cluster in dem bei der Installation der SSE angegebenen Intervall.

Anzeigen synchronisierter Geheimnisse

Zeigen Sie die mit dem Cluster synchronisierten Geheimnisse an, indem Sie den folgenden Befehl ausführen:

# View a list of all secrets in the namespace
kubectl get secrets -n ${KUBERNETES_NAMESPACE}

Tipp

Fügen Sie -o yaml oder -o json hinzu, um das Ausgabeformat der kubectl get und kubectl describe Befehle zu ändern.

Anzeigen von Geheimniswerten

Verwenden Sie den folgenden Befehl, um die synchronisierten Geheimniswerte anzuzeigen, die nun im Kubernetes-Geheimnisspeicher gespeichert sind:

kubectl get secret secret-sync-name -n ${KUBERNETES_NAMESPACE} -o jsonpath="{.data.${KEYVAULT_SECRET_NAME}-data-key0}" | base64 -d && echo
kubectl get secret secret-sync-name -n ${KUBERNETES_NAMESPACE} -o jsonpath="{.data.${KEYVAULT_SECRET_NAME}-data-key1}" | base64 -d && echo

Problembehandlung

Informationen zur Diagnose und Behebung von Problemen finden Sie im Handbuch zur Problembehandlung .

Entfernen der SSE

Um die SSE zu entfernen und die Synchronisierung von Geheimnissen zu beenden, deinstallieren Sie sie mit dem Befehl az k8s-extension delete:

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

Durch das Deinstallieren der Erweiterung werden keine Geheimnisse, SecretSync-Objekte oder CRDs aus dem Cluster entfernt. Diese Objekte müssen direkt mit kubectl entfernt werden.

Beim Löschen der SecretSync-CRD werden alle SecretSync-Objekte und standardmäßig alle eigenen Geheimnisse entfernt, Geheimnisse werden jedoch möglicherweise in folgenden Fällen beibehalten:

  • Sie haben den Besitz eines der Geheimnisse geändert.
  • Sie haben die GC-Einstellungen in Ihrem Cluster geändert und etwa verschiedene Finalizer festgelegt.

In diesen Fällen müssen Geheimnisse direkt mithilfe von kubectl gelöscht werden.

Nächste Schritte