Autenticar no Registro de Contêiner do Azure (ACR) a partir do AKS (Serviço de Kubernetes do Azure)

Ao usar Registro de Contêiner do Azure (ACR) com o AKS (Serviço de Kubernetes do Azure), você precisa estabelecer um mecanismo de autenticação. Você pode configurar as permissões necessárias entre o ACR e o AKS usando o portal CLI do Azure, Azure PowerShell ou Azure. Este artigo fornece exemplos para configurar a autenticação entre esses serviços Azure usando o CLI do Azure ou Azure PowerShell.

A integração do AKS ao ACR atribui a função AcrPull para a identidade gerenciada do Microsoft Entra ID associada ao pool de agentes no cluster do AKS. Para obter mais informações sobre as identidades gerenciadas do AKS, confira Resumo das identidades gerenciadas.

Importante

Há um problema de latência com grupos do Microsoft Entra ao anexar o ACR. Se a função AcrPull for atribuída a um grupo do Microsoft Entra e a identidade do kubelet for adicionada ao grupo para concluir a configuração do controle de acesso baseado em funções do Azure (Azure RBAC), pode haver um atraso antes que o grupo RBAC entre em vigor. Se você estiver executando uma automação que exija que a configuração do RBAC do Azure esteja completa, recomendamos que utilize a opção Traga sua própria identidade de kubele como solução alternativa. Você pode criar previamente uma identidade atribuída ao usuário, adicioná-la ao grupo do Microsoft Entra e, em seguida, usar essa identidade como identidade do kubelet para criar um cluster do AKS. Esse método garante que a identidade seja adicionada ao grupo de Microsoft Entra antes que um token seja gerado pelo kubelet, o que evita o problema de latência.

Observação

Este artigo aborda a autenticação automática entre o AKS e o ACR. Se você precisar efetuar o pull de uma imagem de um registro externo privado, use um segredo de pull de imagem.

Cuidado

A integração AKS-ACR por meio de az aks --attach-acr não é compatível com registros ACR habilitados para ABAC nos quais o modo de permissões de atribuição de funções está definido como "Registro RBAC + Permissões do Repositório ABAC". Os registros ACR habilitados para ABAC exigem a função Container Registry Repository Reader em vez da função AcrPull para conceder permissões de download de imagens. Para registros ACR habilitados para ABAC, você não deve usar az aks --attach-acr, mas sim atribuir manualmente a atribuição de função Container Registry Repository Reader usando o Portal do Azure, az role assignment a CLI ou o Azure Resource Manager. Para obter mais informações sobre registros do ACR habilitados para ABAC, consulte controle de acesso baseado em atributos do Azure.

Neste passo a passo, você configura um cluster AKS (Serviço de Kubernetes do Azure) para extrair imagens com segurança de um Registro de Contêiner do Azure (ACR). Em CLI do Azure, use --attach-acr. No Terraform, atribua a função AcrPull à identidade gerenciada do kubelet do AKS. Este guia segue o mesmo fluxo que o fluxo de trabalho CLI do Azure ao usar o Terraform para provisionamento de infraestrutura.

Antes de começar

  • Se você estiver usando CLI do Azure, este artigo exigirá que você esteja executando CLI do Azure versão 2.7.0 ou posterior. para localizar a versão, execute o az --version comando. Se precisar instalar ou atualizar, consulte Instalar CLI do Azure.
  • Se você estiver usando Azure PowerShell, este artigo exigirá que você esteja executando Azure PowerShell versão 5.9.0 ou posterior. Para localizar a versão, execute o comando Get-InstalledModule -Name Az. Se você precisar instalar ou atualizar, consulte Instalar Azure PowerShell.
  • Veja exemplos e a sintaxe de uso do Terraform para configurar o ACR na referência do Terraform.
  • Terraform instalado (>= 1.6).
  • CLI do Azure instalado e conectado à sua assinatura.
  • Permissões para atribuir funções (Proprietário ou Administrador de Acesso do Usuário).

Neste artigo, você configura um cluster AKS (Serviço de Kubernetes do Azure) para efetuar pull de imagens com segurança de um ACR (Registro de Contêiner do Azure). Em CLI do Azure, use --attach-acr. No Terraform, atribua a função AcrPull à identidade gerenciada do kubelet do AKS.

Este artigo segue o mesmo fluxo que o fluxo de trabalho CLI do Azure ao usar o Terraform para provisionamento de infraestrutura. Para verificar se você está conectado à assinatura correta, use os seguintes comandos de CLI do Azure:

az login
az account show

Criar um novo ACR

Se você ainda não tiver um ACR, crie um usando o comando az acr create.

O nome do registro deve ser globalmente exclusivo no Azure, contendo de 5 a 50 caracteres alfanuméricos, sem incluir caracteres traço (-). Esse nome faz parte do nome DNS totalmente qualificado do 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

A RANDOM_STRING variável armazena uma cadeia de caracteres aleatória de 10 dígitos. O MYACR valor é concatenado com o RANDOM_STRING valor para criar um nome exclusivo.

Se você ainda não tiver um ACR, crie um usando o cmdlet New-AzContainerRegistry.

O nome do registro deve ser exclusivo em nível global no Azure e conter de 5 a 50 caracteres alfanuméricos, excluindo caracteres traço (-). Esse nome faz parte do nome DNS totalmente qualificado do 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

A $RandomString variável armazena uma cadeia de caracteres aleatória de 10 dígitos. O $MyAcr valor é concatenado com o $RandomString valor para criar um nome exclusivo.

Crie um arquivo main.tf para a configuração e comece definindo os provedores terraform e gerando um sufixo exclusivo para nomes de recursos globalmente exclusivos. Um nome global exclusivo garante que seu nome de Registro de Contêiner do Azure não entre em conflito com os 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
}

Criar um novo cluster do AKS e integrar-se a um ACR existente

Crie um novo cluster do AKS e integre-se a um ACR existente usando o az aks create comando com o --attach-acr parâmetro. Esse comando permite que você autorize um ACR existente em sua assinatura e configure a função apropriada AcrPull para a identidade gerenciada.

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

Use um ACR em uma assinatura diferente ou anexe usando a ID de recurso

Se você estiver usando um ACR localizado em uma assinatura diferente do cluster do AKS ou preferir usar a ID de recurso do ACR em vez do nome do ACR, use a sintaxe a seguir. Este exemplo cria a ACR_RESOURCE_ID variável usando o registro de contêiner criado na seção 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

Crie um novo cluster AKS e integre com um ACR existente usando o cmdlet New-AzAksCluster com o parâmetro -AcrNameToAttach. Esse comando permite que você autorize um ACR existente em sua assinatura e configure a função apropriada AcrPull para a identidade gerenciada.

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

New-AzResourceGroup -Name $ClusterResourceGroup -Location $Location

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

New-AzAksCluster @NewCluster

Use um ACR de outra assinatura ou vincule-o usando o ID do recurso

Azure PowerShell só dá suporte à anexação do ACR ao AKS usando o parâmetro -AcrNameToAttach e não dá suporte à anexação a um ACR pelo ID de recurso.

Em seguida, crie um grupo de recursos e um Registro de Contêiner do Azure. Este registro armazena as imagens de contêiner que o seu cluster AKS irá baixar posteriormente.

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
}

Agora, crie o cluster do AKS que consome imagens do registro. Esse cluster usa uma identidade gerenciada atribuída pelo sistema, que receberá permissão para efetuar pull de imagens.

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

Neste estágio, o cluster do AKS existe, mas ainda não tem acesso ao registro de contêiner. Em CLI do Azure, use o parâmetro --attach-acr. No Terraform, você atribui explicitamente a AcrPull função.

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
}

Configurar a integração do ACR para os clusters do AKS existentes

Você pode anexar um ACR a um cluster do AKS existente ou desanexar um ACR de um cluster do AKS se não quiser mais que o cluster tenha acesso ao registro.

Os exemplos anteriores no artigo criaram um Registro de Contêiner do Azure e um cluster Serviço de Kubernetes do Azure anexado ao ACR. Veja a seguir exemplos de como anexar ou desanexar um registro de contêiner de um cluster e usar o cluster do ACR e do AKS criado neste artigo. Você pode substituir os valores de variável por seus próprios valores de cluster ACR e AKS.

Anexar um ACR a cluster do AKS existente

Integre um ACR existente a um cluster do AKS existente usando o az aks update comando com o --attach-acr parâmetro.

# 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

O comando az aks update --attach-acr usa as permissões do usuário que está executando o comando para criar a atribuição de função do ACR. Essa função é atribuída à identidade gerenciada do kubelet. Para obter mais informações sobre as identidades gerenciadas do AKS, confira Resumo das identidades gerenciadas.

