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. Sempre verifique o guia de solução de problemas do AKS para ver se o problema está descrito lá. Este artigo descreve detalhes e considerações adicionais de uma perspectiva de solução de problemas de rede e problemas específicos que podem surgir.

O cliente não pode 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 AKS (Serviço de Kubernetes do Azure) 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

Você pode ver erros parecidos com estes:

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 esteja incluído nesses intervalos de IP. Para determinar se os intervalos de IP estão habilitados, use o comando az aks show a seguir na CLI do Azure. Se os intervalos de IP estiverem habilitados, o comando produzirá uma lista de intervalos de IP.

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

Solução 1

Verifique se o endereço IP do cliente está dentro dos intervalos autorizados pelo servidor de API do cluster:

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

  2. Atualize o intervalo autorizado pelo servidor de API usando o comando az aks update na CLI do Azure. Autorize o endereço IP do seu cliente. Para obter instruções, consulte Atualizar os 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 de API não terá um endereço IP público. Você precisa usar uma VM que tenha acesso de rede à rede virtual do cluster AKS.

Solução 2

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

O pod falha ao alocar o endereço IP

Erro

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

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 repositório IPAM do plug-in. Você pode descobrir que todos os endereços IP estã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

Observação

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 CNI do Azure 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 uma 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 de lixo rápida para o kubelet. Para obter instruções, consulte a documentação da coleta de lixo do Kubernetes.

Serviço não acessível nos 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ê obtiver um resultado vazio, o seletor de rótulo do 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 é igual ao do 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á escutando o containerPortespecificado. (Verifique a descrição do Pod).
  • Está ocorrendo um erro de plug-in CNI ou de rota de rede.
  • O kube-proxy não está em execução ou as regras de iptables não estão configuradas corretamente.
  • As Políticas de Rede estão descartando 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 estiver usando o Calico como seu plug-in de rede, você também poderá capturar o tráfego de política de rede. Para obter informações sobre como configurar isso, consulte o site do Calico.

Os nós não podem 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 ajudar você 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á.

# 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 íntegra será semelhante ao seguinte.

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

Se ocorrer um erro, verifique se o serviço kubernetes-internal 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 da rede.

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

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

Por fim, 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 erro 403 - Forbidden for retornado, o kube-apiserver provavelmente estará configurado com o RBAC (controle de acesso baseado em função) e o contêiner ServiceAccount provavelmente não está autorizado a acessar recursos. Nesse caso, você deve criar os objetos RoleBinding e ClusterRoleBinding apropriados. Para obter informações sobre funções e associações de função, consulte Acesso e identidade. Para obter exemplos de como configurar o RBAC no cluster, consulte Uso da Autorização RBAC.

Colaboradores

Esse artigo é mantido pela Microsoft. Ele foi originalmente escrito pelos colaboradores a seguir.

Autor principal:

Outros colaboradores:

Próximas etapas