Solucionar problemas de rede em clusters AKS

Problemas de rede podem ocorrer em novas instalações do Kubernetes ou quando você aumenta a carga do Kubernetes. Outros problemas relacionados a problemas de rede também podem ocorrer. Verifique sempre o guia de resolução de problemas do AKS para ver se o seu problema está descrito lá. Este artigo descreve detalhes e considerações adicionais de uma perspetiva de solução de problemas de rede e problemas específicos que podem surgir.

O cliente não consegue acessar o servidor de API

Esses erros envolvem problemas de conexão que ocorrem quando você não consegue acessar o servidor de API de um cluster do Serviço Kubernetes do Azure (AKS) por meio da ferramenta de linha de comando do cluster Kubernetes (kubectl) ou qualquer outra ferramenta, como a API REST por meio de uma linguagem de programação.

Erro

Poderá ver erros semelhantes aos seguintes:

Unable to connect to the server: dial tcp <API-server-IP>:443: i/o timeout 
Unable to connect to the server: dial tcp <API-server-IP>:443: connectex: A connection attempt
failed because the connected party did not properly respond after a period, or established 
connection failed because connected host has failed to respond. 

Causa 1

É possível que os intervalos de IP autorizados pelo servidor de API estejam habilitados no servidor de API do cluster, mas o endereço IP do cliente não está incluído nesses intervalos de IP. Para determinar se os intervalos de IP estão habilitados, use o seguinte az aks show comando na CLI do Azure. Se os intervalos IP estiverem habilitados, o comando produzirá uma lista de intervalos IP.

az aks show --resource-group <cluster-resource-group> \ 
    --name <cluster-name> \ 
    --query apiServerAccessProfile.authorizedIpRanges 

Solução 1

Certifique-se de que o endereço IP do seu cliente está dentro dos intervalos autorizados pelo servidor de API do cluster:

  1. Encontre o seu endereço IP local. Para obter informações sobre como encontrá-lo no Windows e Linux, consulte Como encontrar meu IP.

  2. Atualize o intervalo autorizado pelo servidor de API usando o comando na CLI az aks update do Azure. Autorize o endereço IP do seu cliente. Para obter instruções, consulte Atualizar intervalos de IP autorizados do servidor de API de um cluster.

Causa 2

Se o cluster AKS for um cluster privado, o ponto de extremidade do servidor API não terá um endereço IP público. Você precisa usar uma VM que tenha acesso à rede virtual do cluster AKS.

Solução 2

Para obter informações sobre como resolver esse problema, consulte opções para se conectar a um cluster privado.

Pod não consegue alocar o endereço IP

Erro

O Pod está preso no ContainerCreating estado, e seus eventos relatam um Failed to allocate address erro:

Normal   SandboxChanged          5m (x74 over 8m)    kubelet, k8s-agentpool-00011101-0 Pod sandbox
changed, it will be killed and re-created. 

  Warning  FailedCreatePodSandBox  21s (x204 over 8m)  kubelet, k8s-agentpool-00011101-0 Failed 
create pod sandbox: rpc error: code = Unknown desc = NetworkPlugin cni failed to set up pod 
"deployment-azuredisk6-874857994-487td_default" network: Failed to allocate address: Failed to 
delegate: Failed to allocate address: No available addresses 

Ou um not enough IPs available erro:

Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox 
'ac1b1354613465324654c1588ac64f1a756aa32f14732246ac4132133ba21364': plugin type='azure-vnet' 
failed (add): IPAM Invoker Add failed with error: Failed to get IP address from CNS with error: 
%w: AllocateIPConfig failed: not enough IPs available for 9c6a7f37-dd43-4f7c-a01f-1ff41653609c, 
waiting on Azure CNS to allocate more with NC Status: , IP config request is [IPConfigRequest: 
DesiredIPAddress , PodInterfaceID a1876957-eth0, InfraContainerID 
a1231464635654a123646565456cc146841c1313546a515432161a45a5316541, OrchestratorContext 
{'PodName':'a_podname','PodNamespace':'my_namespace'}]

