Fundamentação Teórica: Create and manage an Azure Container Registry
1. Intuição Inicial
Imagine que você desenvolveu uma aplicação e precisa distribuí-la para múltiplos servidores, ambientes de teste e produção. Em vez de copiar o código e configurar cada servidor individualmente, você empacota tudo em um container: uma unidade autocontida que inclui o código, as dependências, as bibliotecas e as configurações necessárias para executar a aplicação. Esse container é definido por uma imagem, que funciona como o "molde" a partir do qual qualquer número de containers pode ser instanciado.
Agora você precisa de um lugar para armazenar e distribuir essas imagens. O Azure Container Registry (ACR) é exatamente isso: um repositório privado e gerenciado para imagens de container no Azure. É o Docker Hub da sua organização, mas privado, seguro e integrado ao ecossistema Azure.
A analogia mais precisa é uma biblioteca particular de livros técnicos: em vez de usar a biblioteca pública (Docker Hub), você mantém seus próprios livros (imagens) em uma biblioteca privada onde controla quem pode ler e quem pode adicionar novos títulos.
2. Contexto
O ACR ocupa uma posição central no fluxo de desenvolvimento e entrega de aplicações baseadas em containers:
Sem um registry privado, as opções são usar o Docker Hub público (sem controle de acesso, sem isolamento, imagens visíveis a todos) ou gerenciar manualmente a distribuição de imagens. O ACR resolve isso oferecendo armazenamento privado, autenticação integrada com o Entra ID e ferramentas de gerenciamento de ciclo de vida.
3. Construção dos Conceitos
3.1 Estrutura do ACR: Registry, Repository, Tag
A hierarquia de organização dentro do ACR tem três níveis:
- Registry: o serviço em si, com um nome único globalmente no formato
<nome>.azurecr.io - Repository: um conjunto de imagens relacionadas (geralmente uma aplicação ou serviço). Dentro de um registry, você pode ter múltiplos repositories.
- Tag: a versão de uma imagem dentro de um repository. A tag
latesté convenção, mas não tem comportamento especial; é uma tag como qualquer outra.
Uma imagem é referenciada pelo seu caminho completo: minhacr.azurecr.io/api-gateway:v1.2.3
3.2 SKUs do ACR
Existem três tiers de serviço:
| Feature | Basic | Standard | Premium |
|---|---|---|---|
| Armazenamento incluído | 10 GB | 100 GB | 500 GB |
| Throughput de imagem | Baixo | Médio | Alto |
| Geo-replication | Não | Não | Sim |
| Private Link | Não | Não | Sim |
| Customer-managed keys | Não | Não | Sim |
| Content Trust (assinatura) | Não | Não | Sim |
| Webhooks | 2 | 10 | 500 |
| Casos de uso | Dev/Test | Produção padrão | Enterprise, multi-região |
Para o AZ-104, o foco está em entender quando usar cada tier. O Standard é o mais comum para ambientes de produção. O Premium é necessário quando você precisa de geo-replication (imagens disponíveis em múltiplas regiões com baixa latência) ou de acesso via Private Link (rede privada, sem exposição pública).
3.3 Autenticação no ACR
Esta é a área de maior importância para o AZ-104. Existem três formas de autenticar no ACR:
1. Admin Account (conta de administrador)
O ACR tem uma conta de administrador opcional com um par de credenciais (username + 2 senhas). É simples mas menos segura, pois as credenciais são compartilhadas e não vinculadas a uma identidade específica.
# Habilitar admin account
az acr update --name minhacr --resource-group rg-containers --admin-enabled true
# Obter credenciais de admin
az acr credential show --name minhacr --resource-group rg-containers
2. Identidade (Entra ID + RBAC)
A abordagem recomendada. Qualquer principal do Entra ID (usuário, service principal, managed identity) pode ter papéis RBAC atribuídos no ACR:
| Papel ACR | O que permite |
|---|---|
| AcrPull | Fazer pull de imagens (leitura) |
| AcrPush | Fazer push e pull de imagens |
| AcrDelete | Deletar imagens |
| AcrImageSigner | Assinar imagens (Content Trust) |
| Owner | Gerenciar o registry e todas as permissões |
| Contributor | Gerenciar o registry mas não permissões |
| Reader | Ver recursos mas não imagens |
3. Token de repositório (Repository-scoped token)
Um token com escopo limitado a um ou mais repositories específicos e com permissões granulares (pull, push, delete). Útil para automações que devem ter acesso apenas a parte do registry.
3.4 ACR Tasks: Build e Automação
O ACR tem um recurso embutido chamado ACR Tasks que permite executar builds de imagens diretamente no Azure, sem precisar de um agente de build local ou de um pipeline separado para operações simples:
| Tipo de Task | Descrição |
|---|---|
| Quick task | Build único via az acr build, imagem vai direto para o registry |
| Automatic trigger | Build automático ao fazer commit no repositório de código |
| Scheduled task | Build em agendamento (cron) para atualizações periódicas de imagens base |
| Multi-step task | Sequência de steps: build, teste, push |
4. Visão Estrutural
5. Funcionamento na Prática
Ciclo de Vida de uma Imagem no ACR
Comportamentos Importantes e Não Óbvios
Tag é mutável, digest é imutável: uma tag como latest pode ser sobrescrita por um novo push. Mas cada imagem tem um digest (hash SHA-256) imutável que identifica exatamente aquela versão. Para ambientes de produção, referencie imagens pelo digest (minhacr.azurecr.io/api:sha256:abc123...) em vez da tag para garantir reprodutibilidade.
Imagens são compostas por layers: cada instrução no Dockerfile gera um layer. O ACR armazena layers de forma deduplificada: se duas imagens compartilham os mesmos layers base, eles são armazenados apenas uma vez. Isso é importante para calcular custos reais de armazenamento.
O ACR não executa containers: ele apenas armazena e distribui imagens. A execução é responsabilidade de AKS, ACI, App Service ou qualquer host Docker.
Pull de imagens cobra pelo tráfego de saída: pulls de imagens do ACR para fora da região Azure incorrem em custo de egress. Para workloads multi-região, considere geo-replication (Premium) para ter o registry na mesma região do workload.
6. Formas de Implementação
6.1 Portal do Azure
Quando usar: criação inicial, verificação visual de repositories e tags, configuração de webhooks e replication.
Caminho: Create a resource > Containers > Container Registry
Campos na criação:
- Registry name: nome único globalmente (apenas alphanumerico, 5-50 caracteres)
- SKU: Basic, Standard ou Premium
- Admin user: habilitar ou não a conta de administrador
6.2 Azure CLI
Criar ACR:
az acr create \
--name minhacr \
--resource-group rg-containers \
--sku Standard \
--location brazilsouth \
--admin-enabled false
Autenticar com Entra ID para operações de imagem:
# Login usando credenciais do Entra ID (para dev local)
az acr login --name minhacr
Isso obtém um token temporário e configura o Docker local para usar o ACR. Válido por 3 horas.
Build de imagem diretamente no ACR (sem Docker local):
# Build do Dockerfile no diretório atual e push direto para o ACR
az acr build \
--registry minhacr \
--image api-gateway:v1.2.3 \
--file Dockerfile \
.
Operações com imagens:
# Listar repositories
az acr repository list --name minhacr --output table
# Listar tags de um repository
az acr repository show-tags \
--name minhacr \
--repository api-gateway \
--orderby time_desc \
--output table
# Ver detalhes de uma imagem específica (incluindo digest)
az acr repository show-manifests \
--name minhacr \
--repository api-gateway \
--query "[].{Digest:digest, Tags:tags, Created:timestamp}" \
--output table
# Deletar uma tag específica
az acr repository delete \
--name minhacr \
--image api-gateway:v1.2.2 \
--yes
# Deletar um repository inteiro
az acr repository delete \
--name minhacr \
--repository api-gateway-old \
--yes
Atribuir papel AcrPull a um serviço:
# ID do ACR
ACR_ID=$(az acr show --name minhacr --resource-group rg-containers --query id -o tsv)
# Atribuir AcrPull a um service principal
az role assignment create \
--assignee <service-principal-object-id> \
--role AcrPull \
--scope $ACR_ID
# Atribuir AcrPull a um AKS cluster (Managed Identity)
AKS_KUBELET_ID=$(az aks show \
--name meu-cluster-aks \
--resource-group rg-aks \
--query identityProfile.kubeletidentity.objectId -o tsv)
az role assignment create \
--assignee $AKS_KUBELET_ID \
--role AcrPull \
--scope $ACR_ID
Configurar política de retenção (limpar imagens sem tag):
az acr config retention update \
--registry minhacr \
--status enabled \
--days 30 \
--type UntaggedManifests
Geo-replication (apenas Premium):
az acr replication create \
--registry minhacr \
--location eastus
6.3 PowerShell
# Criar ACR
New-AzContainerRegistry `
-ResourceGroupName "rg-containers" `
-Name "minhacr" `
-Sku "Standard" `
-Location "brazilsouth" `
-EnableAdminUser:$false
# Obter ID do ACR
$acr = Get-AzContainerRegistry -Name "minhacr" -ResourceGroupName "rg-containers"
# Atribuir AcrPull a um principal
New-AzRoleAssignment `
-ObjectId "<principal-object-id>" `
-RoleDefinitionName "AcrPull" `
-Scope $acr.Id
# Listar repositories
Get-AzContainerRegistryRepository -RegistryName "minhacr"
6.4 Bicep
param location string = resourceGroup().location
param acrName string = 'minhacr'
resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
name: acrName
location: location
sku: {
name: 'Standard'
}
properties: {
adminUserEnabled: false
policies: {
retentionPolicy: {
status: 'enabled'
days: 30
}
}
}
}
// Dar AcrPull a um AKS Managed Identity
resource acrPullAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(acr.id, aksIdentityObjectId, 'AcrPull')
scope: acr
properties: {
roleDefinitionId: subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'7f951dda-4ed3-4680-a7ca-43fe172d538d' // AcrPull role definition ID
)
principalId: aksIdentityObjectId
principalType: 'ServicePrincipal'
}
}
output acrLoginServer string = acr.properties.loginServer
7. Controle e Segurança
Desabilitar Acesso Público (SKU Premium)
Com o ACR Premium, você pode desabilitar o acesso público e usar apenas Private Link:
# Desabilitar acesso público
az acr update \
--name minhacr \
--resource-group rg-containers \
--public-network-enabled false
# Criar Private Endpoint para o ACR
az network private-endpoint create \
--name pe-acr-minhacr \
--resource-group rg-networking \
--vnet-name vnet-producao \
--subnet subnet-private-endpoints \
--private-connection-resource-id $(az acr show --name minhacr --query id -o tsv) \
--group-id registry \
--connection-name conn-acr-minhacr
Microsoft Defender for Containers
O Microsoft Defender for Containers pode ser habilitado para escanear imagens no ACR em busca de vulnerabilidades conhecidas (CVEs) nos pacotes do sistema operacional e nas dependências da aplicação:
az security pricing create \
--name ContainerRegistry \
--tier Standard
Quando habilitado, cada push de imagem dispara um scan automático, e o resultado fica visível no Microsoft Defender for Cloud com detalhes sobre cada vulnerabilidade encontrada e recomendações de remediação.
Content Trust (Assinatura de Imagens)
O ACR Premium suporta Content Trust baseado em Notary: imagens são assinadas digitalmente, e clientes podem ser configurados para apenas executar imagens com assinatura válida. Isso previne a execução de imagens que não foram produzidas pelo pipeline oficial.
8. Tomada de Decisão
Qual SKU escolher?
| Situação | SKU | Motivo |
|---|---|---|
| Ambiente de desenvolvimento, testes | Basic | Custo mínimo, features suficientes |
| Produção de aplicação única, região única | Standard | Throughput adequado, custo razoável |
| Produção multi-região, alta disponibilidade | Premium | Geo-replication para baixa latência |
| Compliance, rede privada obrigatória | Premium | Private Link disponível apenas no Premium |
| Assinatura de imagens (Content Trust) | Premium | Feature exclusiva do Premium |
Como autenticar pipelines CI/CD no ACR?
| Cenário | Abordagem | Motivo |
|---|---|---|
| Azure DevOps com Service Connection | Service Principal + AcrPush | Integração nativa, auditável |
| GitHub Actions | Service Principal ou Workload Identity Federation | Sem segredo para gerenciar com WIF |
| Azure Pipelines com Managed Identity | Managed Identity do agente + AcrPush | Sem credenciais para rotacionar |
| Build local de desenvolvedor | az acr login (token temporário) | Token expira em 3h, sem credencial persistente |
| Script de automação em VM Azure | Managed Identity da VM + AcrPull/Push | Sem credencial para gerenciar |
| Acesso de sistema externo sem Entra ID | Repository-scoped token | Escopo mínimo, pode ser revogado |
9. Boas Práticas
Nunca use a conta de administrador em produção: a conta de admin compartilha credenciais entre todos que a usam, sem rastreabilidade de quem fez o quê. Use RBAC com identidades específicas para cada workload.
Aplique o princípio do menor privilégio: pipelines de CI que só precisam fazer push recebem AcrPush. Clusters AKS que só precisam fazer pull recebem AcrPull. Ninguém recebe Owner ou Contributor no ACR a menos que precise gerenciar o registry em si.
Use tags semânticas e imutáveis: além da tag latest (para conveniência), use tags semânticas versionadas como v1.2.3 e idealmente também o hash do commit do código (sha-a1b2c3d). Para referências em manifests Kubernetes de produção, use o digest (sha256:...) para garantir que o container seja exatamente o que foi testado.
Configure políticas de retenção: imagens sem tag (untagged) se acumulam rapidamente em pipelines CI que fazem múltiplos builds por dia. Configure retenção para remover imagens sem tag após 30 dias e versões antigas após um número definido de versões.
Implemente scan de vulnerabilidades: habilite Microsoft Defender for Containers e configure alertas para vulnerabilidades críticas. Inclua o resultado do scan no pipeline de CI como gate de qualidade (não promover imagens com vulnerabilidades críticas).
10. Erros Comuns
Usar a conta de admin em pipelines
A conta de admin é habilitada "temporariamente" para um teste e nunca desabilitada. Os pipelines passam a usar essas credenciais. Com o tempo, as credenciais são compartilhadas em múltiplos lugares, ninguém sabe quem tem acesso, e a rotação das senhas se torna um evento traumático. Use Service Principals ou Managed Identities desde o início.
Não configurar política de retenção e esgotar armazenamento
Um pipeline de CI que faz 20 builds por dia produz ~7.300 imagens por ano, cada uma podendo ter GB de dados. Sem política de retenção, o armazenamento cresce indefinidamente e os custos aumentam. Configure retenção para imagens sem tag logo após criar o registry.
Dar AcrPush a workloads que só precisam de AcrPull
Um cluster AKS recebe AcrPush "para não ter problemas". Isso significa que se o cluster for comprometido, um atacante pode fazer push de imagens maliciosas no registry. AKS só precisa de AcrPull para fazer pull das imagens. Nunca dê permissões excessivas.
Confundir az acr login com autenticação de longo prazo
O az acr login obtém um token temporário válido por 3 horas que configura o Docker local. Em pipelines CI, não use az acr login com service principal de forma manual. Use o mecanismo nativo de autenticação da ferramenta (Docker login com --password-stdin usando o token do service principal, ou o task nativo do Azure DevOps).
Referenciar latest em produção
latest é uma tag mutável. Se você faz deploy de minhacr.azurecr.io/api:latest e alguém faz push de uma nova versão com bugs, o próximo restart do container pode puxar a versão com bugs. Em produção, sempre referencie versões específicas ou digests.
11. Operação e Manutenção
Monitorar Uso e Tamanho
# Ver tamanho total usado no registry
az acr show-usage --name minhacr --resource-group rg-containers --output table
# Listar imagens por tamanho
az acr repository show-manifests \
--name minhacr \
--repository api-gateway \
--query "[].{Digest:digest, SizeBytes:imageSize, Tags:tags, Created:timestamp}" \
--output table
Limpeza Manual de Imagens Antigas
# Deletar tags específicas
az acr repository delete \
--name minhacr \
--image api-gateway:v1.0.0 \
--yes
# Purge de imagens sem tag antigas (mais de 30 dias, sem tag)
az acr run \
--cmd "acr purge --filter 'api-gateway:.*' --untagged --ago 30d" \
--registry minhacr \
/dev/null
O comando az acr run com acr purge executa uma task diretamente no ACR para limpeza sem precisar de Docker local.
Limites Importantes
| Item | Basic | Standard | Premium |
|---|---|---|---|
| Armazenamento incluído | 10 GB | 100 GB | 500 GB |
| Leituras de camada/dia | 1.000 | 10.000 | 50.000 |
| Escritas de camada/dia | 200 | 500 | 1.000 |
| Webhooks | 2 | 10 | 500 |
| Replicações geo | - | - | Ilimitado |
12. Integração e Automação
Pipeline Completo: Código para AKS
ACR Tasks para Build Automatizado
Configure uma ACR Task que faz rebuild automático quando o código muda no repositório:
az acr task create \
--registry minhacr \
--name task-build-api-gateway \
--image api-gateway:{{.Run.ID}} \
--arg BUILD_VERSION={{.Run.ID}} \
--context https://github.com/minhaorg/meu-repo.git#refs/heads/main \
--file Dockerfile \
--git-access-token <github-pat>
Quando houver commit na branch main, o ACR automaticamente faz o build e push da imagem com o ID do run como tag.
Integração com Azure DevOps
# azure-pipelines.yml
stages:
- stage: Build
jobs:
- job: BuildAndPush
pool:
vmImage: ubuntu-latest
steps:
- task: AzureCLI@2
inputs:
azureSubscription: 'my-azure-service-connection'
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
az acr build \
--registry minhacr \
--image api-gateway:$(Build.BuildId) \
--image api-gateway:latest \
.
Usando az acr build diretamente do pipeline, não é necessário instalar Docker no agente: o build acontece no contexto do ACR.
13. Resumo Final
Pontos essenciais:
- O ACR é um registry privado gerenciado para imagens de container, com integração nativa ao ecossistema Azure.
- A estrutura é: Registry > Repository > Tag/Digest.
- Três SKUs: Basic (dev/test), Standard (produção padrão), Premium (multi-região, Private Link, Content Trust).
- A autenticação recomendada é via RBAC com Entra ID (Managed Identity ou Service Principal). A conta de admin deve ser evitada em produção.
Diferenças críticas:
- Tag é mutável (pode ser sobrescrita). Digest (SHA-256) é imutável e identifica exatamente uma versão de imagem.
- AcrPull (somente leitura de imagens) vs. AcrPush (escrita e leitura) vs. Contributor (gerencia o registry, não necessariamente acesso às imagens via Docker).
- Az acr login obtém um token temporário de 3 horas para uso local. Não é para pipelines de longa duração.
- ACR Tasks executam builds no Azure sem precisar de Docker local ou agente de build separado.
O que precisa ser lembrado:
- Nunca use a conta de administrador em automações ou produção. Use RBAC com identidades dedicadas.
- Dê
AcrPullao AKS,AcrPushao pipeline de CI, nunca mais do que o necessário. - Configure política de retenção para evitar acúmulo de imagens sem tag e crescimento descontrolado de custos.
- Private Link e geo-replication são funcionalidades exclusivas do SKU Premium.
- Para builds sem Docker local:
az acr build --registry minhacr --image nome:tag . - A atribuição de AcrPull ao AKS é feita no kubelet identity (identidade da node pool), não na identidade do control plane do cluster.