Autenticar con el Registro del Contenedor de Azure (ACR por sus siglas en inglés) desde los Servicios Kubernetes de Azure (AKS por sus siglas en inglés)

Al usar Azure Container Registry (ACR) con Azure Kubernetes Service (AKS), debe establecer un mecanismo de autenticación. Puede configurar los permisos necesarios entre ACR y AKS mediante el portal de CLI de Azure, Azure PowerShell o Azure portal. En este artículo se proporcionan ejemplos para configurar la autenticación entre estos servicios de Azure mediante el CLI de Azure o Azure PowerShell.

La integración de AKS a ACR asigna el rol AcrPull a la identidad administrada de Microsoft Entra ID asociada al grupo de agentes del clúster de AKS. Para obtener más información sobre las identidades administradas de AKS, consulte Resumen de identidades administradas.

Importante

Hay un problema de latencia con los grupos de Microsoft Entra al adjuntar ACR. Si se concede el rol AcrPull a un grupo de Microsoft Entra y la identidad de kubelet se agrega al grupo para completar la configuración del control de acceso basado en rol (Azure RBAC), puede haber un retraso antes de que el grupo de RBAC de Azure entre en vigor. AzureSi ejecuta una automatización que requiere que se complete la configuración de Azure RBAC, se recomienda usar una identidad kubelet propia como solución alternativa. Puede crear previamente una identidad asignada por el usuario, agregarla al grupo de Microsoft Entra y, a continuación, usar la identidad como identidad kubelet para crear un clúster de AKS. Este método garantiza que la identidad se agrega al grupo de Microsoft Entra antes de que kubelet genere un token, lo que evita el problema de latencia.

Nota:

En este artículo se trata la autenticación automática entre AKS y ACR. Si necesita extraer una imagen de un registro externo privado, use un secreto de extracción de imágenes.

Precaución

La integración de AKS-ACR a través de az aks --attach-acr no es compatible con los registros de ACR habilitados para ABAC donde el modo de permisos de asignación de roles está establecido en "RBAC Registry + ABAC Repository Permissions". Los registros de ACR habilitados para ABAC requieren el Container Registry Repository Reader rol en lugar del AcrPull rol para conceder permisos de extracción de imágenes. En el caso de los registros de ACR habilitados para ABAC, no debe usar az aks --attach-acr sino asignar manualmente la asignación de roles Container Registry Repository Reader, ya sea mediante Azure Portal, la CLI de az role assignment o Azure Resource Manager. Para obtener más información sobre los registros de ACR con ABAC habilitado, consulte control de acceso de Azure basado en atributos.

En este tutorial, configurará un clúster de Azure Kubernetes Service (AKS) para extraer imágenes de forma segura de un Azure Container Registry (ACR). En CLI de Azure, use --attach-acr. En Terraform, asigne el rol AcrPull a la identidad administrada del kubelet de AKS. En esta guía se sigue el mismo flujo que el flujo de trabajo de CLI de Azure mientras se usa Terraform para el aprovisionamiento de infraestructura.

Antes de empezar

  • Si usa CLI de Azure, este artículo requiere que ejecute CLI de Azure versión 2.7.0 o posterior. para buscar la versión, ejecute el az --version comando . Si necesita instalar o actualizar, consulte Install CLI de Azure.
  • Si usa Azure PowerShell, este artículo requiere que ejecute Azure PowerShell versión 5.9.0 o posterior. Para encontrar la versión, ejecute el comando Get-InstalledModule -Name Az. Si necesita instalar o actualizar, consulte Install Azure PowerShell.
  • Puede encontrar ejemplos y sintaxis para usar Terraform para configurar ACR en la referencia de Terraform.
  • Terraform instalado (>= 1.6).
  • La CLI de Azure instalada y con la sesión iniciada en la suscripción.
  • Permisos para asignar roles (propietario o administrador de acceso de usuario).

