Compartir por


Implementación de un clúster de AKS con contenedores confidenciales y una directiva predeterminada

En este artículo, usará la CLI de Azure para implementar un clúster de Azure Kubernetes Service (AKS) y configurar contenedores confidenciales (versión preliminar) con una directiva de seguridad predeterminada. A continuación, implementará una aplicación como contenedor confidencial. Para más información, leer la información general de los contenedores confidenciales de AKS.

En general, la introducción a los contenedores confidenciales de AKS implica los pasos siguientes.

  • Implementación o actualización de un clúster de AKS mediante la CLI de Azure
  • Agregue una anotación al manifiesto YAML del pod para marcar el pod como que se ejecuta como un contenedor confidencial
  • Adición de una directiva de seguridad al manifiesto YAML de pod
  • Habilitación del cumplimiento de la directiva de seguridad
  • Implementación de la aplicación en computación confidencial

Requisitos previos

  • La CLI de Azure, versión 2.44.1 o posterior. Ejecute az --version para buscar la versión y ejecute az upgrade para actualizar la versión. Si necesita instalarla o actualizarla, vea Instalación de la CLI de Azure.

  • La extensiónaks-previewCLI de Azure versión 0.5.169 o posterior.

  • La extensión confcom de la CLI de Azure de contenedor confidencial 0.3.3 o posterior. confcom es necesario para generar unadirectiva de seguridad.

  • Registre la característica Preview en la suscripción de Azure.

  • AKS admite contenedores confidenciales (versión preliminar) en la versión 1.25.0 y posteriores.

  • Una identidad de carga de trabajo y una credencial de identidad federada. La credencial de identidad de carga de trabajo habilita el acceso de las aplicaciones Kubernetes a los recursos Azure de forma segura con un Id. de Microsoft Entra basado en cuentas de servicio anotadas. Si no está familiarizado con el id. de carga de trabajo de Microsoft Entra, consulte la información general del id. de carga de trabajo de Microsoft Entra y revise cómo funciona identidad de carga de trabajo con AKS.

  • La identidad que usa para crear el clúster tiene los permisos mínimos adecuados. Para más información sobre el acceso y la identidad en AKS, consulte Opciones de acceso e identidad en Azure Kubernetes Service (AKS).

  • Para administrar un clúster de Kubernetes, use kubectl, el cliente de línea de comandos de Kubernetes. Azure Cloud Shell viene con kubectl. Puede instalar kubectl localmente. Para ello debe usar el comando az aks install-cli.

  • Los contenedores confidenciales de AKS proporcionan un contenedor de código abierto sidecar para la atestación y la versión de clave segura. El sidecar se integra con un servicio de administración de claves (KMS), como Azure Key Vault, para liberar una clave al grupo de contenedores una vez completada la validación. La implementación de un HSM administrado por Azure Key Vault (módulo de seguridad de hardware) es opcional, pero se recomienda admitir la integridad y la atestación de nivel de contenedor. Consulte Aprovisionamiento y activación de un HSM administrado para implementar HSM administrado.

Instalación de la versión preliminar de la extensión de la CLI de Azure en versión preliminar de AKS

Importante

Las características en versión preliminar de AKS están disponibles como opción de participación y autoservicio. Las versiones preliminares se proporcionan "tal cual" y "como están disponibles", y están excluidas de los Acuerdos de nivel de servicio y garantía limitada. Las versiones preliminares de AKS reciben cobertura parcial del soporte al cliente en la medida de lo posible. Por lo tanto, estas características no están diseñadas para su uso en producción. Para más información, consulte los siguientes artículos de soporte:

Ejecute el siguiente comando para instalar la extensión de versión preliminar de AKS:

az extension add --name aks-preview

Ejecute el siguiente comando para actualizar a la versión más reciente de la extensión publicada:

az extension update --name aks-preview

Instalación de la extensión confcom de la CLI de Azure

Para instalar la extensión confcom, ejecute el siguiente comando:

az extension add --name confcom

Ejecute el siguiente comando para actualizar a la versión más reciente de la extensión publicada:

az extension update --name confcom

Registrar la marca de característica KataCcIsolationPreview

Registre la marca de la característica KataCcIsolationPreview con el comando KataCcIsolationPreview, como se muestra en el siguiente ejemplo:

az feature register --namespace "Microsoft.ContainerService" --name "KataCcIsolationPreview"

