Получение секретов в кластерах Kubernetes с поддержкой Azure Arc с использованием расширения поставщика секретов Azure Key Vault

Поставщик Azure Key Vault для драйвера CSI хранилища секретов позволяет интегрировать Azure Key Vault в качестве хранилища секретов с кластером Kubernetes (AKS) через том CSI. Для кластеров Kubernetes с поддержкой Azure Arc можно установить расширение поставщика секретов Azure Key Vault, которое позволяет получить секреты.

К возможностям расширения поставщика секретов Azure Key Vault относятся:

  • подключение секретов, ключей и сертификатов к pod с помощью встроенного тома CSI;
  • Поддерживает переносимость модулей посредством CRD SecretProviderClass
  • поддержка контейнеров Linux и Windows;
  • поддержка синхронизации с секретами Kubernetes;
  • поддержка автоматической смены секретов;
  • компоненты расширения развертываются в зонах доступности, что делает их избыточными между зонами.

Необходимые компоненты

  • Кластер с поддерживаемым дистрибутивом Kubernetes, который уже подключен к Azure Arc. В настоящее время для этого сценария поддерживаются следующие дистрибутивы Kubernetes:
    • Cluster API Azure
    • кластеры Служба Azure Kubernetes (AKS) в Azure Stack HCI
    • AKS, включенный Azure Arc
    • Google Kubernetes Engine
    • Дистрибутив OpenShift Kubernetes
    • Дистрибутив Canonical Kubernetes
    • Elastic Kubernetes Service;
    • Tanzu Kubernetes Grid
    • Azure Red Hat OpenShift
  • Убедитесь, что вы выполнили общие предварительные требования для расширений кластера. Необходимо использовать расширение Azure CLI k8s-extension 0.4.0 или более поздней версии.

Установка расширения поставщика секретов Azure Key Vault в кластере Kubernetes с поддержкой Arc

Расширение поставщика секретов Azure Key Vault можно установить в подключенном кластере в портал Azure с помощью Azure CLI или путем развертывания шаблона ARM.

В каждом кластере Kubernetes с поддержкой Azure Arc можно развернуть только один экземпляр расширения.

Совет

Если кластер находится за исходящим прокси-сервером, убедитесь, что он подключен к Azure Arc с помощью параметра конфигурации прокси-сервера перед установкой расширения.

Портал Azure

  1. На портале Azure перейдите к разделу Kubernetes — Azure Arc и выберите свой кластер.

  2. Выберите элемент Расширения (в разделе Параметры) и нажмите кнопку + Добавить.

    Screenshot showing the Extensions page for an Arc-enabled Kubernetes cluster in the Azure portal.

  3. В списке доступных расширений выберите вариант Поставщик секретов Azure Key Vault, чтобы развернуть последнюю версию расширения.

    Screenshot of the Azure Key Vault Secrets Provider extension in the Azure portal.

  4. Следуйте подсказкам для развертывания расширения. При необходимости настройте установку, изменив параметры по умолчанию на вкладке "Конфигурация ".

Azure CLI

  1. Задайте переменные среды:

    export CLUSTER_NAME=<arc-cluster-name>
    export RESOURCE_GROUP=<resource-group-name>
    
  2. Установите драйвер CSI хранилища секретов и расширение поставщика секретов Azure Key Vault, выполнив следующую команду:

    az k8s-extension create --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --cluster-type connectedClusters --extension-type Microsoft.AzureKeyVaultSecretsProvider --name akvsecretsprovider
    

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