En este artículo, configurará un clúster de Azure Kubernetes Service (AKS) para extraer imágenes de forma segura de un Azure Container Registry (ACR). En CLI de Azure, use --attach-acr. En Terraform, asigne el rol AcrPull a la identidad administrada del kubelet de AKS.

En este artículo se sigue el mismo flujo que el flujo de trabajo de CLI de Azure mientras se usa Terraform para el aprovisionamiento de infraestructura. Para comprobar que ha iniciado sesión en la suscripción correcta, use los siguientes comandos de CLI de Azure:

az login
az account show

Crear un ACR

Si aún no tiene un ACR, cree uno con el comando az acr create.

El nombre del registro debe ser globalmente único en Azure y contener de 5 a 50 caracteres alfanuméricos, exceptuando los caracteres (-). Este nombre forma parte del nombre de dominio completo (FQDN) del registro.

export RANDOM_STRING=$(printf '%05d%05d' "$RANDOM" "$RANDOM")
export MYACR="mycontainerregistry$RANDOM_STRING"
export ACR_RESOURCE_GROUP="myContainerRegistryResourceGroup"
export LOCATION="westcentralus"

az group create \
  --name $ACR_RESOURCE_GROUP \
  --location $LOCATION

az acr create \
  --name $MYACR \
  --resource-group $ACR_RESOURCE_GROUP \
  --sku basic

La RANDOM_STRING variable almacena una cadena aleatoria de 10 dígitos. El MYACR valor se concatena con el RANDOM_STRING valor para crear un nombre único.

Si aún no tiene un ACR, cree uno con el cmdlet New-AzContainerRegistry.

El nombre del registro debe ser globalmente único en Azure y contener de 5 a 50 caracteres alfanuméricos, exceptuando los caracteres (-). Este nombre forma parte del nombre de dominio completo (FQDN) del registro.

$RandomString = (Get-Random -Minimum 1000000000 -Maximum 10000000000).ToString()
$MyAcr = "mycontainerregistry$RandomString"
$AcrResourceGroup = "myContainerRegistryResourceGroup"
$Location = "westcentralus"

New-AzResourceGroup -Name $AcrResourceGroup -Location $Location

$NewAcr = @{
 Name = $MyAcr
 ResourceGroupName = $AcrResourceGroup
 Location = $Location
 Sku = "Basic"
}

New-AzContainerRegistry @NewAcr

La $RandomString variable almacena una cadena aleatoria de 10 dígitos. El $MyAcr valor se concatena con el $RandomString valor para crear un nombre único.

Cree un archivo main.tf para la configuración y comience definiendo los proveedores de Terraform y generando un sufijo único para los nombres de recursos únicos globalmente. Un nombre único global garantiza que el nombre de Azure Container Registry no entre en conflicto con los registros existentes.

terraform {
 required_version = ">= 1.6.0"
 required_providers {
   azurerm = {
     source  = "hashicorp/azurerm"
     version = "~> 4.0"
   }
   random = {
     source  = "hashicorp/random"
     version = "~> 3.6"
   }
 }
}
provider "azurerm" {
 features {}
}
resource "random_string" "suffix" {
 length  = 6
 upper   = false
 special = false
}

Creación de un nuevo clúster de AKS e integración con un ACR existente

Cree un nuevo clúster de AKS e intégrelo con un ACR existente mediante el az aks create comando con el --attach-acr parámetro . Este comando le permite autorizar un ACR existente en la suscripción y configurar el rol adecuado AcrPull para la identidad administrada.

export CLUSTER_NAME="myAKSCluster"
export CLUSTER_RESOURCE_GROUP="myClusterResourceGroup"

az group create \
  --name $CLUSTER_RESOURCE_GROUP \
  --location $LOCATION

az aks create \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --generate-ssh-keys \
  --attach-acr $MYACR

Usa un ACR en una suscripción diferente o adjunta usando el identificador de recurso

