Partilhar via


Falha ao efetuar pull de imagens de Registro de Contêiner do Azure para o cluster do Serviço de Kubernetes do Azure

Observação

Esse artigo foi útil? Sua opinião é importante para nós. Use o botão Comentários nesta página para nos informar o quão bem este artigo funcionou para você ou como podemos melhorá-lo.

Quando você estiver usando o Registro de Contêiner do Microsoft Azure junto com o AKS (Serviço de Kubernetes do Azure), um mecanismo de autenticação deve ser estabelecido. Você pode configurar a integração do AKS com o Registro de Contêiner usando alguns comandos simples da CLI do Azure ou do Azure PowerShell. Essa integração atribui a função AcrPull para a identidade kubelet associada ao cluster do AKS para extrair imagens de um registro de contêiner.

Em alguns casos, a tentativa de extrair imagens de um registro de contêiner para um cluster do AKS falha. Este artigo fornece diretrizes para solucionar os erros mais comuns encontrados ao efetuar pull de imagens de um registro de contêiner para um cluster do AKS.

Antes de começar

Este artigo pressupõe que você tenha um cluster do AKS existente e um registro de contêiner existente. Consulte o seguinte início rápido:

Você também precisa que a CLI do Azure versão 2.0.59 ou posterior seja instalada e configurada. Execute az version para determinar a versão. Se você precisar instalar ou atualizar, consulte Instalar a CLI do Azure.

Sintomas e solução de problemas inicial

O STATUS do pod do Kubernetes é ImagePullBackOff ou ErrImagePull. Para obter informações detalhadas sobre o erro, execute o comando a seguir e verifique Eventos na saída.

kubectl describe pod <podname> -n <namespace>

Recomendamos que você inicie a solução de problemas verificando a integridade do registro de contêiner e verificando se o registro de contêiner pode ser acessado no cluster do AKS.

Para verificar a integridade do registro de contêiner, execute o seguinte comando:

az acr check-health --name <myregistry> --ignore-errors --yes

Se um problema for detectado, ele mostrará um código de erro e uma descrição. Para obter mais informações sobre os erros e possíveis soluções, consulte Referência de erro de verificação de integridade.

Observação

Se você receber erros relacionados ao Helm ou ao Notary, isso não significa que um problema está afetando o Registro de Contêiner ou o AKS. Ele indica apenas que o Helm ou o Notary não está instalado ou que a CLI do Azure não é compatível com a versão atual instalada do Helm ou do Notary e assim por diante.

Para validar se o registro de contêiner pode ser acessado no cluster do AKS, execute o seguinte comando az aks check-acr :

az aks check-acr --resource-group <MyResourceGroup> --name <MyManagedCluster> --acr <myacr>.azurecr.io

As seções a seguir ajudam a solucionar os erros mais comuns exibidos em Eventos na saída do kubectl describe pod comando.

Causa 1: erro 401 não autorizado

Um cluster do AKS requer uma identidade. Essa identidade pode ser uma identidade gerenciada ou uma entidade de serviço. Se o cluster do AKS usar uma identidade gerenciada, a identidade kubelet será usada para autenticação com o ACR. Se o cluster do AKS estiver usando como identidade uma entidade de serviço, a própria entidade de serviço será usada para autenticação com o ACR. Não importa qual seja a identidade, a autorização adequada usada para extrair uma imagem de um registro de contêiner é necessária. Caso contrário, você poderá receber o seguinte erro "401 Não autorizado":

