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 ejecuteaz upgrade
para actualizar la versión. Si necesita instalarla o actualizarla, vea Instalación de la CLI de Azure.La extensión
aks-preview
CLI 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
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.
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
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:
- Siga los pasos para registrar la marca de la característica KataVMIsolationPreview.
- Compruebe que el clúster ejecuta la versión 1.25.0 o posterior de Kubernetes.
- Habilite la identidad de carga de trabajo en el clúster si aún no lo está.
Use el comando siguiente para habilitar Contenedores confidenciales (versión preliminar) mediante la creación de un grupo de nodos para hospedarlo.
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.
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.
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.
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:
La identidad administrada es el valor que asignó a la
USER_ASSIGNED_IDENTITY_NAME
variable.Para agregar asignaciones de roles, debe tener permisos
Microsoft.Authorization/roleAssignments/write
yMicrosoft.Authorization/roleAssignments/delete
, como Administrador de acceso a datos de Key Vault,administrador de acceso de usuarioo propietario.Debe usar la SKU premium de Key Vault para admitir claves protegidas con HSM.
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
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
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
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
.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.
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 protocolohttps://
. El valor actual del marcador de posición de valor esmyKeyVault.vault.azure.net
. Actualice el valor de la variable de entorno de podSkrClientMAAEndpoint
con el valor deMAA_ENDPOINT
. Puede encontrar el valor deMAA_ENDPOINT
si ejecuta el comandoecho $MAA_ENDPOINT
o el comandoaz attestation show --name "myattestationprovider" --resource-group "MyResourceGroup" --query 'attestUri' -o tsv | cut -c 9-
.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)
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 Bashsetup-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.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
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 dekafka-encryption-demo-pub.pem
que se creó en el paso anterior.Implemente los manifiestos
consumer
yproducer
YAML mediante los archivos que guardó anteriormente.kubectl apply -f consumer.yaml
kubectl apply -f producer.yaml
Obtenga la dirección IP del servicio web mediante el comando siguiente:
kubectl get svc consumer -n kafka
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
También debe intentar ejecutar el consumidor como pod de Kubernetes normal quitando la especificación de
skr container
ykata-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.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.
Azure Kubernetes Service