Si usa un ACR ubicado en una suscripción diferente del clúster de AKS o prefiere usar el identificador de recurso de ACR en lugar del nombre de ACR, use la sintaxis siguiente. En este ejemplo se crea la ACR_RESOURCE_ID variable mediante el registro de contenedor creado en la sección anterior.

ACR_RESOURCE_ID=$(az acr show \
  --name $MYACR \
  --resource-group $ACR_RESOURCE_GROUP \
  --query id --output tsv)

az aks create \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --generate-ssh-keys \
  --attach-acr $ACR_RESOURCE_ID

Cree un nuevo clúster de AKS e intégrelo con un ACR existente mediante el New-AzAksCluster cmdlet con el -AcrNameToAttach parámetro . Este comando le permite autorizar un ACR existente en la suscripción y configurar el rol adecuado AcrPull para la identidad administrada.

$ClusterName = "myAKSCluster"
$ClusterResourceGroup = "myClusterResourceGroup"

New-AzResourceGroup -Name $ClusterResourceGroup -Location $Location

$NewCluster = @{
 Name = $ClusterName
 ResourceGroupName = $ClusterResourceGroup
 GenerateSshKey = $true
 AcrNameToAttach = $MyAcr
}

New-AzAksCluster @NewCluster

Utilizar un ACR en una suscripción diferente o adjuntar mediante el identificador de recurso

Azure PowerShell solo admite la asociación de ACR a AKS mediante el parámetro -AcrNameToAttach y no admite la asociación a un ACR mediante id. de origen.

A continuación, cree un grupo de recursos y un Azure Container Registry. Este registro almacena las imágenes de contenedor que extrae el clúster de AKS más adelante.

locals {
 location           = "westcentralus"
 acr_name           = "myacr${random_string.suffix.result}"
 acr_resource_group = "myContainerRegistryResourceGroup"
}
resource "azurerm_resource_group" "acr_rg" {
 name     = local.acr_resource_group
 location = local.location
}
resource "azurerm_container_registry" "acr" {
 name                = local.acr_name
 resource_group_name = azurerm_resource_group.acr_rg.name
 location            = azurerm_resource_group.acr_rg.location
 sku                 = "Basic"
 admin_enabled       = false
}

Ahora cree el clúster de AKS que consume imágenes del registro. Este clúster usa una identidad administrada asignada por el sistema, que se concederá permiso para extraer imágenes.

locals {
 aks_name           = "myAKSCluster"
 aks_resource_group = "myClusterResourceGroup"
}
resource "azurerm_resource_group" "aks_rg" {
 name     = local.aks_resource_group
 location = local.location
}
resource "azurerm_kubernetes_cluster" "aks" {
 name                = local.aks_name
 location            = azurerm_resource_group.aks_rg.location
 resource_group_name = azurerm_resource_group.aks_rg.name
 dns_prefix          = local.aks_name
 identity {
   type = "SystemAssigned"
 }
 default_node_pool {
   name       = "systempool"
   node_count = 2
   vm_size    = "Standard_DS2_v2"
 }
}

En esta fase, el clúster de AKS existe, pero aún no tiene acceso al registro de contenedor. En CLI de Azure, use el parámetro --attach-acr. En Terraform, asigne el rol AcrPull explícitamente.

resource "azurerm_role_assignment" "aks_acr_pull" {
 scope                = azurerm_container_registry.acr.id
 role_definition_name = "AcrPull"
 principal_id         = azurerm_kubernetes_cluster.aks.kubelet_identity[0].object_id
}

Configuración de la integración de ACR para un clúster de AKS existente

Puede adjuntar un ACR a un clúster de AKS existente o desasociar un ACR de un clúster de AKS si ya no desea que el clúster tenga acceso al registro.

En los ejemplos anteriores del artículo se creó un Azure Container Registry y un clúster de Azure Kubernetes Service asociado al ACR. A continuación se muestran ejemplos de cómo adjuntar o desasociar un registro de contenedor de un clúster y usar el clúster de ACR y AKS creado en este artículo. Puede reemplazar los valores de variable por sus propios valores de clúster de ACR y AKS.