{
  "aksAssignedIdentity": null,
  "autoUpgradeMinorVersion": true,
  "configurationProtectedSettings": {},
  "configurationSettings": {},
  "customLocationSettings": null,
  "errorInfo": null,
  "extensionType": "microsoft.azurekeyvaultsecretsprovider",
  "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Kubernetes/connectedClusters/$CLUSTER_NAME/providers/Microsoft.KubernetesConfiguration/extensions/akvsecretsprovider",
  "identity": {
    "principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "tenantId": null,
    "type": "SystemAssigned"
  },
  "location": null,
  "name": "akvsecretsprovider",
  "packageUri": null,
  "provisioningState": "Succeeded",
  "releaseTrain": "Stable",
  "resourceGroup": "$RESOURCE_GROUP",
  "scope": {
    "cluster": {
      "releaseNamespace": "kube-system"
    },
    "namespace": null
  },
  "statuses": [],
  "systemData": {
    "createdAt": "2022-05-12T18:35:56.552889+00:00",
    "createdBy": null,
    "createdByType": null,
    "lastModifiedAt": "2022-05-12T18:35:56.552889+00:00",
    "lastModifiedBy": null,
    "lastModifiedByType": null
  },
  "type": "Microsoft.KubernetesConfiguration/extensions",
  "version": "1.1.3"
}

Шаблон ARM

  1. Создайте файл JSON в следующем формате. Обязательно обновите значение <имени кластера>, чтобы можно было ссылаться на кластер.

    {
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
            "ConnectedClusterName": {
                "defaultValue": "<cluster-name>",
                "type": "String",
                "metadata": {
                    "description": "The Connected Cluster name."
                }
            },
            "ExtensionInstanceName": {
                "defaultValue": "akvsecretsprovider",
                "type": "String",
                "metadata": {
                    "description": "The extension instance name."
                }
            },
            "ExtensionVersion": {
                "defaultValue": "",
                "type": "String",
                "metadata": {
                    "description": "The version of the extension type."
                }
            },
            "ExtensionType": {
                "defaultValue": "Microsoft.AzureKeyVaultSecretsProvider",
                "type": "String",
                "metadata": {
                    "description": "The extension type."
                }
            },
            "ReleaseTrain": {
                "defaultValue": "stable",
                "type": "String",
                "metadata": {
                    "description": "The release train."
                }
            }
        },
        "functions": [],
        "resources": [
            {
                "type": "Microsoft.KubernetesConfiguration/extensions",
                "apiVersion": "2021-09-01",
                "name": "[parameters('ExtensionInstanceName')]",
                "identity": {
                 "type": "SystemAssigned"
                },
                "properties": {
                    "extensionType": "[parameters('ExtensionType')]",
                    "releaseTrain": "[parameters('ReleaseTrain')]",
                    "version": "[parameters('ExtensionVersion')]"
                },
                "scope": "[concat('Microsoft.Kubernetes/connectedClusters/', parameters('ConnectedClusterName'))]"
            }
        ]
    }
    
  2. Теперь задайте переменные среды с помощью следующей команды Azure CLI:

    export TEMPLATE_FILE_NAME=<template-file-path>
    export DEPLOYMENT_NAME=<desired-deployment-name>
    
  3. Наконец, выполните следующую команду Azure CLI, чтобы установить расширение поставщика секретов Azure Key Vault:

    az deployment group create --name $DEPLOYMENT_NAME --resource-group $RESOURCE_GROUP --template-file $TEMPLATE_FILE_NAME
    

Теперь у вас должна быть возможность просматривать ресурсы поставщика секретов и использовать расширение в своем кластере.

Проверка установки расширения

Чтобы убедиться в том, что расширение поставщика секретов Azure Key Vault успешно установлено, выполните следующую команду.

az k8s-extension show --cluster-type connectedClusters --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --name akvsecretsprovider

Вы должны увидеть выходные данные, аналогичные этому примеру.

{
  "aksAssignedIdentity": null,
  "autoUpgradeMinorVersion": true,
  "configurationProtectedSettings": {},
  "configurationSettings": {},
  "customLocationSettings": null,
  "errorInfo": null,
  "extensionType": "microsoft.azurekeyvaultsecretsprovider",
  "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Kubernetes/connectedClusters/$CLUSTER_NAME/providers/Microsoft.KubernetesConfiguration/extensions/akvsecretsprovider",
  "identity": {
    "principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "tenantId": null,
    "type": "SystemAssigned"
  },
  "location": null,
  "name": "akvsecretsprovider",
  "packageUri": null,
  "provisioningState": "Succeeded",
  "releaseTrain": "Stable",
  "resourceGroup": "$RESOURCE_GROUP",
  "scope": {
    "cluster": {
      "releaseNamespace": "kube-system"
    },
    "namespace": null
  },
  "statuses": [],
  "systemData": {
    "createdAt": "2022-05-12T18:35:56.552889+00:00",
    "createdBy": null,
    "createdByType": null,
    "lastModifiedAt": "2022-05-12T18:35:56.552889+00:00",
    "lastModifiedBy": null,
    "lastModifiedByType": null
  },
  "type": "Microsoft.KubernetesConfiguration/extensions",
  "version": "1.1.3"
}

