Połączenie dostawcy tożsamości platformy Azure do sterownika CSI magazynu wpisów tajnych usługi Azure Key Vault w usłudze Azure Kubernetes Service (AKS)

Sterownik interfejsu CSI (Container Storage Interface) magazynu wpisów tajnych w usłudze Azure Kubernetes Service (AKS) zapewnia różne metody dostępu opartego na tożsamościach do usługi Azure Key Vault. W tym artykule opisano te metody i najlepsze rozwiązania dotyczące używania kontroli dostępu opartej na rolach (RBAC) lub modeli zabezpieczeń OpenID Połączenie (OIDC) w celu uzyskania dostępu do magazynu kluczy i klastra usługi AKS.

Możesz użyć jednej z następujących metod dostępu:

Wymagania wstępne dotyczące sterownika CSI

Dostęp za pomocą Tożsamość obciążeń Microsoft Entra

Tożsamość obciążeń Microsoft Entra to tożsamość używana przez aplikację działającą w zasobniku do uwierzytelniania się w innych usługach platformy Azure, takich jak obciążenia w oprogramowaniu. Sterownik CSI magazynu wpisów tajnych integruje się z natywnymi możliwościami platformy Kubernetes w celu federacji z zewnętrznymi dostawcami tożsamości.

W tym modelu zabezpieczeń klaster usługi AKS działa jako wystawca tokenu. Następnie identyfikator Entra firmy Microsoft używa identyfikatora OIDC do odnajdywania publicznych kluczy podpisywania i weryfikowania autentyczności tokenu konta usługi przed wymianą go na token entra firmy Microsoft. Aby obciążenie wymieniało token konta usługi przewidywany na jego wolumin dla tokenu Entra firmy Microsoft, potrzebna jest biblioteka klienta tożsamości platformy Azure w zestawie Azure SDK lub biblioteka Microsoft Authentication Library (MSAL)

Uwaga

  • Ta metoda uwierzytelniania zastępuje tożsamość zarządzaną zasobnika firmy Microsoft (wersja zapoznawcza). Tożsamość zarządzana typu open source firmy Microsoft Entra (wersja zapoznawcza) w usłudze Azure Kubernetes Service została uznana za przestarzałą od 24.01.2022 r.
  • Tożsamość obciążeń Microsoft Entra obsługuje zarówno klastry systemu Windows, jak i Linux.

Konfigurowanie tożsamości obciążenia

  1. Ustaw subskrypcję przy użyciu az account set polecenia .

    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. Utwórz tożsamość zarządzaną przy użyciu az identity create polecenia .

    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. Utwórz przypisanie roli, które przyznaje tożsamości obciążenia uprawnienia dostępu do wpisów tajnych magazynu kluczy, kluczy dostępu i certyfikatów przy użyciu az role assignment create polecenia .

    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. Pobierz adres URL wystawcy OIDC klastra az aks show usługi AKS przy użyciu polecenia .

    Uwaga

    W tym kroku założono, że masz istniejący klaster usługi AKS z włączonym adresem URL wystawcy OIDC. Jeśli nie jest ona włączona, zobacz Aktualizowanie klastra usługi AKS za pomocą wystawcy OIDC, aby go włączyć.

    export AKS_OIDC_ISSUER="$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "oidcIssuerProfile.issuerUrl" -o tsv)"
    echo $AKS_OIDC_ISSUER
    
  5. Ustanów poświadczenia tożsamości federacyjnej między aplikacją Microsoft Entra, wystawcą konta usługi i tematem. Pobierz identyfikator obiektu aplikacji Microsoft Entra przy użyciu następujących poleceń. Pamiętaj, aby zaktualizować wartości dla serviceAccountName i serviceAccountNamespace przy użyciu nazwy konta usługi Kubernetes i jego przestrzeni nazw.

    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. Utwórz poświadczenia tożsamości federacyjnej między tożsamością zarządzaną, wystawcą konta usługi i podmiotem az identity federated-credential create przy użyciu polecenia .

    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. SecretProviderClass Wdróż element przy użyciu kubectl apply polecenia i następującego skryptu YAML.

    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
    

    Uwaga

    Jeśli używasz objectAlias zamiast objectName, zaktualizuj skrypt YAML, aby go uwzględnić.

    Uwaga

    Aby element SecretProviderClass to działał prawidłowo, przed odwoływaniem się do nich w objects sekcji upewnij się, że usługa Azure Key Vault zostanie wypełniona wpisami tajnymi, kluczami lub certyfikatami.

  8. Wdróż przykładowy zasobnik przy użyciu kubectl apply polecenia i następującego skryptu YAML.

    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
    

Dostęp za pomocą tożsamości zarządzanej

Identyfikator zarządzany firmy Microsoft Entra to tożsamość używana przez administratora do uwierzytelniania się w innych usługach platformy Azure. Tożsamość zarządzana używa kontroli dostępu opartej na rolach do federacji z zewnętrznymi dostawcami tożsamości.

W tym modelu zabezpieczeń można udzielić dostępu do zasobów klastra członkom zespołu lub dzierżawcom udostępniającym rolę zarządzaną. Rola jest sprawdzana pod kątem zakresu dostępu do magazynu kluczy i innych poświadczeń. Po włączeniu dostawcy usługi Azure Key Vault dla sterownika CSI magazynu wpisów tajnych w klastrze usługi AKS została utworzona tożsamość użytkownika.

