Connectez votre fournisseur d’identité Azure au f fournisseur Azure Key Vault pour le pilote Secrets Store CSI dans AKS (Azure Kubernetes Services)

Le pilote CSI (Container Storage Interface) Secrets Store sur AKS (Azure Kubernetes Services) fournit diverses méthodes d’accès basé sur l’identité à votre instance Azure Key Vault. Cet article décrit ces méthodes et meilleures pratiques pour le moment de l’utilisation du contrôle d’accès en fonction du rôle (RBAC) ou des modèles de sécurité OIDC (OpenID Connect ) pour accéder à votre coffre de clés et à votre cluster AKS.

Vous pouvez adopter l’une des méthodes d’accès suivantes :

Conditions préalables pour le pilote CSI

Accéder avec une charge de travail Microsoft Entra ID

Un ID de charge de travail Microsoft Entra est une identité utilisée par une application s’exécutant sur un pod pour s’authentifie auprès d’autres services Azure, comme une charge de travail dans un logiciel. Le pilote CSI Secrets Store s’intègre aux fonctionnalités natives de Kubernetes pour se fédérer avec des fournisseurs d’identité externes.

Dans ce modèle de sécurité, le cluster AKS agit en tant qu’émetteur de jeton. Microsoft Entra ID utilise ensuite OIDC pour découvrir des clés de signature publique et vérifier l’authenticité du jeton du compte du service avant de l’échanger pour un jeton Microsoft Entra. Afin que votre charge de travail échange un jeton du compte de service projeté sur son volume pour un jeton Microsoft Entra, vous avez besoin d’une bibliothèque cliente Azure Identity avec le kit de développement logiciel (SDK) Azure ou la bibliothèque d’authentification Microsoft (MSAL)

Remarque

  • Cette méthode d’authentification remplace l’identité managée par pod Microsoft Entra (préversion). L’identité managée par pod Microsoft Entra open source (préversion) dans Azure Kubernetes Service est déconseillée depuis le 24/10/2022.
  • L’ID de la charge de travail Microsoft Entra est pris en charge sur des clusters Windows et Linux.

Configurer une identité de charge de travail

  1. Définissez votre abonnement à l’aide de la commande az account set.

    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. Créez une identité managée à l’aide de la commande az identity create.

    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. Créez une attribution de rôle qui accorde à l’identité de charge de travail l’autorisation d’accéder aux secrets, clés d’accès et certificats Key Vault en utilisant la commande az role assignment create.

    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. Obtenez l’URL de l’émetteur OIDC du cluster AKS à l’aide de la az aks show commande .

    Remarque

    Cette étape suppose que vous disposez d’un cluster AKS existant, avec l’URL de l’émetteur OIDC activée. Si vous ne l’avez pas activé, consultez Mettre à jour un cluster AKS avec l’émetteur OIDC pour l’activer.

    export AKS_OIDC_ISSUER="$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "oidcIssuerProfile.issuerUrl" -o tsv)"
    echo $AKS_OIDC_ISSUER
    
  5. Établissez des informations d’identification de l’identité fédérée entre l’application Microsoft Entra et l’émetteur du compte de service et le sujet. Obtenez l’ID d’objet de l’application Microsoft Entra à l’aide des commandes suivantes. Assurez-vous de mettre à jour les valeurs pour serviceAccountName et serviceAccountNamespace avec le nom du compte de service Kubernetes et son espace de noms.

    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. Créez les informations d’identification d’identité fédérées entre l’identité managée, l’émetteur du compte de service et l’objet à l’aide de la commande 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. Déployez un SecretProviderClass à l’aide de la kubectl apply commande et du script YAML suivant.

    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
    

    Remarque

    Si vous utilisez objectAlias plutôt que objectName, mettez à jour le script YAML pour le justifier.

    Remarque

    Pour que le SecretProviderClass fonctionne correctement, assurez-vous de remplir votre Azure Key Vault de secrets, de clés ou de certificats, avant de les référencer dans la section objects.

  8. Déployez un échantillon de pod à l’aide de la kubectl apply commande et du script YAML suivant.

    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
    

Accès avec une identité managée

Un ID managé Microsoft Entra est utilisée par un administrateur pour s’authentifier auprès d’autres services Azure. L’identité managée utilise le contrôle d’accès en fonction du rôle pour une fédération avec des fournisseurs d’identité externes.

Dans ce modèle de sécurité, vous pouvez octroyer l’accès aux ressources de votre cluster aux membres de l’équipe ou aux locataires partageant un rôle managé. Le rôle est vérifié pour un accès de l’étendue au coffre de clés et à d’autres informations d’identification. Lorsque vous avez activé le fournisseur Azure Key Vault pour le pilote Secrets Store CSI du magasin de secrets sur votre cluster AKS, il a créé une identité utilisateur.

