Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo, aprenderá a implementar y configurar un clúster de Azure Kubernetes Service (AKS) con Id. de carga de trabajo de Microsoft Entra. Los pasos de este artículo incluyen:
- Cree un clúster de AKS nuevo o actualice uno existente mediante el emisor de CLI de Azure o Terraform con openID Connect (OIDC) y Id. de carga de trabajo de Microsoft Entra habilitados.
- Cree una identidad de carga de trabajo y una cuenta de servicio de Kubernetes.
- Configurar la identidad administrada para la federación de tokens.
- Implementar la carga de trabajo y comprobar la autenticación con la identidad de carga de trabajo.
- Opcionalmente, conceda a un pod del clúster acceso a los secretos de un almacén de claves de Azure.
Requisitos previos
- Si no tiene una cuenta de Azure, cree una cuenta free antes de comenzar.
- Este artículo requiere la versión 2.47.0 o posterior del CLI de Azure. Si usa Azure Cloud Shell, la versión más reciente ya está instalada. Ejecute
az --versionpara encontrar la versión. Si necesita instalar o actualizar, consulte Install CLI de Azure. - Asegúrese de que la identidad que use para crear el clúster tenga los permisos mínimos adecuados. Para obtener más información, vea Acceso y opciones de identidad para Azure Kubernetes Service (AKS).
- Asegúrese de que su identidad tenga permisos para crear asignaciones de roles en el ámbito del almacén de claves, como el rol Administrador del control de acceso basado en roles. Los roles Contributor y Key Vault Contributor no pueden crear asignaciones de roles.
- Si tiene varias suscripciones de Azure, seleccione el identificador de suscripción adecuado en el que se deben facturar los recursos mediante el comando
az account set.
- Terraform instalado localmente. Para obtener instrucciones de instalación, consulte Instalación de Terraform.
- La variable de entorno
ARM_SUBSCRIPTION_IDdebe estar configurada con el ID de suscripción en la que desea crear los recursos. AzureRM 4.x requiere el identificador de suscripción para planear y aplicar operaciones.
Nota:
Puede usar Service Connector para ayudarle a configurar algunos pasos automáticamente. Para más información, consulte Tutorial: Conexión a la cuenta de almacenamiento de Azure en Azure Kubernetes Service (AKS) con Service Connector mediante Id. de carga de trabajo de Microsoft Entra.
Creación del archivo de configuración de Terraform
El main.tf archivo incluye definiciones para el clúster de AKS, la identidad administrada, las credenciales de identidad federada, Azure Key Vault y los recursos de Kubernetes que se usan para configurar y comprobar Id. de carga de trabajo de Microsoft Entra.
Cree un archivo denominado
main.tfy agregue el código siguiente para definir la versión de Terraform y especifique el proveedor de Azure:terraform { required_version = ">= 1.5.0" required_providers { azurerm = { source = "hashicorp/azurerm" version = "~> 4.0" } kubernetes = { source = "hashicorp/kubernetes" version = "~> 2.30" } random = { source = "hashicorp/random" version = "~> 3.6" } } } provider "azurerm" { features {} } data "azurerm_client_config" "current" {}Agregue el código siguiente para
main.tfdefinir variables reutilizables y generar nombres únicos para todos los recursos:resource "random_string" "suffix" { length = 6 upper = false special = false numeric = true } locals { suffix = random_string.suffix.result resource_group_name = "rg-aks-wi-${local.suffix}" cluster_name = "akswi${local.suffix}" managed_identity_name = "uami-wi-${local.suffix}" federated_credential_name = "fic-wi-${local.suffix}" key_vault_name = lower(substr("kvwi${local.suffix}", 0, 24)) secret_name = "secret-${local.suffix}" service_account_name = "workload-sa-${local.suffix}" service_account_namespace = "default" workload_identity_subject = "system:serviceaccount:${local.service_account_namespace}:${local.service_account_name}" }
Crear un grupo de recursos
Cree un grupo de recursos con el comando az group create.
export RANDOM_ID="$(openssl rand -hex 3)"
export RESOURCE_GROUP="myResourceGroup$RANDOM_ID"
export LOCATION="<your-preferred-region>"
az group create --name "${RESOURCE_GROUP}" --location "${LOCATION}"
Agregue el código siguiente a main.tf para crear un grupo de recursos de Azure. Actualice el valor de location para que coincida con la región de Azure preferida.
resource "azurerm_resource_group" "this" {
name = local.resource_group_name
location = "eastus"
}
Habilitar el emisor de OIDC y el Id. de carga de trabajo de Microsoft Entra en un clúster de AKS
Puede habilitar el emisor OIDC y Id. de carga de trabajo de Microsoft Entra en un clúster AKS nuevo o existente.
Cree un clúster de AKS mediante el comando
export CLUSTER_NAME="myAKSCluster$RANDOM_ID"
az aks create \
--resource-group "${RESOURCE_GROUP}" \
--name "${CLUSTER_NAME}" \
--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.
Agregue el código siguiente a main.tf para crear un clúster de AKS con un emisor de OIDC y Id. de carga de trabajo de Microsoft Entra habilitado:
resource "azurerm_kubernetes_cluster" "this" {
name = local.cluster_name
location = azurerm_resource_group.this.location
resource_group_name = azurerm_resource_group.this.name
dns_prefix = local.cluster_name
oidc_issuer_enabled = true
workload_identity_enabled = true
role_based_access_control_enabled = true
default_node_pool {
name = "system"
node_count = 1
vm_size = "Standard_B4ms"
}
identity {
type = "SystemAssigned"
}
}
Recuperación de la dirección URL del emisor de OIDC
Obtenga la dirección URL del emisor de OIDC mediante el az aks show comando y guárdela en una variable de entorno.
export AKS_OIDC_ISSUER="$(az aks show --name "${CLUSTER_NAME}" \
--resource-group "${RESOURCE_GROUP}" \
--query "oidcIssuerProfile.issuerUrl" \
--output tsv)"
La variable de entorno debe contener una dirección URL del emisor similar al ejemplo siguiente:
https://eastus.oic.prod-aks.azure.com/00000000-0000-0000-0000-000000000000/11111111-1111-1111-1111-111111111111/
De manera predeterminada, el emisor tiene establecido usar la dirección URL base https://{region}.oic.prod-aks.azure.com/{tenant_id}/{uuid}, donde el valor {region} coincide con la ubicación en la que se implementa el clúster de AKS. El valor {uuid} representa la clave OIDC, que es un GUID generado aleatoriamente e inmutable para cada clúster.
Agregue el siguiente código a main.tf para recuperar la dirección URL del emisor de OIDC:
output "oidc_issuer_url" {
value = azurerm_kubernetes_cluster.this.oidc_issuer_url
}
Creación de una entidad administrada
Obtenga el identificador de suscripción y guárdelo en una variable de entorno mediante el
az account showcomando .export SUBSCRIPTION="$(az account show --query id --output tsv)"Use el comando
az identity createpara crear una identidad administrada asignada por el usuario.export USER_ASSIGNED_IDENTITY_NAME="myIdentity$RANDOM_ID" az identity create \ --name "${USER_ASSIGNED_IDENTITY_NAME}" \ --resource-group "${RESOURCE_GROUP}" \ --location "${LOCATION}" \ --subscription "${SUBSCRIPTION}"En el ejemplo de salida siguiente se muestra la creación correcta de una identidad administrada:
{ "clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/myResourceGroupxxxxxx/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentityxxxxxx", "location": "eastus", "name": "myIdentityxxxxxx", "principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "resourceGroup": "myResourceGroupxxxxxx", "systemData": null, "tags": {}, "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "type": "Microsoft.ManagedIdentity/userAssignedIdentities" }Obtenga el identificador de cliente de la identidad administrada y guárdelo en una variable de entorno mediante el
az identity showcomando .export USER_ASSIGNED_CLIENT_ID="$(az identity show \ --resource-group "${RESOURCE_GROUP}" \ --name "${USER_ASSIGNED_IDENTITY_NAME}" \ --query 'clientId' \ --output tsv)"
Agregue el siguiente código a main.tf para crear una identidad administrada:
resource "azurerm_user_assigned_identity" "this" {
name = local.managed_identity_name
location = azurerm_resource_group.this.location
resource_group_name = azurerm_resource_group.this.name
}
Creación de una cuenta de servicio de Kubernetes
Conectar al clúster de AKS mediante el comando
az aks get-credentials.az aks get-credentials --name "${CLUSTER_NAME}" --resource-group "${RESOURCE_GROUP}"Cree una cuenta de servicio de Kubernetes y anótela con el identificador de cliente de la identidad administrada aplicando el siguiente manifiesto mediante el comando
kubectl apply.export SERVICE_ACCOUNT_NAME="workload-identity-sa$RANDOM_ID" export SERVICE_ACCOUNT_NAMESPACE="default" 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}" EOFEn la salida siguiente se muestra la creación correcta de la identidad de carga de trabajo:
serviceaccount/workload-identity-sa created
Agregue el código siguiente para configurar el acceso a
main.tfKubernetes para permitir la creación de recursos de Kubernetes:data "azurerm_kubernetes_cluster" "this" { name = azurerm_kubernetes_cluster.this.name resource_group_name = azurerm_resource_group.this.name } provider "kubernetes" { host = data.azurerm_kubernetes_cluster.this.kube_config[0].host client_certificate = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].client_certificate) client_key = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].client_key) cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].cluster_ca_certificate) }Agregue el siguiente código en
main.tfpara crear una cuenta de servicio de Kubernetes y anotarla con el ID de cliente de la identidad administrada:resource "kubernetes_service_account" "this" { metadata { name = local.service_account_name namespace = local.service_account_namespace annotations = { "azure.workload.identity/client-id" = azurerm_user_assigned_identity.this.client_id } } }
Creación de la credencial de identidad federada
Cree una credencial de identidad federada entre la identidad administrada, el emisor de cuentas de servicio y el asunto mediante el comando az identity federated-credential create.
export FEDERATED_IDENTITY_CREDENTIAL_NAME="myFedIdentity$RANDOM_ID"
az identity federated-credential create \
--name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} \
--identity-name "${USER_ASSIGNED_IDENTITY_NAME}" \
--resource-group "${RESOURCE_GROUP}" \
--issuer "${AKS_OIDC_ISSUER}" \
--subject system:serviceaccount:"${SERVICE_ACCOUNT_NAMESPACE}":"${SERVICE_ACCOUNT_NAME}" \
--audience api://AzureADTokenExchange
Nota:
La credencial de identidad federada tarda unos segundos en propagarse después de agregarla. Si se realiza una solicitud de token inmediatamente después de agregar la credencial de identidad federada, es posible que se produzca un error en la solicitud hasta que se actualice la memoria caché. Para evitar este problema, puede agregar un ligero retraso después de agregar la credencial de identidad federada.
Warning
La audiencia indicada anteriormente es la audiencia predeterminada y recomendada para Id. de carga de trabajo de Microsoft Entra. Este valor es global y coherente en todas las nubes de Azure, cambiar el valor de audiencia podría interrumpir la compatibilidad con las configuraciones existentes y no se recomienda a menos que sea necesario explícitamente.
Agregue el siguiente código a main.tf para crear una credencial de identidad federada entre la identidad administrada, el emisor de la cuenta de servicio y el sujeto:
resource "azurerm_federated_identity_credential" "this" {
name = local.federated_credential_name
resource_group_name = azurerm_resource_group.this.name
parent_id = azurerm_user_assigned_identity.this.id
issuer = azurerm_kubernetes_cluster.this.oidc_issuer_url
subject = local.workload_identity_subject
audience = ["api://AzureADTokenExchange"]
}
Warning
La audiencia indicada anteriormente es la audiencia predeterminada y recomendada para Id. de carga de trabajo de Microsoft Entra. Este valor es global y coherente en todas las nubes de Azure, cambiar el valor de audiencia podría interrumpir la compatibilidad con las configuraciones existentes y no se recomienda a menos que sea necesario explícitamente.
Para obtener más información sobre las credenciales de identidad federada en Microsoft Entra, consulte Información general de las credenciales de identidad federada en Microsoft Entra ID.
Creación de un Azure Key Vault con autorización de RBAC de Azure
Los siguientes pasos usan el modelo de permisos de control de acceso basado en roles de Azure (Azure RBAC). Para obtener información general, consulte Concesión de permiso a las aplicaciones para acceder a un almacén de claves de Azure mediante Azure RBAC.
Cree un almacén de claves con protección de purga y con la autorización de Azure RBAC habilitada mediante el comando
az keyvault create. También puede usar un almacén de claves existente si está configurado para la protección de purga y la autorización de RBAC de Azure.export KEYVAULT_NAME="kv-workload-id$RANDOM_ID" az keyvault create \ --name "${KEYVAULT_NAME}" \ --resource-group "${RESOURCE_GROUP}" \ --location "${LOCATION}" \ --enable-purge-protection \ --enable-rbac-authorizationObtenga el identificador de recurso del almacén de claves y guárdelo en una variable de entorno mediante el comando
az keyvault show.export KEYVAULT_RESOURCE_ID=$(az keyvault show --resource-group "${RESOURCE_GROUP}" \ --name "${KEYVAULT_NAME}" \ --query id \ --output tsv)
Agregue el código siguiente a main.tf para crear un almacén de claves con la protección contra purgas y la autorización RBAC de Azure habilitadas:
resource "azurerm_key_vault" "this" {
name = local.key_vault_name
location = azurerm_resource_group.this.location
resource_group_name = azurerm_resource_group.this.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
enable_rbac_authorization = true
purge_protection_enabled = true
}
Asignación de permisos de RBAC para la administración de Azure Key Vault
Obtenga el identificador de objeto del autor de la llamada y guárdelo en una variable de entorno mediante el
az ad signed-in-user showcomando .export CALLER_OBJECT_ID=$(az ad signed-in-user show --query id -o tsv)Asígnese el rol Azure RBAC Key Vault Secrets Officer para que pueda crear un secreto en la nueva bóveda de claves mediante el comando
az role assignment create.az role assignment create --assignee "${CALLER_OBJECT_ID}" \ --role "Key Vault Secrets Officer" \ --scope "${KEYVAULT_RESOURCE_ID}"Importante
Las asignaciones de roles de Azure pueden tardar hasta 10 minutos en propagarse. Si la creación del secreto en la sección siguiente devuelve un
403error, espere a que se propague la asignación de roles y vuelva a intentar el comando. Para obtener más información, consulte Troubleshoot Azure RBAC.
Agregue el siguiente código a main.tf para asignarse el rol Agente de secretos de Key Vault de Azure RBAC y poder crear un secreto en el nuevo Key Vault y asignar el rol Usuario de secretos de Key Vault a la identidad administrada asignada por el usuario:
resource "azurerm_role_assignment" "user" {
scope = azurerm_key_vault.this.id
role_definition_name = "Key Vault Secrets Officer"
principal_id = data.azurerm_client_config.current.object_id
}
resource "azurerm_role_assignment" "identity" {
scope = azurerm_key_vault.this.id
role_definition_name = "Key Vault Secrets User"
principal_id = azurerm_user_assigned_identity.this.principal_id
}
Crear y configurar el acceso a secretos
Cree un secreto en el almacén de claves mediante el comando
az keyvault secret set.Cree un secreto cuyo nombre se almacena en la variable
KEYVAULT_SECRET_NAMEy establezca su valor enHello!en el almacén de claves que creó.export KEYVAULT_SECRET_NAME="my-secret$RANDOM_ID" az keyvault secret set \ --vault-name "${KEYVAULT_NAME}" \ --name "${KEYVAULT_SECRET_NAME}" \ --value 'Hello!'Obtenga el identificador principal de la identidad administrada asignada por el usuario y guárdelo en una variable de entorno con el comando
az identity show.export IDENTITY_PRINCIPAL_ID=$(az identity show \ --name "${USER_ASSIGNED_IDENTITY_NAME}" \ --resource-group "${RESOURCE_GROUP}" \ --query principalId \ --output tsv)Asigne el rol Key Vault Secrets User a la identidad administrada asignada por el usuario mediante el comando
az role assignment create. En este paso se proporciona permiso a la identidad administrada para leer secretos de la bóveda de claves.az role assignment create \ --assignee-object-id "${IDENTITY_PRINCIPAL_ID}" \ --role "Key Vault Secrets User" \ --scope "${KEYVAULT_RESOURCE_ID}" \ --assignee-principal-type ServicePrincipalCree una variable de entorno para la dirección URL del almacén de claves mediante el
az keyvault showcomando .export KEYVAULT_URL="$(az keyvault show \ --resource-group "${RESOURCE_GROUP}" \ --name ${KEYVAULT_NAME} \ --query properties.vaultUri \ --output tsv)"
Agregue el código siguiente a main.tf para crear un secreto en el almacén de claves:
resource "azurerm_key_vault_secret" "this" {
name = local.secret_name
value = "Hello from Key Vault"
key_vault_id = azurerm_key_vault.this.id
depends_on = [azurerm_role_assignment.user]
}
Importante
Las asignaciones de roles de Azure pueden tardar hasta 10 minutos en propagarse. Si terraform apply devuelve un 403 error al crear el secreto, espere a que se propague la asignación de roles y vuelva a ejecutar el comando. Para obtener más información, consulte Troubleshoot Azure RBAC.
Implementación de un pod de comprobación y prueba de acceso (CLI de Azure)
Implemente un pod para verificar que la identidad de la carga de trabajo puede acceder al secreto en el almacén de claves. En el ejemplo siguiente se usa la imagen de
ghcr.io/azure/azure-workload-identity/msal-go, que contiene una aplicación de ejemplo que recupera un secreto de Azure Key Vault mediante Id. de carga de trabajo de Microsoft Entra:kubectl apply -f - <<EOF apiVersion: v1 kind: Pod metadata: name: sample-workload-identity-key-vault namespace: ${SERVICE_ACCOUNT_NAMESPACE} labels: azure.workload.identity/use: "true" spec: serviceAccountName: ${SERVICE_ACCOUNT_NAME} containers: - image: ghcr.io/azure/azure-workload-identity/msal-go name: oidc env: - name: KEYVAULT_URL value: ${KEYVAULT_URL} - name: SECRET_NAME value: ${KEYVAULT_SECRET_NAME} nodeSelector: kubernetes.io/os: linux EOFEspere a que el pod esté en el estado
Readyutilizando el comandokubectl wait.kubectl wait --namespace ${SERVICE_ACCOUNT_NAMESPACE} --for=condition=Ready pod/sample-workload-identity-key-vault --timeout=120sCompruebe que la
SECRET_NAMEvariable de entorno está establecida en el pod mediante elkubectl describecomando .kubectl describe pod sample-workload-identity-key-vault | grep "SECRET_NAME:"Si se ejecuta correctamente, la salida debe ser similar al ejemplo siguiente:
SECRET_NAME: ${KEYVAULT_SECRET_NAME}Verifique que los pods puedan obtener un token y acceder al recurso mediante el comando
kubectl logs.kubectl logs sample-workload-identity-key-vaultSi se ejecuta correctamente, la salida debe ser similar al ejemplo siguiente:
I0114 10:35:09.795900 1 main.go:63] "successfully got secret" secret="Hello!"Importante
Las asignaciones de roles de RBAC en Azure pueden tardar hasta 10 minutos en propagarse. Si el pod no puede acceder al secreto, es posible que tenga que esperar a que se propague la asignación de roles. Para obtener más información, consulte Troubleshoot Azure RBAC.
Deshabilitación de Id. de carga de trabajo de Microsoft Entra en un clúster de AKS
Para deshabilitar Id. de carga de trabajo de Microsoft Entra en el clúster de AKS donde lo habilitó y configuró, use el comando az aks update con el parámetro --disable-workload-identity.
az aks update \
--resource-group "${RESOURCE_GROUP}" \
--name "${CLUSTER_NAME}" \
--disable-workload-identity
Desplegar un pod de verificación (Terraform)
Agregue el siguiente código en main.tf para implementar un pod de verificación que use la identidad de carga de trabajo para obtener acceso al secreto en el almacén de claves:
resource "kubernetes_pod" "test" {
metadata {
name = "workload-identity-test"
namespace = local.service_account_namespace
labels = {
"azure.workload.identity/use" = "true"
}
}
spec {
service_account_name = kubernetes_service_account.this.metadata[0].name
container {
name = "test"
image = "ghcr.io/azure/azure-workload-identity/msal-go"
env {
name = "KEYVAULT_URL"
value = azurerm_key_vault.this.vault_uri
}
env {
name = "SECRET_NAME"
value = azurerm_key_vault_secret.this.name
}
}
}
depends_on = [
azurerm_federated_identity_credential.this,
azurerm_role_assignment.identity,
]
}
Inicialización de Terraform
Inicialice Terraform en el directorio que contiene el archivo main.tf usando el comando terraform init. Este comando descarga el proveedor de Azure necesario para administrar Azure recursos con Terraform.
terraform init
Creación de un plan de ejecución de Terraform
Cree un plan de ejecución de Terraform mediante el comando terraform plan. Este comando muestra los recursos que Terraform creará o modificará en la suscripción de Azure.
terraform plan
Aplica la configuración de Terraform
Después de revisar y confirmar el plan de ejecución, aplique la configuración de Terraform mediante el terraform apply comando . Este comando crea o modifica los recursos definidos en tu archivo main.tf en tu suscripción de Azure.
terraform apply
Comprobación de la implementación
Conectar al clúster de AKS mediante el comando
az aks get-credentials.az aks get-credentials --name <cluster-name> --resource-group <resource-group>Compruebe el estado del pod de comprobación mediante el
kubectl get podscomando .Una vez que el pod alcance un estado
Ready, compruebe que puede obtener acceso al secreto del almacén de claves comprobando los registros del pod mediante el comandokubectl logs.kubectl logs workload-identity-testSi se ejecuta correctamente, la salida es similar al ejemplo siguiente:
I0114 10:35:09.795900 1 main.go:63] "successfully got secret" secret="Hello from Key Vault"Importante
Las asignaciones de roles de RBAC en Azure pueden tardar hasta 10 minutos en propagarse. Si el pod no puede acceder al secreto, espere a que se aplique la asignación de roles y luego vuelva a crear el pod mediante el comando
terraform apply -replace="kubernetes_pod.test". Para obtener más información, consulte Troubleshoot Azure RBAC.
Contenido relacionado
En este artículo, ha implementado un clúster de Kubernetes y lo ha configurado para usar un Id. de carga de trabajo de Microsoft Entra como preparación para que las cargas de trabajo de la aplicación se autentiquen con esa credencial. Ahora está listo para implementar la aplicación y configurarla para usar la identidad de carga de trabajo con la versión más reciente de Azure Identity biblioteca cliente. Si no puede volver a escribir la aplicación para usar la versión más reciente de la biblioteca cliente, puede configurar el pod de la aplicación para autenticarse usando la identidad administrada con la identidad de carga de trabajo como solución de migración a corto plazo.
La integración Service Connector ayuda a simplificar la configuración de conexión para cargas de trabajo de AKS y servicios de respaldo de Azure. Controla de forma segura la autenticación y las configuraciones de red y sigue los procedimientos recomendados para conectarse a servicios de Azure. Para obtener más información, consulte Conexión a Azure OpenAI en Foundry Models en AKS mediante Identidad de carga de trabajo de Microsoft Entra y la Introducción al Conector de servicio.