Share via


Uso de la extensión del proveedor de secretos de Azure Key Vault para capturar secretos en clústeres de Kubernetes habilitados para Azure Arc

El proveedor de Azure Key Vault para el controlador CSI de Secrets Store permite la integración de Azure Key Vault como un almacén de secretos con un clúster de Kubernetes mediante un volumen CSI. En el caso de los clústeres de Kubernetes habilitados para Azure Arc, puede instalar la extensión del proveedor de secretos de Azure Key Vault para capturar secretos.

Las capacidades de la extensión Proveedor de secretos de Azure Key Vault incluyen:

  • Monta secretos, claves o certificados en el pod mediante un volumen en línea de CSI.
  • Admite la portabilidad de pods con CRD de SecretProviderClass
  • Admite los contenedores de Linux y Windows.
  • Admite los secretos de Kubernetes.
  • Admite la rotación automática de secretos.
  • Los componentes de la extensión se implementan en zonas de disponibilidad, lo que hace que sean componentes con redundancia de zona.

Requisitos previos

  • Un clúster con una distribución de Kubernetes compatible que ya se ha conectado a Azure Arc. Actualmente se admiten las siguientes distribuciones de Kubernetes para este escenario:
    • Cluster API de Azure
    • Clústeres de Azure Kubernetes Service (AKS) en Azure Stack HCI
    • AKS habilitado por Azure Arc
    • Google Kubernetes Engine
    • Distribución OpenShift Kubernetes
    • Distribución Canonical Kubernetes
    • Elastic Kubernetes Service
    • Tanzu Kubernetes Grid
    • Red Hat OpenShift en Azure
  • Asegúrese de cumplir con los requisitos previos generales para las extensiones de clúster. Debe usar la versión 0.4.0 o una más reciente de la extensión de la CLI de Azure k8s-extension.

Instalación de la extensión del proveedor de secretos de Azure Key Vault en un clúster de Kubernetes habilitado para Arc

Puede instalar la extensión del proveedor de secretos de Azure Key Vault en el clúster conectado en Azure Portal, mediante la CLI de Azure o mediante la implementación de una plantilla de ARM.

Solo se puede implementar una instancia de la extensión en cada clúster de Kubernetes habilitado para Azure Arc.

Sugerencia

Si el clúster está detrás de un servidor proxy de salida, asegúrese de conectarlo a Azure Arc mediante la opción de configuración de proxy antes de instalar la extensión.

Azure portal

  1. En Azure Portal, vaya a Kubernetes: Azure Arc y seleccione el clúster.

  2. Seleccione Extensiones (en Configuración) y después + Agregar.

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

  3. En la lista de extensiones disponibles, seleccione Proveedor de secretos de Azure Key Vault para implementar la versión más reciente de la extensión.

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

  4. Siga las indicaciones para implementar la extensión. Si es necesario, cambie las opciones predeterminadas en la pestaña Configuración para personalizar la instalación.

Azure CLI

  1. Establezca las variables de entorno:

    export CLUSTER_NAME=<arc-cluster-name>
    export RESOURCE_GROUP=<resource-group-name>
    
  2. Instale el controlador CSI del almacén de secretos y la extensión del proveedor de secretos de Azure Key Vault mediante la ejecución del comando siguiente:

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

Debería ver una salida similar a la de este ejemplo. Tenga en cuenta que el gráfico de Helm del proveedor de secretos puede tardar varios minutos en implementarse en el clúster.

{
  "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"
}