Создание или выбор ресурса Azure Key Vault

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

Установите указанные ниже переменные среды.

export AKV_RESOURCE_GROUP=<resource-group-name>
export AZUREKEYVAULT_NAME=<AKV-name>
export AZUREKEYVAULT_LOCATION=<AKV-location>

Затем выполните следующую команду:

az keyvault create -n $AZUREKEYVAULT_NAME -g $AKV_RESOURCE_GROUP -l $AZUREKEYVAULT_LOCATION

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

az keyvault secret set --vault-name $AZUREKEYVAULT_NAME -n DemoSecret --value MyExampleSecret

Прежде чем переходить к следующему разделу, запишите следующие свойства:

  • имя объекта секрета в Key Vault;
  • Тип объекта (секрет, ключ или сертификат)
  • имя вашего ресурса Key Vault;
  • идентификатор клиента Azure для подписки, к которой принадлежит Key Vault.

Предоставление удостоверения для доступа к Azure Key Vault

Сейчас доступ к драйверу CSI хранилища секретов в кластерах с поддержкой Arc можно получить через субъект-службу. Выполните следующие действия, чтобы предоставить удостоверение, которое может получить доступ к Key Vault.

  1. Выполните действия , чтобы создать субъект-службу в Azure. Запишите значения идентификатора и секрета клиента, созданные на этом этапе.

  2. Затем убедитесь, что Azure Key Vault имеет разрешение GET для созданного субъекта-службы.

  3. Используйте идентификатор клиента и секрет клиента из первого шага, чтобы создать секрет Kubernetes в подключенном кластере:

    kubectl create secret generic secrets-store-creds --from-literal clientid="<client-id>" --from-literal clientsecret="<client-secret>"
    
  4. Добавление метки к созданному секрету:

    kubectl label secret secrets-store-creds secrets-store.csi.k8s.io/used=true
    
  5. SecretProviderClass Создайте следующий YAML, заполнив значения для имени хранилища ключей, идентификатора клиента и объектов для получения из экземпляра AKV:

    # This is a SecretProviderClass example using service principal to access Keyvault
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: akvprovider-demo
    spec:
      provider: azure
      parameters:
        usePodIdentity: "false"
        keyvaultName: <key-vault-name>
        cloudName:                           # Defaults to AzurePublicCloud
        objects:  |
          array:
            - |
              objectName: DemoSecret
              objectType: secret             # object types: secret, key or cert
              objectVersion: ""              # [OPTIONAL] object versions, default to latest if empty
        tenantId: <tenant-Id>                # The tenant ID of the Azure Key Vault instance
    

    Для использования с национальными облаками перейдите cloudName на AzureUSGovernmentCloud Azure для государственных организаций или AzureChinaCloud на Microsoft Azure под управлением 21Vianet.

  6. Примените SecretProviderClass к своему кластеру:

    kubectl apply -f secretproviderclass.yaml
    
  7. Создайте модуль pod с помощью следующего кода YAML, указав имя своего удостоверения:

    # This is a sample pod definition for using SecretProviderClass and service principal to access Keyvault
    kind: Pod
    apiVersion: v1
    metadata:
      name: busybox-secrets-store-inline
    spec:
      containers:
        - name: busybox
          image: k8s.gcr.io/e2e-test-images/busybox:1.29
          command:
            - "/bin/sleep"
            - "10000"
          volumeMounts:
          - name: secrets-store-inline
            mountPath: "/mnt/secrets-store"
            readOnly: true
      volumes:
        - name: secrets-store-inline
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: "akvprovider-demo"
            nodePublishSecretRef:                       
              name: secrets-store-creds
    
  8. Примените модуль pod к кластеру:

    kubectl apply -f pod.yaml
    

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

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