Configurer une identité managée

  1. Accédez à votre coffre de clés à l’aide de la commande az aks show et de l’identité managée affectée par l’utilisateur créée par le module complémentaire. Vous devez également récupérer l’identité clientId à utiliser dans les étapes ultérieures lors de la création d’un 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
    

    Vous pouvez également créer une nouvelle identité managée et l’affecter à votre groupe de machines virtuelles identiques ou à chaque instance de machine virtuelle dans votre groupe à haute disponibilité à l’aide des commandes suivantes.

    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. Créez une attribution de rôle qui octroie à l’identité l’autorisation d’accéder aux secrets, clés d’accès et certificats Key Vault en utilisant la commande az role assignment create.

    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. Créez un SecretProviderClass à l’aide du code YAML suivant. Assurez-vous de remplacer les valeurs de userAssignedIdentityID, keyvaultName, tenantId et les objets à récupérer à partir de votre coffre de clés.

    # 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
    

    Notes

    Si vous utilisez objectAlias au lieu de objectName, veillez à mettre à jour le script YAML.

    Remarque

    Pour que le SecretProviderClass fonctionne correctement, assurez-vous de remplir votre Azure Key Vault de secrets, de clés ou de certificats, avant de les référencer dans la section objects.

  4. Appliquez le SecretProviderClass à votre cluster à l’aide de la commande kubectl apply.

    kubectl apply -f secretproviderclass.yaml
    
  5. Créez un pod à l’aide du code YAML suivant.

    # 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. Appliquez le pod à votre cluster à l’aide de la commande kubectl apply.

    kubectl apply -f pod.yaml
    

Valider des secrets Key Vault

Une fois le pod démarré, le contenu monté au niveau du chemin d’accès du volume spécifié dans le YAML de votre déploiement est disponible. Utilisez les commandes suivantes pour valider vos secrets et imprimer un secret de test.

  1. Afficher les secrets conservés dans le magasin de secrets à l’aide de la commande suivante.

    kubectl exec busybox-secrets-store-inline-user-msi -- ls /mnt/secrets-store/
    
  2. Afficher un secret du magasin à l’aide de la commande suivante. Cet exemple de commande montre le secret de test ExampleSecret.

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

Obtenir les certificats et clés

La conception d’Azure Key Vault fait une nette distinction entre les clés, les secrets et les certificats. Les fonctionnalités des certificats du service Key Vault sont conçues pour utiliser des caractéristiques de clé et de secret. Lorsque vous créez un certificat Key Vault, il crée une clé adressable et un secret avec le même nom. Cette clé permet d’exécuter des opérations d’authentification, tandis que le secret permet de récupérer la valeur du certificat sous forme de secret.

Un certificat Key Vault contient également des métadonnées de certificat x509 publiques. Le coffre de clés stocke les composantes publiques et privées de votre certificat dans un secret. Vous pouvez obtenir chaque composant individuel en spécifiant le objectType dans SecretProviderClass. Le tableau suivant répertorie les objets qui correspondent aux diverses ressources associées à votre certificat :

Object Valeur retournée Retourne la totalité de la chaîne de certificats
key La clé publique, au format Privacy Enhanced Mail (PEM). N/A
cert Certificat, au format PEM. Non
secret Clé privée et le certificat, au format PEM. Oui

Désactiver le module complémentaire sur des clusters existants

Remarque

Avant de désactiver le module complémentaire, assurez-vous qu’aucune SecretProviderClass n’est en cours d’utilisation. Si vous tentez de désactiver le module complémentaire alors qu’une SecretProviderClass existe, une erreur se produit.

  • Désactivez la fonctionnalité Fournisseur Azure Key Vault pour le pilote CSI du magasin de secrets dans un cluster existant à l’aide de la az aks disable-addons commande avec le azure-keyvault-secrets-provider module complémentaire.

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

Remarque

Lorsque vous désactivez le module complémentaire, les charges de travail existantes ne doivent rencontrer aucun problème ou voir des mises à jour dans les secrets montés. Si le pod redémarre ou qu’un pod est créé dans le cadre d’un événement de scale-up, le pod ne parvient pas à démarrer car le pilote n’est plus en cours d’exécution.

Étapes suivantes

Dans cet article, vous avez appris à créer et à fournir une identité pour accéder à votre instance Azure Key Vault. Si vous souhaitez configurer des options de configuration supplémentaires ou effectuer une résolution des problèmes, passez à l’article suivant.