Подключение поставщик удостоверений Azure в драйвер CSI хранилища секретов Azure Key Vault в Служба Azure Kubernetes (AKS)

Драйвер служба хранилища интерфейса хранилища секретов (CSI) в Служба Azure Kubernetes (AKS) предоставляет различные методы доступа на основе удостоверений к Azure Key Vault. В этой статье описаны эти методы и рекомендации по использованию моделей безопасности управления доступом на основе ролей (RBAC) или OpenID Подключение (OIDC) для доступа к хранилищу ключей и кластеру AKS.

Вы можете использовать один из следующих методов доступа:

Предварительные требования для драйвера CSI

Доступ с помощью Идентификация рабочей нагрузки Microsoft Entra

Идентификация рабочей нагрузки Microsoft Entra — это удостоверение, которое приложение, работающее в модуле pod, использует для проверки подлинности в других службах Azure, таких как рабочие нагрузки в программном обеспечении. Драйвер CSI хранилища секретов интегрируется с собственными возможностями Kubernetes для федерации с внешними поставщиками удостоверений.

В этой модели безопасности кластер AKS выступает в качестве издателя маркеров. Затем идентификатор Microsoft Entra использует OIDC для обнаружения открытых ключей подписывания и проверки подлинности маркера учетной записи службы перед обменом на токен Microsoft Entra. Чтобы рабочая нагрузка обменилась маркером учетной записи службы, проецируемым на его том для маркера Microsoft Entra, вам потребуется клиентская библиотека удостоверений Azure в пакете SDK Azure или библиотеке проверки подлинности Майкрософт (MSAL)

Примечание.

  • Этот метод проверки подлинности заменяет управляемое модулем Microsoft Entra pod (предварительная версия). Управляемое модулем открытый код Microsoft Entra pod (предварительная версия) в Служба Azure Kubernetes устарело по состоянию на 10.24.2022.
  • Идентификация рабочей нагрузки Microsoft Entra поддерживает кластеры Windows и Linux.

Настройка удостоверения рабочей нагрузки

  1. Задайте подписку 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. Создайте управляемое удостоверение с помощью 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. Создайте назначение ролей, которое предоставляет удостоверению рабочей нагрузки разрешение на доступ к секретам хранилища ключей, ключам доступа и сертификатам с помощью 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. Получите URL-адрес издателя кластера AKS кластера OIDC с помощью az aks show команды.

    Примечание.

    На этом шаге предполагается, что у вас есть существующий кластер AKS с включенным URL-адресом издателя OIDC. Если она не включена, см. статью "Обновить кластер AKS" с помощью издателя OIDC, чтобы включить его.

    export AKS_OIDC_ISSUER="$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "oidcIssuerProfile.issuerUrl" -o tsv)"
    echo $AKS_OIDC_ISSUER
    
  5. Установите учетные данные федеративного удостоверения между приложением Microsoft Entra, издателем учетной записи службы и субъектом. Получите идентификатор объекта приложения Microsoft Entra с помощью следующих команд. Обязательно обновите значения для serviceAccountName имени учетной записи службы Kubernetes и serviceAccountNamespace его пространства имен.

    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. Создайте учетные данные федеративного удостоверения между управляемым удостоверением, издателем учетной записи службы и субъектом 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. SecretProviderClass Разверните команду с помощью следующего kubectl apply скрипта 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
    

    Примечание.

    Если вы используете objectAlias вместо этого objectName, обновите скрипт YAML, чтобы он учитывал.

    Примечание.

    Чтобы SecretProviderClass обеспечить правильную работу, обязательно заполните Azure Key Vault секретами, ключами или сертификатами, прежде чем ссылаться на них в objects разделе.

  8. Разверните пример pod с помощью kubectl apply команды и следующего скрипта 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
    

Доступ с помощью управляемого удостоверения

Управляемый идентификатор Microsoft Entra — это удостоверение, которое администратор использует для проверки подлинности в других службах Azure. Управляемое удостоверение использует RBAC для федерации с внешними поставщиками удостоверений.

