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:
Localize seu endereço IP local. Para obter informações sobre como encontrá-lo no Windows e no Linux, consulte Como encontrar meu IP.
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çocontainerPort
.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
containerPort
especificado. (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:
- Suas políticas de rede. Eles podem estar impedindo o acesso ao plano de gerenciamento de API. Para obter informações sobre como testar as Políticas de Rede, consulte Visão geral das Políticas de Rede.
- Os endereços IP permitidos da API. Para obter informações sobre como resolver esse problema, consulte Atualizar intervalos de IP autorizados do servidor de API de um cluster.
- Seu firewall privado. Se você rotear o tráfego AKS por meio de um firewall privado, verifique se há regras de saída, conforme descrito em Regras de rede de saída necessárias e FQDNs para clusters AKS.
- 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 a comunicação adequada, conclua as etapas em Hub and spoke 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 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:
- Michael Walters | Consultor Sênior
Outros colaboradores:
- Mick Alberts | Escritor Técnico
- Ayobami Ayodeji | Gerente Sênior de Programa
- Bahram Rushenas | Arquiteto
Próximas etapas
- Conceitos de rede para aplicativos no AKS
- Solucionar problemas de aplicativos
- Depurar serviços
- Rede de cluster do Kubernetes
- Escolher o melhor plug-in de rede para o AKS