Verifique os endereços IP alocados no armazenamento IPAM do plugin. Você pode achar que todos os endereços IP são alocados, mas o número é muito menor do que o número de Pods em execução:

Se estiver usando kubenet:

# Kubenet, for example. The actual path of the IPAM store file depends on network plugin implementation. 
chroot /host/
ls -la "/var/lib/cni/networks/$(ls /var/lib/cni/networks/ | grep -e "k8s-pod-network" -e "kubenet")" | grep -v -e "lock\|last\|total" -e '\.$' | wc -l
244

Nota

Para kubenet sem Calico, o caminho é /var/lib/cni/networks/kubenet. Para kubenet com Calico, o caminho é /var/lib/cni/networks/k8s-pod-network. O script acima selecionará automaticamente o caminho durante a execução do comando.

# Check running Pod IPs
kubectl get pods --field-selector spec.nodeName=<your_node_name>,status.phase=Running -A -o json | jq -r '.items[] | select(.spec.hostNetwork != 'true').status.podIP' | wc -l
7 

Se estiver usando o Azure CNI para alocação dinâmica de IP:

kubectl get nnc -n kube-system -o wide
NAME                               REQUESTED IPS  ALLOCATED IPS  SUBNET  SUBNET CIDR   NC ID                                 NC MODE  NC TYPE  NC VERSION
aks-agentpool-12345678-vmss000000  32             32             subnet  10.18.0.0/15  559e239d-f744-4f84-bbe0-c7c6fd12ec17  dynamic  vnet     1
# Check running Pod IPs
kubectl get pods --field-selector spec.nodeName=aks-agentpool-12345678-vmss000000,status.phase=Running -A -o json | jq -r '.items[] | select(.spec.hostNetwork != 'true').status.podIP' | wc -l
21

Causa 1

Este erro pode ser causado por um bug no plug-in de rede. O plugin pode falhar ao desalocar o endereço IP quando um Pod é encerrado.

Solução 1

Entre em contato com a Microsoft para obter uma solução alternativa ou correção.

Causa 2

A criação de Pods é muito mais rápida do que a coleta de lixo de Pods terminados.

Solução 2

Configure a coleta rápida de lixo para o kubelet. Para obter instruções, consulte a documentação de coleta de lixo do Kubernetes.

Serviço não acessível dentro de Pods

A primeira etapa para resolver esse problema é verificar se os pontos de extremidade foram criados automaticamente para o serviço:

kubectl get endpoints <service-name> 

Se você receber um resultado vazio, o seletor de rótulos do seu serviço pode estar errado. Confirme se o rótulo está correto:

# Query Service LabelSelector. 
kubectl get svc <service-name> -o jsonpath='{.spec.selector}' 

# Get Pods matching the LabelSelector and check whether they're running. 
kubectl get pods -l key1=value1,key2=value2 

Se as etapas anteriores retornarem os valores esperados:

  • Verifique se o Pod containerPort é o mesmo que o serviço containerPort.

  • Verifique se podIP:containerPort está funcionando:

    # Testing via cURL. 
    curl -v telnet ://<Pod-IP>:<containerPort>
    
    # Testing via Telnet. 
    telnet <Pod-IP>:<containerPort> 
    

Estas são algumas outras causas potenciais de problemas de serviço:

  • O contêiner não está ouvindo o especificado containerPort. (Verifique a descrição do Pod.)
  • Está ocorrendo um erro de plug-in CNI ou erro de rota de rede.
  • kube-proxy não está em execução ou as regras iptables não estão configuradas corretamente.
  • As Políticas de Rede estão a diminuir o tráfego. Para obter informações sobre como aplicar e testar Políticas de Rede, consulte Visão geral das Políticas de Rede do Kubernetes do Azure.
    • Se você estiver usando o Calico como seu plug-in de rede, também poderá capturar o tráfego da política de rede. Para obter informações sobre como configurar isso, consulte o site do Calico.

Os nós não conseguem acessar o servidor de API