Plantilla ARM

  1. Cree un archivo .json con el formato siguiente. Asegúrese de actualizar el valor de <cluster-name> para hacer referencia al clúster.

    {
        "$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. Ahora establezca las variables de entorno mediante el siguiente comando de la CLI de Azure:

    export TEMPLATE_FILE_NAME=<template-file-path>
    export DEPLOYMENT_NAME=<desired-deployment-name>
    
  3. Por último, ejecute este comando de la CLI de Azure para instalar la extensión del proveedor de secretos de Azure Key Vault:

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

Ahora, debería poder ver los recursos del proveedor de secretos y usar la extensión en el clúster.

Validación de la instalación de la extensión

Para confirmar que la instalación de la extensión del proveedor de secretos de Azure Key Vault se realizó correctamente, ejecute el siguiente comando.

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

Debería ver una salida similar a la de este ejemplo.

{
  "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"
}

Creación o selección de una instancia de Azure Key Vault

A continuación, especifique la instancia de Azure Key Vault que se usará con el clúster conectado. Si aún no tiene ninguna, cree una nueva instancia de Key Vault mediante los siguientes comandos. Tenga en cuenta que el nombre de la instancia del almacén de claves debe ser único globalmente.

Establezca estas variables de entorno:

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

Luego, ejecute el siguiente comando:

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

Azure Key Vault puede almacenar claves, secretos y certificados. En este ejemplo, puede establecer un secreto de texto sin formato llamado DemoSecret mediante el siguiente comando:

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

Antes de pasar a la sección siguiente, tome nota de las siguientes propiedades:

  • Nombre del objeto secreto en Key Vault
  • Tipo de objeto (secreto, clave o certificado)
  • Nombre del recurso de Key Vault
  • Identificador de inquilino de Azure de la suscripción a la que pertenece la instancia de Key Vault

Proporcionar la identidad para acceder a Azure Key Vault

Actualmente, se puede acceder al controlador CSI del almacén de secretos en clústeres habilitados para Arc a través de una entidad de servicio. Siga estos pasos para proporcionar una identidad que pueda acceder a la instancia de Key Vault.

  1. Siga los pasos para crear una entidad de servicio en Azure. Tome nota del identificador y el secreto de cliente generados en este paso.

  2. A continuación, asegúrese de que Azure Key Vault tiene permiso GET para la entidad de servicio creada.

  3. Use el id. de cliente y el secreto de cliente del primer paso para crear un secreto de Kubernetes en el clúster conectado:

    kubectl create secret generic secrets-store-creds --from-literal clientid="<client-id>" --from-literal clientsecret="<client-secret>"
    
  4. Etiquete el secreto creado:

    kubectl label secret secrets-store-creds secrets-store.csi.k8s.io/used=true
    
  5. Cree un SecretProviderClass con el siguiente código YAML, rellenando los valores para el nombre del almacén de claves, el identificador de inquilino y los objetos que se van a recuperar de la instancia de 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
    

    Para su uso con nubes nacionales, cambie cloudName a AzureUSGovernmentCloud para Azure Government o a AzureChinaCloud para Microsoft Azure operado por 21Vianet.

  6. Aplique el objeto SecretProviderClass al clúster:

    kubectl apply -f secretproviderclass.yaml
    
  7. Cree un pod con el siguiente código YAML, en el que debe rellenar el nombre de la identidad:

    # 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. Aplique el pod al clúster:

    kubectl apply -f pod.yaml
    

Validación de los secretos

Una vez que se inicia el pod, el contenido montado en la ruta del volumen especificada en el archivo YAML de implementación estará disponible.

## 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

Opciones de configuración adicionales

La extensión del Proveedor de secretos de Azure Key Vault es compatible con las configuraciones de gráficos de Helm.

Los siguientes ajustes de configuración se usan con frecuencia con la extensión Proveedor de secretos de Azure Key Vault:

Opción de configuración Valor predeterminado Descripción
enableSecretRotation false Tipo booleano. Si es true, actualiza periódicamente el montaje del pod y el secreto de Kubernetes con el contenido más reciente del almacén de secretos externo.
rotationPollInterval 2 m Si enableSecretRotation es true, este ajuste especifica la duración del intervalo de sondeo de rotación secreta. Esta duración se puede ajustar en función de la frecuencia con la que el contenido montado de todos los pods y los secretos de Kubernetes deben resincronizarse a la versión más reciente.
syncSecret.enabled false Entrada booleana. En algunos casos, es posible que quiera crear un secreto de Kubernetes para reflejar el contenido montado. Si es true, SecretProviderClass permite que el campo secretObjects defina el estado deseado de los objetos secretos de Kubernetes sincronizados.

Esta configuración se puede especificar cuando se instala la extensión mediante el comando 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

También se puede cambiar la configuración después de la instalación mediante el comando 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

Puede usar otras opciones de configuración según sea necesario para la implementación. Por ejemplo, para cambiar el directorio raíz de kubelet al crear un clúster, modifique el comando 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

Desinstalación de la extensión del proveedor de secretos de Azure Key Vault

Para desinstalar la extensión, ejecute el comando siguiente:

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

Nota

La desinstalación de la extensión no elimina las definiciones de recursos personalizados (CRD) que se crearon cuando se instaló la extensión.

Para confirmar que se ha eliminado la instancia de la extensión, ejecute el siguiente comando:

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

Si la extensión se quitó correctamente, no verá la extensión del proveedor de secretos de Azure Key Vault en la salida. Si no tiene ninguna otra extensión instalada en el clúster, verá una matriz vacía.

Si ya no lo necesita, asegúrese de eliminar el secreto de Kubernetes asociado a la entidad de servicio mediante la ejecución del siguiente comando:

kubectl delete secret secrets-store-creds

Conciliación y solución de problemas

La extensión del proveedor de secretos de Azure Key Vault se recupera de forma automática. Si alguien intenta cambiar o eliminar un componente de la extensión que estaba implementado cuando se instaló la extensión, dicho componente se reconcilia con su estado original. Las únicas excepciones son para las definiciones de recursos personalizados (CRD). Si las CRD se eliminan, no se conciliarán. Para restaurar las CRD eliminadas, use el comando az k8s-extension create de nuevo con el nombre de la instancia de la extensión existente.

Para obtener más información sobre cómo resolver problemas comunes, consulte las guías de solución de problemas de código abierto sobre el proveedor de Azure Key Vault para el controlador CSI del almacén de secretos y el controlador CSI del almacén de secretos.

Pasos siguientes