Konfigurowanie tożsamości zarządzanej

  1. Uzyskaj dostęp do magazynu kluczy przy użyciu az aks show polecenia i przypisanej przez użytkownika tożsamości zarządzanej utworzonej przez dodatek. Należy również pobrać tożsamość clientId, która będzie używana w kolejnych krokach podczas tworzenia obiektu SecretProviderClass.

    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
    

    Alternatywnie możesz utworzyć nową tożsamość zarządzaną i przypisać ją do zestawu skalowania maszyny wirtualnej lub do każdego wystąpienia maszyny wirtualnej w zestawie dostępności przy użyciu następujących poleceń.

    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. Utwórz przypisanie roli, które przyznaje tożsamości uprawnienia dostępu do wpisów tajnych magazynu kluczy, kluczy dostępu i certyfikatów przy użyciu az role assignment create polecenia .

    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. Utwórz element SecretProviderClass przy użyciu następującego kodu YAML. Pamiętaj, aby użyć własnych wartości dla userAssignedIdentityIDobiektów , , tenantIdkeyvaultNamei do pobrania z magazynu kluczy.

    # 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
    

    Uwaga

    Jeśli używasz objectAlias zamiast objectName, pamiętaj o zaktualizowaniu skryptu YAML.

    Uwaga

    Aby element SecretProviderClass to działał prawidłowo, przed odwoływaniem się do nich w objects sekcji upewnij się, że usługa Azure Key Vault zostanie wypełniona wpisami tajnymi, kluczami lub certyfikatami.

  4. Zastosuj element do klastra SecretProviderClasskubectl apply przy użyciu polecenia .

    kubectl apply -f secretproviderclass.yaml
    
  5. Utwórz zasobnik przy użyciu następującego kodu YAML.

    # 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. Zastosuj zasobnik do klastra kubectl apply przy użyciu polecenia .

    kubectl apply -f pod.yaml
    

Weryfikowanie wpisów tajnych usługi Key Vault

Po uruchomieniu zasobnika jest dostępna instalowana zawartość na ścieżce woluminu określonej w wdrożeniu YAML. Użyj następujących poleceń, aby zweryfikować wpisy tajne i wydrukować wpis tajny testowy.

  1. Pokaż wpisy tajne przechowywane w magazynie wpisów tajnych przy użyciu następującego polecenia.

    kubectl exec busybox-secrets-store-inline-user-msi -- ls /mnt/secrets-store/
    
  2. Wyświetl wpis tajny w magazynie przy użyciu następującego polecenia. W tym przykładowym poleceniu jest wyświetlany wpis tajny ExampleSecrettestu .

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

Uzyskiwanie certyfikatów i kluczy

Projekt usługi Azure Key Vault umożliwia ostre rozróżnienie między kluczami, wpisami tajnymi i certyfikatami. Funkcje certyfikatów usługi Key Vault zostały zaprojektowane tak, aby korzystały z funkcji kluczy i wpisów tajnych. Podczas tworzenia certyfikatu magazynu kluczy tworzy on adresowy klucz i wpis tajny o tej samej nazwie. Ten klucz umożliwia operacje uwierzytelniania, a wpis tajny umożliwia pobieranie wartości certyfikatu jako wpisu tajnego.

Certyfikat magazynu kluczy zawiera również publiczne metadane certyfikatu x509. Magazyn kluczy przechowuje zarówno składniki publiczne, jak i prywatne certyfikatu w kluczu tajnym. Każdy składnik można uzyskać, określając element w SecretProviderClasselemencie objectType . W poniższej tabeli przedstawiono obiekty mapowania na różne zasoby skojarzone z certyfikatem:

Objekt Wartość zwracana Zwraca cały łańcuch certyfikatów
key Klucz publiczny w formacie PEM (Privacy Enhanced Mail). Nie dotyczy
cert Certyfikat w formacie PEM. Nie.
secret Klucz prywatny i certyfikat w formacie PEM. Tak

Wyłączanie dodatku w istniejących klastrach

Uwaga

Przed wyłączeniem dodatku upewnij się, że nieSecretProviderClass jest używany. Próba wyłączenia dodatku, gdy SecretProviderClass element istnieje, powoduje wystąpienie błędu.

  • Wyłącz dostawcę usługi Azure Key Vault dla funkcji sterownika CSI magazynu wpisów tajnych w istniejącym klastrze przy użyciu az aks disable-addons polecenia z dodatkiem azure-keyvault-secrets-provider .

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

Uwaga

Po wyłączeniu dodatku istniejące obciążenia nie powinny mieć problemów ani nie wyświetlać żadnych aktualizacji w zainstalowanych wpisach tajnych. Jeśli zasobnik zostanie uruchomiony ponownie lub nowy zasobnik zostanie utworzony w ramach zdarzenia skalowania w górę, nie można uruchomić zasobnika, ponieważ sterownik nie jest już uruchomiony.

Następne kroki

W tym artykule przedstawiono sposób tworzenia i udostępniania tożsamości w celu uzyskania dostępu do usługi Azure Key Vault. Jeśli chcesz skonfigurować dodatkowe opcje konfiguracji lub wykonać rozwiązywanie problemów, przejdź do następnego artykułu.