Muitos complementos e contêineres precisam acessar a API do Kubernetes (por exemplo, kube-dns e contêineres do operador). Se ocorrerem erros durante esse processo, as etapas a seguir podem ajudá-lo a determinar a origem do problema.

Primeiro, confirme se a API do Kubernetes está acessível nos Pods:

kubectl run curl --image=mcr.microsoft.com/azure-cli -i -t --restart=Never --overrides='[{"op":"add","path":"/spec/containers/0/resources","value":{"limits":{"cpu":"200m","memory":"128Mi"}}}]' --override-type json --command -- sh

Em seguida, execute o seguinte de dentro do contêiner no qual você está agora descascado.

# If you don't see a command prompt, try selecting Enter. 
KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) 
curl -sSk -H "Authorization: Bearer $KUBE_TOKEN" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/default/pods

A saída saudável será semelhante à seguinte.

{ 
  "kind": "PodList", 
  "apiVersion": "v1", 
  "metadata": { 
    "selfLink": "/api/v1/namespaces/default/pods", 
    "resourceVersion": "2285" 
  }, 
  "items": [ 
   ... 
  ] 
} 

Se ocorrer um erro, verifique se o kubernetes-internal serviço e seus pontos de extremidade estão íntegros:

kubectl get service kubernetes-internal
NAME                TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE 
kubernetes-internal ClusterIP   10.96.0.1    <none>        443/TCP   25m 
kubectl get endpoints kubernetes-internal
NAME                ENDPOINTS          AGE 
kubernetes-internal 172.17.0.62:6443   25m 

Se ambos os testes retornarem respostas como as anteriores, e o IP e a porta retornados corresponderem aos do seu contêiner, é provável que o kube-apiserver não esteja em execução ou esteja bloqueado na rede.

Há quatro razões principais pelas quais o acesso pode ser bloqueado:

  • As suas políticas de rede. Eles podem estar impedindo o acesso ao plano de gerenciamento de API. Para obter informações sobre como testar diretivas de rede, consulte Visão geral de diretivas de rede.
  • Os endereços IP permitidos da sua API. Para obter informações sobre como resolver esse problema, consulte Atualizar intervalos de IP autorizados do servidor de API de um cluster.
  • A sua firewall privada. Se encaminhar o tráfego AKS através de uma firewall privada, certifique-se de que existem regras de saída conforme descrito em Regras de rede de saída necessárias e FQDNs para clusters AKS.
  • O seu DNS privado. Se você estiver hospedando um cluster privado e não conseguir acessar o servidor de API, seus encaminhadores DNS podem não estar configurados corretamente. Para garantir uma comunicação adequada, conclua as etapas no Hub e fale com DNS personalizado.

Você também pode verificar os logs do kube-apiserver usando o Container insights. Para obter informações sobre como consultar logs kube-apiserver e muitas outras consultas, consulte Como consultar logs a partir de insights de contêiner.

Finalmente, você pode verificar o status do kube-apiserver e seus logs no próprio cluster:

# Check kube-apiserver status. 
kubectl -n kube-system get pod -l component=kube-apiserver 

# Get kube-apiserver logs. 
PODNAME=$(kubectl -n kube-system get pod -l component=kube-apiserver -o jsonpath='{.items[0].metadata.name}')
kubectl -n kube-system logs $PODNAME --tail 100

Se um 403 - Forbidden erro retornar, o kube-apiserver provavelmente está configurado com RBAC (controle de acesso baseado em função) e o contêiner ServiceAccount provavelmente não está autorizado a acessar recursos. Neste caso, você deve criar objetos e ClusterRoleBinding apropriadosRoleBinding. Para obter informações sobre funções e associações de funções, consulte Acesso e identidade. Para obter exemplos de como configurar o RBAC em seu cluster, consulte Usando a autorização RBAC.

Contribuidores

Este artigo é mantido pela Microsoft. Foi originalmente escrito pelos seguintes contribuidores.

Autor principal:

Outros contribuidores:

Próximos passos