В этой модели безопасности вы можете предоставить доступ к ресурсам кластера участникам группы или клиентам, которым предоставлен доступ к управляемой роли. Роль проверка для область доступа к keyvault и другим учетным данным. Если вы включили поставщик Azure Key Vault для драйвера CSI Хранилища секретов в кластере AKS, он создал удостоверение пользователя.

Настройка управляемого удостоверения

  1. Доступ к хранилищу ключей с помощью az aks show команды и управляемого удостоверения, назначаемого пользователем, созданного надстройкой. Вы также должны получить идентификатор clientId, который вы будете использовать в последующих шагах при создании 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
    

    Кроме того, можно создать управляемое удостоверение и назначить его масштабируемой группе виртуальных машин или каждому экземпляру виртуальной машины в группе доступности с помощью следующих команд.

    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. Создайте назначение роли, которое предоставляет удостоверению доступ к секретам хранилища ключей, ключам доступа и сертификатам с помощью 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. Создайте с помощью следующего SecretProviderClass YAML. Обязательно используйте собственные значения для userAssignedIdentityID, keyvaultNametenantIdи объектов для получения из хранилища ключей.

    # 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
    

    Примечание.

    Если вы objectAlias используете вместо этого objectName, обязательно обновите скрипт YAML.

    Примечание.

    Чтобы SecretProviderClass обеспечить правильную работу, обязательно заполните Azure Key Vault секретами, ключами или сертификатами, прежде чем ссылаться на них в objects разделе.

  4. Примените его к кластеру SecretProviderClasskubectl apply с помощью команды.

    kubectl apply -f secretproviderclass.yaml
    
  5. Создайте модуль pod с помощью следующего 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. Примените pod к кластеру kubectl apply с помощью команды.

    kubectl apply -f pod.yaml
    

Проверка секретов Key Vault

После запуска модуля будет доступно подключенное содержимое по пути к тому, указанному в YAML развертывания. Используйте следующие команды, чтобы проверить секреты и распечатать секрет теста.

  1. Отображение секретов, содержащихся в хранилище секретов, с помощью следующей команды.

    kubectl exec busybox-secrets-store-inline-user-msi -- ls /mnt/secrets-store/
    
  2. Отображение секрета в хранилище с помощью следующей команды. В этом примере команды показан секрет ExampleSecretтеста.

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

Получение сертификатов и ключей

В структуре Azure Key Vault существуют четкие различия между ключами, секретами и сертификатами. Функции сертификата службы Key Vault предназначены для использования возможностей ключа и секретов. При создании сертификата хранилища ключей он создает адресный ключ и секрет с тем же именем. Этот ключ позволяет выполнять операции проверки подлинности, а секрет позволяет получить значение сертификата в виде секрета.

Сертификат хранилища ключей также содержит метаданные открытого сертификата x509. В хранилище ключей в секрете хранятся как общедоступные, так и закрытые компоненты сертификата. Для получения каждого отдельного компонента указывайте параметр objectType в классе SecretProviderClass. В таблице ниже показано, какие объекты сопоставляются с различными ресурсами, связанными с сертификатом.

Object Возвращаемое значение Возвращает всю цепочку сертификатов
key Открытый ключ в формате "Расширенная почта конфиденциальности" (PEM). Н/П
cert Сертификат в формате PEM. No
secret Закрытый ключ и сертификат в формате PEM. Да

Отключение надстройки в существующих кластерах

Примечание.

Прежде чем отключить надстройку, убедитесь, что он неSecretProviderClass используется. Попытка отключить надстройку во время SecretProviderClass существования приводит к ошибке.

  • Отключите поставщик Azure Key Vault для возможности драйвера CSI хранилища секретов в существующем кластере с помощью az aks disable-addons команды с надстройкой azure-keyvault-secrets-provider .

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

Примечание.

При отключении надстройки существующие рабочие нагрузки не должны иметь проблем или просматривать обновления в подключенных секретах. Если модуль pod перезапускается или создается новый модуль pod в рамках события масштабирования, модуль pod не запускается, так как драйвер больше не работает.

Следующие шаги

Из этой статьи вы узнали, как создать и предоставить удостоверение для доступа к Azure Key Vault. Если вы хотите настроить дополнительные параметры конфигурации или выполнить устранение неполадок, перейдите к следующей статье.