Tarda unos minutos en que el estado muestre Registrado. Para comprobar el estado de registro se usa el comandoaz feature show:

az feature show --namespace "Microsoft.ContainerService" --name "KataCcIsolationPreview"

Cuando aparezca el estado Registrado, actualice el registro del proveedor de recursos Microsoft.ContainerService mediante el comando az provider register:

az provider register --namespace "Microsoft.ContainerService"

Implemente un nuevo clúster

  1. Cree un clúster de AKS mediante el comando az aks create y especifique los parámetros siguientes:

    • --os-sku: AzureLinux. Solo os-sku de Linux en Azure admite esta característica en esta versión preliminar.
    • --node-vm-size: Cualquier tamaño de VM de Azure que sea una VM de 2.ª generación y admita trabajos de virtualización anidada. Por ejemplo, Standard_DC8as_cc_v5 máquinas virtuales.
    • --enable-workload-identity: Habilita la creación de un Id. de carga de trabajo de Microsoft Entra que permita que los pods usen una identidad de Kubernetes.
    • --enable-oidc-issuer: habilita el emisor de OpenID Connect (OIDC). Permite que un Microsoft Entra ID u otra plataforma de administración de identidades y acceso del proveedor de nube pueda detectar las claves de firma pública del servidor de API.

    En el ejemplo siguiente se actualiza el clúster denominado myAKSCluster y se crea un único grupo de nodos del sistema en myResourceGroup:

    az aks create --resource-group myResourceGroup --name myAKSCluster --kubernetes-version <1.25.0 and above> --os-sku AzureLinux --node-vm-size Standard_DC4as_cc_v5 --node-count 1 --enable-oidc-issuer --enable-workload-identity --generate-ssh-keys
    

    Transcurridos unos minutos, el comando se completa y devuelve información en formato JSON sobre el clúster. El clúster creado en el paso anterior tiene un grupo de nodo único. En el paso siguiente, agregamos un segundo grupo de nodos al clúster.

  2. Cuando el clúster esté listo, obtenga las credenciales del clúster mediante el comando az aks get-credentials.

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
    
  3. Agregue un grupo de nodos de usuario a myAKSCluster con dos nodos en nodepool2 en myResourceGroup mediante el comando az aks nodepool add . Especifique los parámetros siguientes:

    • --workload-runtime: especifique KataCcIsolation para habilitar la característica Contenedores confidenciales en el grupo de nodos. Con este parámetro, estos otros parámetros cumplirán los siguientes requisitos. De lo contrario, se produce un error en el comando e informa de un problema con los parámetros correspondientes.
    • --os-sku: AzureLinux. Solo os-sku de Linux en Azure admite esta característica en esta versión preliminar.
    • --node-vm-size: Cualquier tamaño de VM de Azure que sea una VM de 2.ª generación y admita trabajos de virtualización anidada. Por ejemplo, Standard_DC8as_cc_v5 máquinas virtuales.
    az aks nodepool add --resource-group myResourceGroup --name nodepool2 --cluster-name myAKSCluster --node-count 2 --os-sku AzureLinux --node-vm-size Standard_DC4as_cc_v5 --workload-runtime KataCcIsolation
    

Transcurridos unos minutos, el comando se completa y devuelve información en formato JSON sobre el clúster.

Implementación en un clúster existente

Para usar esta característica con un clúster de AKS existente, se deben cumplir los siguientes requisitos:

Use el comando siguiente para habilitar Contenedores confidenciales (versión preliminar) mediante la creación de un grupo de nodos para hospedarlo.

  1. Agregue un grupo de nodos al clúster de AKS mediante el comando az aks nodepool add. Especifique los parámetros siguientes:

    • --resource-group: Escriba el nombre de un grupo de recursos existente en el que va a crear el clúster de AKS.
    • --cluster-name: Escriba un nombre único para el clúster de AKS, como myAKSCluster.
    • --name: Escriba un nombre único para el grupo de nodos de clústeres, como nodepool2.
    • --workload-runtime: especifique KataCcIsolation para habilitar la característica en el grupo de nodos. Junto con el parámetro --workload-runtime, estos otros parámetros cumplirán los siguientes requisitos. De lo contrario, se produce un error en el comando e informa de un problema con los parámetros correspondientes.
    • --os-sku: AzureLinux. Solo os-sku de Linux en Azure admite esta característica en esta versión preliminar.
    • --node-vm-size: Cualquier tamaño de VM de Azure que sea una VM de 2.ª generación y admita trabajos de virtualización anidada. Por ejemplo, Standard_DC8as_cc_v5 máquinas virtuales.

    En el ejemplo siguiente se agrega un grupo de nodos a myAKSCluster con dos nodos en nodepool2 en el myResourceGroup:

    az aks nodepool add --resource-group myResourceGroup --name nodepool2 –-cluster-name myAKSCluster --node-count 2 --os-sku AzureLinux --node-vm-size Standard_DC4as_cc_v5 --workload-runtime KataCcIsolation
    

    Transcurridos unos minutos, el comando se completa y devuelve información en formato JSON sobre el clúster.

  2. Ejecute el comando az aks update para habilitar Contenedores confidenciales (versión preliminar) en el clúster.

    az aks update --name myAKSCluster --resource-group myResourceGroup
    

    Transcurridos unos minutos, el comando se completa y devuelve información en formato JSON sobre el clúster.

  3. Cuando el clúster esté listo, obtenga las credenciales del clúster mediante el comando az aks get-credentials.

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
    

Configuración del contenedor

Antes de configurar el acceso a Azure Key Vault y el secreto, y de implementar una aplicación como contenedor confidencial, debe completar la configuración de la identidad de la carga de trabajo.

Para configurar la identidad de carga de trabajo, siga estos pasos descritos en el artículo Implementación y configuración de la identidad de carga de trabajo:

  • Obtener la dirección URL del emisor de OIDC
  • Creación de una entidad administrada
  • Creación de una cuenta de servicio de Kubernetes
  • Establecimiento de una credencial de identidad federada

Importante

Debe establecer las variables de entorno de la sección Exportar variables de entorno en el artículo Implementación y configuración de la identidad de carga de trabajo para completar este tutorial. Recuerde establecer la variable SERVICE_ACCOUNT_NAMESPACE en kafka y ejecutar el comando kubectl create namespace kafka antes de configurar la identidad de carga de trabajo.

Implementación de una aplicación de confianza con kata-cc y contenedor de atestación

En los pasos siguientes se configura el cifrado de un extremo a otro para los mensajes de Kafka mediante claves de cifrado administradas por Módulos de seguridad de hardware administrados de Azure (mHSM). La clave solo se libera cuando el consumidor de Kafka se ejecuta dentro de un contenedor confidencial con un contenedor de aprovisionamiento de secretos de atestación de Azure insertado en el pod.

Esta configuración se basa en los cuatro componentes siguientes:

  • Clúster de Kafka: un clúster de Kafka simple implementado en el espacio de nombres de Kafka en el clúster.
  • Productor de Kafka: productor de Kafka que se ejecuta como pod de Kubernetes de vainilla que envía mensajes cifrados configurados por el usuario mediante una clave pública a un tema de Kafka.
  • Consumidor de Kafka: un pod de consumidor de Kafka que se ejecuta con el entorno de ejecución kata-cc, equipado con un contenedor de versión de claves segura para recuperar la clave privada para descifrar los mensajes de Kafka y representar los mensajes en la interfaz de usuario web.