Asociación de un ACR a un clúster de AKS ya existente

Integre un ACR existente con un clúster existente de AKS usando el comando az aks update con el parámetro --attach-acr.

# Attach using acr-name
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --attach-acr $MYACR


# Attach using acr-resource-id
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --attach-acr $ACR_RESOURCE_ID

El comando az aks update --attach-acr usa los permisos del usuario que ejecuta el comando para crear la asignación de roles de ACR. Este rol se asigna a la identidad administrada de kubelet. Para obtener más información sobre las identidades administradas de AKS, consulte Resumen de identidades administradas.

Integre un ACR existente con un clúster AKS existente mediante el comando con los parámetros Set-AzAksCluster y -AcrNameToAttach.

$AttachCluster = @{
 Name = $ClusterName
 ResourceGroupName = $ClusterResourceGroup
 AcrNameToAttach = $MyAcr
}

Set-AzAksCluster @AttachCluster

El Set-AzAksCluster -AcrNameToAttach cmdlet utiliza los permisos del usuario que ejecuta el comando para crear la asignación ACR de rol. Este rol se asigna a la identidad administrada de kubelet. Para obtener más información sobre las identidades administradas de AKS, consulte Resumen de identidades administradas.

Si el clúster de AKS ya existe, puede adjuntar un ACR haciendo referencia a los recursos y creando la misma asignación de roles.

data "azurerm_kubernetes_cluster" "existing_aks" {
 name                = "myAKSCluster"
 resource_group_name = "myClusterResourceGroup"
}
data "azurerm_container_registry" "existing_acr" {
 name                = "mycontainerregistry"
 resource_group_name = "myContainerRegistryResourceGroup"
}
resource "azurerm_role_assignment" "existing_aks_acr_pull" {
 scope                = data.azurerm_container_registry.existing_acr.id
 role_definition_name = "AcrPull"
 principal_id         = data.azurerm_kubernetes_cluster.existing_aks.kubelet_identity[0].object_id
}

Desasociación de un ACR de un clúster de AKS

Elimine la integración entre un ACR y un clúster de AKS usando el comando az aks update con el parámetro --detach-acr.

# Detach using acr-name
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --detach-acr $MYACR

# Detach using acr-resource-id
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --detach-acr $ACR_RESOURCE_ID

Quite la integración entre un ACR y un clúster de AKS mediante el comando Set-AzAksCluster con el parámetro -AcrNameToDetach.

$DetachCluster = @{
 Name = $ClusterName
 ResourceGroupName = $ClusterResourceGroup
 AcrNameToDetach = $MyAcr
}

Set-AzAksCluster @DetachCluster

Para quitar el acceso, elimine la asignación de roles que concede al clúster permiso para extraer imágenes.

# Remove this resource to revoke access
# resource "azurerm_role_assignment" "existing_aks_acr_pull" {
#   scope                = data.azurerm_container_registry.existing_acr.id
#   role_definition_name = "AcrPull"
#   principal_id         = data.azurerm_kubernetes_cluster.existing_aks.kubelet_identity[0].object_id
# }

Inicialización e implementación de la configuración

Una vez completada la configuración, inicialice Terraform y revise el plan de ejecución antes de aplicarla.

terraform fmt
terraform init
terraform validate
terraform plan
terraform apply

En este momento, el clúster de AKS está configurado para extraer imágenes de ACR.

Ahora puede hacer lo siguiente:

  • Importe imágenes en ACR.
  • Despliegue cargas de trabajo en AKS.
  • Compruebe la implementación del pod.

Trabajar con ACR y AKS

Importe una imagen en ACR y, a continuación, implemente esa imagen en el clúster de AKS.

Importación de una imagen en ACR

Importe una imagen de Docker Hub en ACR mediante el comando az acr import.

az acr import \
  --name $MYACR \
  --source docker.io/library/nginx:latest \
  --image nginx:v1