## show secrets held in secrets-store
kubectl exec busybox-secrets-store-inline -- ls /mnt/secrets-store/

## print a test secret 'DemoSecret' held in secrets-store
kubectl exec busybox-secrets-store-inline -- cat /mnt/secrets-store/DemoSecret

Дополнительные параметры конфигурации

Расширение поставщика секретов Azure Key Vault поддерживает конфигурации диаграмм Helm.

Следующие параметры конфигурации часто используются с расширением поставщика секретов Azure Key Vault:

Параметр конфигурации По умолчанию. Description
enableSecretRotation false Логический тип. Если установлено значение true, подключение pod и секрет Kubernetes периодически обновляются с добавлением последнего содержимого из внешнего хранилища секретов.
rotationPollInterval 2 м Если enableSecretRotation это trueтак, этот параметр задает длительность интервала опроса поворота секретов. Эту длительность можно настроить в зависимости от частоты повторной синхронизации подключенного содержимого для всех модулей pod и секретов Kubernetes с последней версией.
syncSecret.enabled false Логические входные данные. В некоторых случаях, возможно, вам нужно будет создать секрет Kubernetes для зеркалирования подключенного содержимого. Если задано значение true, SecretProviderClass позволяет полю secretObjects определить требуемое состояние синхронизированных объектов секретов Kubernetes.

Эти параметры можно указать при установке расширения с помощью команды az k8s-extension create:

az k8s-extension create --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --cluster-type connectedClusters --extension-type Microsoft.AzureKeyVaultSecretsProvider --name akvsecretsprovider --configuration-settings secrets-store-csi-driver.enableSecretRotation=true secrets-store-csi-driver.rotationPollInterval=3m secrets-store-csi-driver.syncSecret.enabled=true

Эти параметры также можно изменить после установки с помощью az k8s-extension update команды:

az k8s-extension update --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --cluster-type connectedClusters --name akvsecretsprovider --configuration-settings secrets-store-csi-driver.enableSecretRotation=true secrets-store-csi-driver.rotationPollInterval=3m secrets-store-csi-driver.syncSecret.enabled=true

При необходимости можно использовать другие параметры конфигурации. Например, чтобы изменить корневой каталог kubelet при создании кластера, измените az k8s-extension create команду:

az k8s-extension create --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --cluster-type connectedClusters --extension-type Microsoft.AzureKeyVaultSecretsProvider --name akvsecretsprovider --configuration-settings linux.kubeletRootDir=/path/to/kubelet secrets-store-csi-driver.linux.kubeletRootDir=/path/to/kubelet

Удаление расширения поставщика секретов Azure Key Vault

Чтобы удалить расширение, выполните следующую команду:

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

Примечание.

При удалении расширения не удаляются пользовательские определения ресурсов (CRD), созданные при установке расширения.

Чтобы убедиться, что экземпляр расширения удален, выполните следующую команду:

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

Если расширение было успешно удалено, вы не увидите расширение поставщика секретов Azure Key Vault, указанное в выходных данных. Если в кластере не установлены другие расширения, отобразится пустой массив.

Если он больше не нужен, обязательно удалите секрет Kubernetes, связанный с субъектом-службой, выполнив следующую команду:

kubectl delete secret secrets-store-creds

Выверка и устранение неполадок

Расширение поставщика секретов Azure Key Vault восстанавливается автоматически. Если кто-то пытается изменить или удалить компонент расширения, развернутый при установке расширения, этот компонент примирится с исходным состоянием. Исключение делается только для пользовательских определений ресурсов (CRD). Если определения CRD удаляются, выверка не выполняется. Чтобы восстановить удаленные определения CRD, еще раз используйте команду az k8s-extension create с существующим именем экземпляра расширения.

Дополнительные сведения об устранении распространенных проблем см. в руководствах по устранению неполадок с открытым кодом для поставщика Azure Key Vault для драйвера CSI хранилища секретов и самого драйвера CSI хранилища секретов.

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