Falha ao extrair a imagem "<acrname.azurecr.io/<> repository:tag>": [rpc error: code = Unknown desc = falha ao extrair e descompactar a imagem "<acrname.azurecr.io/<> repository:tag>": falha ao resolver a referência "<acrname.azurecr.io/>< repository:tag>": falha ao autorizar: falha ao buscar o token oauth: status inesperado: 401 Não autorizado

Várias soluções podem ajudá-lo a resolver esse erro, sujeito às seguintes restrições:

Solução 1: verifique se a atribuição de função AcrPull foi criada para identidade

A integração entre o AKS e o Registro de Contêiner cria uma atribuição de função AcrPull no nível do registro de contêiner para a identidade kubelet do cluster do AKS. Verifique se a atribuição de função foi criada.

Para verificar se a atribuição de função AcrPull foi criada, use um dos seguintes métodos:

  • Execute o comando a seguir:

    az role assignment list --scope /subscriptions/<subscriptionID>/resourceGroups/<resourcegroupname>/providers/Microsoft.ContainerRegistry/registries/<acrname> -o table
    
  • Faça check-in no portal do Azure selecionando Atribuições de função do IAM (controle de acesso)> do Registro>de Contêiner do Azure. Para obter mais informações, consulte Listar atribuições de função do Azure usando o portal do Azure.

Além da função AcrPull, algumas funções internas e funções personalizadas também podem conter a ação "Microsoft.ContainerRegistry/registries/pull/read". Verifique essas funções, se você tiver alguma delas.

Se a atribuição de função AcrPull não for criada, crie-a configurando a integração do Registro de Contêiner para o cluster do AKS com o seguinte comando:

az aks update -n <myAKSCluster> -g <myResourceGroup> --attach-acr <acr-resource-id>

Solução 2: verifique se a entidade de serviço não expirou

Verifique se o segredo da entidade de serviço associada ao cluster do AKS não expirou. Para verificar a data de expiração da entidade de serviço, execute os seguintes comandos:

SP_ID=$(az aks show --resource-group <myResourceGroup> --name <myAKSCluster> \
    --query servicePrincipalProfile.clientId -o tsv)

az ad app credential list --id "SP_ID" --query "[].endDateTime" --output tsv

Para obter mais informações, consulte Verificar a data de expiração da entidade de serviço.

Se o segredo tiver expirado, atualize as credenciais do cluster do AKS.

Solução 3: verifique se a função AcrPull está atribuída à entidade de serviço correta

Em alguns casos, a atribuição de função de registro de contêiner ainda se refere à entidade de serviço antiga. Por exemplo, quando a entidade de serviço do cluster do AKS é substituída por uma nova. Para garantir que a atribuição de função do Registro de contêiner se refira à entidade de serviço correta, siga estas etapas:

  1. Para verificar a entidade de serviço usada pelo cluster do AKS, execute o seguinte comando:

    az aks show --resource-group <myResourceGroup> \
        --name <myAKSCluster> \
        --query servicePrincipalProfile.clientId \
        --output tsv
    
  2. Para verificar a entidade de serviço referenciada pela atribuição de função de registro de contêiner, execute o seguinte comando:

    az role assignment list --scope /subscriptions/<subscriptionID>/resourceGroups/<resourcegroupname>/providers/Microsoft.ContainerRegistry/registries/<acrname> -o table
    
  3. Compare as duas entidades de serviço. Se eles não corresponderem, integre o cluster do AKS ao registro de contêiner novamente.

Solução 4: verifique se a identidade do kubelet é referenciada no VMSS do AKS

Quando uma identidade gerenciada é usada para autenticação com o ACR, a identidade gerenciada é conhecida como identidade kubelet. Por padrão, a identidade kubelet é atribuída no nível VMSS do AKS. Se a identidade do kubelet for removida do VMSS do AKS, os nós do AKS não poderão efetuar pull de imagens do ACR.

Para localizar a identidade kubelet do cluster do AKS, execute o seguinte comando:

az aks show --resource-group <MyResourceGroup> --name <MyManagedCluster> --query identityProfile.kubeletidentity

Em seguida, você pode listar as identidades do VMSS do AKS abrindo o VMSS do grupo de recursos do nó e selecionando Usuário de Identidade>atribuído no portal do Azure ou executando o seguinte comando:

az vmss identity show --resource-group <NodeResourceGroup> --name <AksVmssName>

Se a identidade kubelet do cluster do AKS não estiver atribuída ao VMSS do AKS, atribua-a novamente.

Observação

Não há suporte para modificar o VMSS do AKS usando as APIs de IaaS ou do portal do Azure, e nenhuma operação do AKS pode remover a identidade do kubelet do VMSS do AKS. Isso significa que algo inesperado o removeu, por exemplo, uma remoção manual realizada por um membro da equipe. Para evitar essa remoção ou modificação, você pode considerar o uso do recurso NRGLockdown.

Como não há suporte para modificações no VMSS do AKS, elas não se propagam no nível do AKS. Para reatribuir a identidade kubelet ao VMSS do AKS, é necessária uma operação de reconciliação. Para fazer isso, execute o seguinte comando:

az aks update --resource-group <MyResourceGroup> --name <MyManagedCluster>

Solução 5: verifique se a entidade de serviço está correta e se o segredo é válido

Se você efetuar pull de uma imagem usando um segredo de pull de imagem e esse segredo do Kubernetes tiver sido criado usando os valores de uma entidade de serviço, verifique se a entidade de serviço associada está correta e se o segredo ainda é válido. Siga estas etapas:

  1. Execute o seguinte comando kubectl get e base64 para ver os valores do segredo do Kubernetes:

    kubectl get secret <secret-name> --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
    
  2. Verifique a data de expiração executando o seguinte comando az ad sp credential list . O nome de usuário é o valor da entidade de serviço.

    az ad sp credential list --id "<username>" --query "[].endDate" --output tsv
    
  3. Se necessário, redefina o segredo dessa entidade de serviço executando o seguinte comando az ad sp credential reset :

    az ad sp credential reset --name "$SP_ID" --query password --output tsv
    
  4. Atualize ou recrie o segredo do Kubernetes de acordo.

Solução 6: verifique se o segredo do Kubernetes tem os valores corretos da conta de administrador do registro de contêiner

Se você efetuar pull de uma imagem usando um segredo de pull de imagem e esse segredo do Kubernetes tiver sido criado usando valores da conta de administrador do registro de contêiner, verifique se os valores no segredo do Kubernetes são os mesmos que os valores da conta de administrador do registro de contêiner. Siga estas etapas:

  1. Execute o seguinte comando kubectl get e base64 para ver os valores do segredo do Kubernetes:

    kubectl get secret <secret-name> --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
    
  2. No portal do Azure, pesquise e selecione Registros de contêiner.

  3. Na lista de registros de contêiner, selecione seu registro de contêiner.

  4. No painel de navegação do registro de contêiner, selecione Chaves de acesso.

  5. Na página Chaves de acesso do registro de contêiner, compare os valores do registro de contêiner com os valores no segredo do Kubernetes.

  6. Se os valores não corresponderem, atualize ou recrie o segredo do Kubernetes de acordo.

Observação

Se ocorreu uma operação Regenerar senha, uma operação chamada "Regenerar Credenciais de Logon do Registro de Contêiner" será exibida na página Log de atividades do registro de contêiner. O registro de atividades tem um período de retenção de 90 dias.

Causa 2: erro de imagem não encontrada

Falha ao extrair a imagem "<acrname.azurecr.io/<> repository:tag>": [erro rpc: código = NotFound desc = falha ao extrair e descompactar a imagem "<acrname.azurecr.io/<> repository:tag>": falha ao resolver a referência "<acrname.azurecr.io/>< repository:tag>": <acrname.azurecr.io/>< repository:tag>: não encontrado

Solução: verifique se o nome da imagem está correto

Se você vir esse erro, certifique-se de que o nome da imagem esteja totalmente correto. Você deve verificar o nome do registro, o servidor de login do registro, o nome do repositório e a tag. Um erro comum é que o servidor de login é especificado como "azureacr.io" em vez de "azurecr.io".

Se o nome da imagem não estiver totalmente correto, o erro 401 Não autorizado também poderá ocorrer porque o AKS sempre tenta pull anônimo, independentemente de o registro de contêiner ter habilitado o acesso de pull anônimo.

Causa 3: 403 Erro proibido

Falha ao extrair a imagem "<acrname.azurecr.io/<> repository:tag>": erro rpc: código = Desconhecido desc = falha ao extrair e descompactar a imagem "<acrname.azurecr.io/<> repository:tag>": falha ao resolver a referência "<acrname.azurecr.io/>< repository:tag>": falha ao autorizar: falha ao buscar token anônimo: status inesperado: 403 Proibido

Se o adaptador de rede do ponto de extremidade privado do registro de contêiner e o cluster do AKS estiverem em redes virtuais diferentes, verifique se o link de rede virtual para a rede virtual do cluster do AKS está definido na zona DNS privada do registro de contêiner. (Esse link é chamado de "privatelink.azurecr.io" por padrão.) Se o link de rede virtual não estiver na zona DNS Privada do registro de contêiner, adicione-o usando uma das seguintes maneiras:

Solução 2: Adicionar o endereço IP público do Balanceador de Carga do AKS ao intervalo de endereços IP permitido do registro de contêiner

Se o cluster do AKS se conectar publicamente ao registro de contêiner (NÃO por meio de um link privado ou de um ponto de extremidade) e o acesso à rede pública do registro de contêiner estiver limitado às redes selecionadas, adicione o endereço IP público do Balanceador de Carga do AKS ao intervalo de endereços IP permitido do registro de contêiner:

  1. Verifique se o acesso à rede pública está limitado às redes selecionadas.

    No portal do Azure, navegue até o registro de contêiner. Em Configurações, selecione Rede. Na guia Acesso público, o acesso à rede pública é definido como Redes selecionadas ou Desabilitado.

  2. Obtenha o endereço IP público do Balanceador de Carga do AKS usando uma das seguintes maneiras:

    • No portal do Azure, navegue até o cluster do AKS. Em Configurações, selecione Propriedades, selecione um dos conjuntos de dimensionamento de máquinas virtuais no grupo de recursos de infraestrutura e verifique o endereço IP público do Balanceador de Carga do AKS.

    • Execute o comando a seguir:

      az network public-ip show --resource-group <infrastructure-resource-group> --name <public-IP-name> --query ipAddress -o tsv
      
  3. Permita o acesso do endereço IP público do Balanceador de Carga do AKS usando uma das seguintes maneiras:

    • Execute az acr network-rule add o comando da seguinte maneira:

      az acr network-rule add --name acrname --ip-address <AKS-load-balancer-public-IP-address>
      

      Para obter mais informações, consulte Adicionar regra de rede ao Registro.

    • No portal do Azure, navegue até o registro de contêiner. Em Configurações, selecione Rede. Na guia Acesso público, em Firewall, adicione o endereço IP público do Balanceador de Carga do AKS ao Intervalo de endereços e selecione Salvar. Para obter mais informações, consulte Acesso da rede pública selecionada - portal.

      Observação

      Se o acesso à rede pública estiver definido como Desabilitado, alterne-o primeiro para Redes selecionadas .

      Captura de tela sobre como adicionar o endereço IP público do Balanceador de Carga do AKS ao intervalo de endereços

Causa 4: "erro de tempo limite de E/S"

Falha ao extrair a imagem "<acrname.azurecr.io/<> repository:tag>": erro rpc: código = Desconhecido desc = falha ao extrair e descompactar a imagem "<acrname.azurecr.io/<> repository:tag>": falha ao resolver a referência "<acrname.azurecr.io/<> repository:tag>": falha ao fazer a solicitação: Cabeçalho "https://< acrname.azurecr.io/v2/<> repository>/manifests/v1": disque tcp <acrprivateipaddress>:443: tempo limite de E/S

Observação

O erro "tempo limite de E/S" ocorre somente quando você se conecta de forma privada a um registro de contêiner usando o Link Privado do Azure.

Solução 1: verifique se o emparelhamento de rede virtual é usado

Se o adaptador de rede do ponto de extremidade privado do registro de contêiner e o cluster do AKS estiverem em redes virtuais diferentes, verifique se o emparelhamento de rede virtual é usado para ambas as redes virtuais. Você pode verificar o emparelhamento de rede virtual executando o comando az network vnet peering list --resource-group <MyResourceGroup> --vnet-name <MyVirtualNetwork> --output table da CLI do Azure ou no portal do Azure selecionando os Emparelhamentos de VNETs> no painel Configurações. Para obter mais informações sobre como listar todos os emparelhamentos de uma rede virtual especificada, consulte az network vnet peering list.

Se o emparelhamento de rede virtual for usado para ambas as redes virtuais, verifique se o status é "Conectado". Se o status for Desconectado, exclua o emparelhamento de ambas as redes virtuais e recrie-o. Se o status for "Conectado", consulte o guia de solução de problemas: O status de emparelhamento é "Conectado".

Para obter mais soluções de problemas, conecte-se a um dos nós ou pods do AKS e teste a conectividade com o registro de contêiner no nível TCP usando o utilitário Telnet ou Netcat. Verifique o endereço IP com o nslookup <acrname>.azurecr.io comando e execute-o telnet <ip-address-of-the-container-registry> 443 .

Para obter mais informações sobre como se conectar a nós do AKS, consulte Conectar-se com SSH aos nós de cluster do AKS (Serviço de Kubernetes do Azure) para manutenção ou solução de problemas.

Solução 2: Usar o Serviço de Firewall do Azure

Se o adaptador de rede do ponto de extremidade privado do registro de contêiner e o cluster do AKS estiverem em redes virtuais diferentes, além do emparelhamento de rede virtual, você poderá usar o Serviço de Firewall do Azure para configurar uma topologia de rede Hub-spoke no Azure. Ao configurar a regra de firewall, você precisa usar regras de rede para permitir explicitamente a conexão de saída com os endereços IP do ponto de extremidade privado do registro de contêiner.

Causa 5: nenhuma correspondência para a plataforma no manifesto

O sistema operacional do host (sistema operacional do nó) é incompatível com a imagem usada para o pod ou contêiner. Por exemplo, se você programar um pod para executar um contêiner do Linux em um nó do Windows ou um contêiner do Windows em um nó do Linux, ocorrerá o seguinte erro:

Falha ao extrair a imagem "<acrname.azurecr.io/<> repository:tag>":
[
  Erro de RPC:
  código = NotFound
  desc = falha ao extrair e descompactar a imagem "<acrname.azurecr.io/>< repository:tag>": nenhuma correspondência para a plataforma no manifesto: não encontrado,
]

Esse erro pode ocorrer para uma imagem extraída de qualquer fonte, desde que a imagem seja incompatível com o sistema operacional host. O erro não se limita a imagens extraídas do registro de contêiner.

Solução: configure o campo nodeSelector corretamente no pod ou na implantação

Especifique o campo correto nodeSelector nas definições de configuração do pod ou da implantação. O valor correto para a kubernetes.io/os configuração desse campo garante que o pod seja agendado no tipo correto de nó. A tabela a seguir mostra como definir a kubernetes.io/os configuração no YAML:

Tipo de contêiner Configuração YAML
Contêiner do Linux "kubernetes.io/os": linux
Contêiner do Windows "kubernetes.io/os": windows

Por exemplo, o código YAML a seguir descreve um pod que precisa ser agendado em um nó do Linux:

apiVersion: v1
kind: Pod
metadata:
  name: aspnetapp
  labels:
    app: aspnetapp
spec:
  containers:
  - image: "mcr.microsoft.com/dotnet/core/samples:aspnetapp"
    name: aspnetapp-image
    ports:
    - containerPort: 80
      protocol: TCP
  nodeSelector:
    "kubernetes.io/os": linux

Mais informações

Se as diretrizes de solução de problemas neste artigo não ajudarem você a resolver o problema, aqui estão algumas outras coisas a serem consideradas:

  • Verifique os grupos de segurança de rede e as tabelas de rotas associadas às sub-redes, se você tiver algum desses itens.

  • Se um dispositivo virtual, como um firewall, controlar o tráfego entre sub-redes, verifique o firewall e as regras de acesso do Firewall.

Aviso de isenção de responsabilidade para informações de terceiros

Os produtos de terceiros mencionados neste artigo são produzidos por empresas independentes da Microsoft. A Microsoft não oferece nenhuma garantia, implícita ou não, do desempenho ou da confiabilidade desses produtos.

Entre em contato conosco para obter ajuda

Se você tiver dúvidas ou precisar de ajuda, crie uma solicitação de suporte ou peça ajuda à comunidade de suporte do Azure. Você também pode enviar comentários sobre o produto para a comunidade de comentários do Azure.