Integre um ACR existente a um cluster do AKS existente usando o Set-AzAksCluster comando com o -AcrNameToAttach parâmetro.

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

Set-AzAksCluster @AttachCluster

O Set-AzAksCluster -AcrNameToAttach cmdlet usa as permissões do usuário que executa o comando para criar a atribuição de função ACR. Essa função é atribuída à identidade gerenciada do kubelet. Para obter mais informações sobre as identidades gerenciadas do AKS, confira Resumo das identidades gerenciadas.

Se o cluster do AKS já existir, você poderá anexar um ACR referenciando ambos os recursos e criando a mesma atribuição de função.

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
}

Desanexar um ACR de um cluster do AKS

Remova a integração entre um ACR e um cluster do AKS usando o az aks update comando com o --detach-acr parâmetro.

# 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

Remova a integração entre um ACR e um cluster do AKS usando o Set-AzAksCluster comando com o -AcrNameToDetach parâmetro.

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

Set-AzAksCluster @DetachCluster

Para remover o acesso, exclua a atribuição de função que concede permissão ao cluster para baixar imagens.

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

Inicializar e implantar a configuração

Após a conclusão da configuração, inicialize o Terraform e examine o plano de execução antes de aplicar.

terraform fmt
terraform init
terraform validate
terraform plan
terraform apply

Neste momento, seu cluster AKS está configurado para baixar imagens do ACR.

Agora você pode:

  • Importar imagens para o ACR.
  • Implemente cargas de trabalho no AKS.
  • Verifique a implantação do pod.

Trabalhando com o ACR e o AKS

Importe uma imagem para o ACR e implante essa imagem no cluster do AKS.

Importe uma imagem para o seu ACR

Importe uma imagem de Docker Hub para o ACR usando o comando az acr import.

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

Execute os comandos a seguir para verificar se a imagem foi importada.

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

Importe uma imagem de Docker Hub para o ACR usando o cmdlet Import-AzContainerRegistryImage.

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

Import-AzContainerRegistryImage @ImportImage

Execute os comandos a seguir para verificar se a imagem foi importada.

Get-AzContainerRegistryRepository -RegistryName $MyAcr

Get-AzContainerRegistryTag -RegistryName $MyAcr -Repository nginx

Criar arquivo de implantação

Crie uma implantação do Kubernetes que faça referência à imagem importada para o ACR. Se a implantação for bem-sucedida e a imagem for baixada corretamente, o cluster do AKS está devidamente integrado ao ACR.

Crie um arquivo chamado acr-nginx.yaml usando o YAML de exemplo a seguir. Na propriedade image, substitua acr-name pelo nome do seu ACR. Em CLI do Azure, execute echo $MYACR para exibir o nome do ACR. Em Azure PowerShell, execute $MyAcr para exibir o nome do 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

Obter credenciais e executar a implantação

  1. Certifique-se de que você tenha as credenciais do AKS adequadas usando o comando az aks get-credentials.

    az aks get-credentials \
      --resource-group $CLUSTER_RESOURCE_GROUP \
      --name $CLUSTER_NAME
    
  2. Execute a implantação no seu cluster do AKS usando o comando kubectl apply.

    kubectl apply -f acr-nginx.yaml
    
  3. Monitore a implantação usando o comando kubectl get pods.

    kubectl get pods
    

    A saída deve mostrar dois pods em execução, conforme mostrado no seguinte exemplo de saída:

    NAME                                 READY   STATUS    RESTARTS   AGE
    nginx0-deployment-669dfc4d4b-x74kr   1/1     Running   0          20s
    nginx0-deployment-669dfc4d4b-xdpd6   1/1     Running   0          20s
    
  1. Certifique-se de que você tenha as credenciais do AKS adequadas usando o cmdlet Import-AzAksCredential.

    Import-AzAksCredential -ResourceGroupName $ClusterResourceGroup -Name $ClusterName
    
  2. Execute a implantação no seu cluster do AKS usando o comando kubectl apply.

    kubectl apply -f acr-nginx.yaml
    
  3. Monitore a implantação usando o comando kubectl get pods.

    kubectl get pods
    

    A saída deve mostrar dois pods em execução, conforme mostrado no seguinte exemplo de saída:

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

Solução de problemas

Limpar os recursos

Quando você não precisar mais dos recursos criados neste artigo, poderá excluir os grupos de recursos para remover todos os recursos associados. Esses comandos excluem o ACR e o cluster AKS, além do grupo de recursos de nós do cluster que começa com 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