Ejecute los siguientes comandos para comprobar que se importó la imagen.

az acr repository show --name $MYACR --repository nginx
az acr repository show-tags --name $MYACR --repository nginx

Importe una imagen de Docker Hub a ACR mediante el cmdlet Import-AzContainerRegistryImage.

$ImportImage = @{
 RegistryName = $MyAcr
 ResourceGroupName = $AcrResourceGroup
 SourceRegistryUri = 'docker.io'
 SourceImage = 'library/nginx:latest'
 TargetTag = 'nginx:v1'
}

Import-AzContainerRegistryImage @ImportImage

Ejecute los siguientes comandos para comprobar que se importó la imagen.

Get-AzContainerRegistryRepository -RegistryName $MyAcr

Get-AzContainerRegistryTag -RegistryName $MyAcr -Repository nginx

Creación de un archivo de implementación

Cree una implementación de Kubernetes que haga referencia a la imagen que importó en ACR. Si la implementación se realiza correctamente y la imagen se extrae correctamente, el clúster de AKS se integra correctamente con ACR.

Cree un archivo denominado acr-nginx.yaml con el siguiente código YAML de ejemplo. En la image propiedad , reemplace acr-name por el nombre de su ACR. En CLI de Azure, ejecute echo $MYACR para mostrar el nombre de ACR. En Azure PowerShell, ejecute $MyAcr para mostrar el nombre de ACR.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx0-deployment
  labels:
    app: nginx0-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx0
  template:
    metadata:
      labels:
        app: nginx0
    spec:
      containers:
      - name: nginx
        image: <acr-name>.azurecr.io/nginx:v1
        ports:
        - containerPort: 80

Obtención de credenciales y ejecución de la implementación

  1. Asegúrese de que tiene las credenciales de AKS mediante el comando az aks get-credentials.

    az aks get-credentials \
      --resource-group $CLUSTER_RESOURCE_GROUP \
      --name $CLUSTER_NAME
    
  2. Ejecute la implementación en el clúster de AKS mediante el comando kubectl apply.

    kubectl apply -f acr-nginx.yaml
    
  3. Supervise la implementación con el comando kubectl get pods.

    kubectl get pods
    

    La salida debe mostrar dos pods en ejecución, como se muestra en la salida de ejemplo siguiente:

    NAME                                 READY   STATUS    RESTARTS   AGE
    nginx0-deployment-669dfc4d4b-x74kr   1/1     Running   0          20s
    nginx0-deployment-669dfc4d4b-xdpd6   1/1     Running   0          20s
    
  1. Asegúrese de que tiene las credenciales de AKS mediante el cmdlet Import-AzAksCredential.

    Import-AzAksCredential -ResourceGroupName $ClusterResourceGroup -Name $ClusterName
    
  2. Ejecute la implementación en el clúster de AKS mediante el comando kubectl apply.

    kubectl apply -f acr-nginx.yaml
    
  3. Supervise la implementación con el comando kubectl get pods.

    kubectl get pods
    

    La salida debe mostrar dos pods en ejecución, como se muestra en la salida de ejemplo siguiente:

    NAME                                 READY   STATUS    RESTARTS   AGE
    nginx0-deployment-669dfc4d4b-x74kr   1/1     Running   0          20s
    nginx0-deployment-669dfc4d4b-xdpd6   1/1     Running   0          20s
    

Solución de problemas

Limpieza de recursos

Cuando ya no necesite los recursos creados en este artículo, puede eliminar los grupos de recursos para quitar todos los recursos asociados. Estos comandos eliminan el clúster de ACR y AKS y el grupo de recursos del nodo de clústeres que comienza con MC_.

az group delete --name $ACR_RESOURCE_GROUP --yes --no-wait
az group delete --name $CLUSTER_RESOURCE_GROUP --yes --no-wait
Remove-AzResourceGroup -Name $AcrResourceGroup -Force
Remove-AzResourceGroup -Name $ClusterResourceGroup -Force