Para esta versión preliminar, recomendamos, con fines de prueba y evaluación, crear o usar un recurso de nivel Premium de Azure Key Vault existente que admita el almacenamiento de claves en un módulo de seguridad de hardware (HSM). No se recomienda usar el almacén de claves de producción. Si no tiene una instancia de Azure Key Vault, consulte Creación de un almacén de claves mediante la CLI de Azure.

  1. Conceda a la identidad administrada que creó anteriormente y su cuenta, acceso al almacén de claves. Asignar ambas identidades a los roles Agente criptográfico de Key Vault y Usuario criptográfico de Key Vault Azure RBAC.

    Nota:

    Ejecute el siguiente comando para establecer el ámbito:

    AKV_SCOPE=$(az keyvault show --name <AZURE_AKV_RESOURCE_NAME> --query id --output tsv)
    

    Ejecute el siguiente comando para asignar el rol Agente criptográfico de Key Vault.

    az role assignment create --role "Key Vault Crypto Officer" --assignee "${USER_ASSIGNED_IDENTITY_NAME}" --scope $AKV_SCOPE
    

    Ejecute el siguiente comando para asignar el rol de Usuario criptográfico de Key Vault.

    az role assignment create --role "Key Vault Crypto User" --assignee "${USER_ASSIGNED_IDENTITY_NAME}" --scope $AKV_SCOPE
    
  2. Ejecute el siguiente comando para instalar el clúster de Kafka en el espacio de nombres de Kafka:

    kubectl create -f 'https://strimzi.io/install/latest?namespace=kafka' -n kafka
    
  3. Ejecute el siguiente comando para aplicar el archivo CR del clúster de kafka.

    kubectl apply -f https://strimzi.io/examples/latest/kafka/kafka-persistent-single.yaml -n kafka
    
  4. Prepare la clave de cifrado/descifrado RSA mediante el script de Bash para la carga de trabajo desde GitHub. Guarde el archivo como setup-key.sh.

  5. Establezca la variable de entorno MAA_ENDPOINT con el FQDN de URI de atestación mediante la ejecución del comando siguiente.

    export MAA_ENDPOINT="$(az attestation show --name "myattestationprovider" --resource-group "MyResourceGroup" --query 'attestUri' -o tsv | cut -c 9-)"
    

    Compruebe si el FQDN del URI de atestación tiene el formato correcto (MAA_ENDPOINT no debe incluir el prefijo "https://"):

    echo $MAA_ENDPOINT
    

    Nota:

    Para configurar Microsoft Azure Attestation, consulte Inicio rápido: Configuración de Azure Attestation con la CLI de Azure.

  6. Copie el siguiente manifiesto DE YAML y guárdelo como consumer.yaml.

    apiVersion: v1
    kind: Pod
    metadata:
      name: kafka-golang-consumer
      namespace: kafka
      labels:
        azure.workload.identity/use: "true"
        app.kubernetes.io/name: kafka-golang-consumer
    spec:
      serviceAccountName: workload-identity-sa
      runtimeClassName: kata-cc-isolation
      containers:
        - image: "mcr.microsoft.com/aci/skr:2.7"
          imagePullPolicy: Always
          name: skr
          env:
            - name: SkrSideCarArgs
              value: ewogICAgImNlcnRjYWNoZSI6IHsKCQkiZW5kcG9pbnRfdHlwZSI6ICJMb2NhbFRISU0iLAoJCSJlbmRwb2ludCI6ICIxNjkuMjU0LjE2OS4yNTQvbWV0YWRhdGEvVEhJTS9hbWQvY2VydGlmaWNhdGlvbiIKCX0gIAp9
          command:
            - /bin/skr
          volumeMounts:
            - mountPath: /opt/confidential-containers/share/kata-containers/reference-info-base64
              name: endor-loc
        - image: "mcr.microsoft.com/acc/samples/kafka/consumer:1.0"
          imagePullPolicy: Always
          name: kafka-golang-consumer
          env:
            - name: SkrClientKID
              value: kafka-encryption-demo
            - name: SkrClientMAAEndpoint
              value: sharedeus2.eus2.test.attest.azure.net
            - name: SkrClientAKVEndpoint
              value: "myKeyVault.vault.azure.net"
            - name: TOPIC
              value: kafka-demo-topic
          command:
            - /consume
          ports:
            - containerPort: 3333
              name: kafka-consumer
          resources:
            limits:
              memory: 1Gi
              cpu: 200m
      volumes:
        - name: endor-loc
          hostPath:
            path: /opt/confidential-containers/share/kata-containers/reference-info-base64
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: consumer
      namespace: kafka
    spec:
      type: LoadBalancer
      selector:
        app.kubernetes.io/name: kafka-golang-consumer
      ports:
        - protocol: TCP
          port: 80
          targetPort: kafka-consumer
    

    Nota:

    Actualice el valor de la variable de entorno de pod SkrClientAKVEndpoint para que coincida con la dirección URL de Azure Key Vault, excepto el valor del protocolo https://. El valor actual del marcador de posición de valor es myKeyVault.vault.azure.net. Actualice el valor de la variable de entorno de pod SkrClientMAAEndpoint con el valor de MAA_ENDPOINT. Puede encontrar el valor de MAA_ENDPOINT si ejecuta el comando echo $MAA_ENDPOINT o el comando az attestation show --name "myattestationprovider" --resource-group "MyResourceGroup" --query 'attestUri' -o tsv | cut -c 9-.

  7. Genere la directiva de seguridad para el manifiesto YAML del consumidor de Kafka y obtenga el hash de la directiva de seguridad almacenada en la WORKLOAD_MEASUREMENT variable ejecutando el siguiente comando:

    export WORKLOAD_MEASUREMENT=$(az confcom katapolicygen -y consumer.yaml --print-policy | base64 -d | sha256sum | cut -d' ' -f1)
    
  8. Para generar un par de claves asimétricas RSA (claves públicas y privadas), ejecute el script setup-key.sh mediante el comando siguiente. El valor <Azure Key Vault URL> debe ser <your-unique-keyvault-name>.vault.azure.net

    export MANAGED_IDENTITY=${USER_ASSIGNED_CLIENT_ID}
    bash setup-key.sh "kafka-encryption-demo" <Azure Key Vault URL>
    

    Nota:

    • La variable de entorno MANAGED_IDENTITY requiere el script de Bash setup-key.sh.

    • La clave pública se guardará como kafka-encryption-demo-pub.pem después de ejecutar el script de Bash.

    Importante

    Si recibe el error ForbiddenByRbac, puede que tenga que esperar hasta 24 horas, ya que los servicios back-end para identidades administradas conservan una memoria caché por URI de recurso durante un máximo de 24 horas. Consulte Solución de problemas de Azure RBA.

  9. Para comprobar que las claves se han cargado correctamente en el almacén de claves, ejecute los comandos siguientes:

    az account set --subscription <Subscription ID>
    az keyvault key list --vault-name <KeyVault Name> -o table
    
  10. Copie el siguiente manifiesto DE YAML y guárdelo como producer.yaml.

    apiVersion: v1
    kind: Pod
    metadata:
      name: kafka-producer
      namespace: kafka
    spec:
      containers:
        - image: "mcr.microsoft.com/acc/samples/kafka/producer:1.0"
          name: kafka-producer
          command:
            - /produce
          env:
            - name: TOPIC
              value: kafka-demo-topic
            - name: MSG
              value: "Azure Confidential Computing"
            - name: PUBKEY
              value: |-
                -----BEGIN PUBLIC KEY-----
                MIIBojAN***AE=
                -----END PUBLIC KEY-----
          resources:
            limits:
              memory: 1Gi
              cpu: 200m
    

    Nota:

    Actualice el valor que comienza por -----BEGIN PUBLIC KEY----- y termina en -----END PUBLIC KEY----- con el contenido de kafka-encryption-demo-pub.pem que se creó en el paso anterior.

  11. Implemente los manifiestosconsumeryproducer YAML mediante los archivos que guardó anteriormente.

    kubectl apply -f consumer.yaml
    
    kubectl apply -f producer.yaml
    
  12. Obtenga la dirección IP del servicio web mediante el comando siguiente:

    kubectl get svc consumer -n kafka
    
  13. Copie y pegue la dirección IP externa del servicio de consumidor en el explorador y observe el mensaje descifrado.

    La salida del comando es similar al ejemplo siguiente:

    Welcome to Confidential Containers on AKS!
    Encrypted Kafka Message:
    Msg 1: Azure Confidential Computing
    
  14. También debe intentar ejecutar el consumidor como pod de Kubernetes normal quitando la especificación de skr container y kata-cc runtime class. Puesto que no está ejecutando el consumidor con la clase en tiempo de ejecución kata-cc, ya no necesita la directiva.

  15. Quite toda la directiva y observe los mensajes de nuevo en el explorador después de volver a implementar la carga de trabajo. Los mensajes aparecen como texto cifrado codificado en base64 porque no se puede recuperar la clave de cifrado privada. La clave no se puede recuperar porque el consumidor ya no se ejecuta en un entorno confidencial, y falta el skr container, lo que impide el descifrado de mensajes.

Limpieza

Cuando haya terminado de evaluar esta característica, para evitar cargos de Azure, limpie los recursos innecesarios. Si ha implementado un nuevo clúster como parte de la evaluación o prueba, puede eliminar el clúster con el comando az aks delete.

az aks delete --resource-group myResourceGroup --name myAKSCluster

Si ha habilitado Contenedores confidenciales (versión preliminar) en un clúster existente, puede quitar los pods mediante el comando kubectl delete pod.

kubectl delete pod pod-name

Pasos siguientes

  • Obtenga más información sobre los hosts dedicados de Azure para los nodos con el clúster de AKS para usar el aislamiento de hardware y el control sobre los eventos de mantenimiento iniciados por la plataforma Azure.