Pular para o conteúdo principal

Solução de problemas de rede

Problemas de rede no AKS são os mais difíceis de depurar porque as falhas são silenciosas. Um pod não recebe tráfego e não há log de erro dizendo o motivo. Esta página oferece uma abordagem sistemática.

Comece aqui

Antes de investigar falhas específicas, colete informações de base:

# Cluster networking model
az aks show -g myRG -n myCluster --query "networkProfile" -o table

# Node status and IPs
kubectl get nodes -o wide

# All services and their endpoints
kubectl get svc -A

# All network policies
kubectl get networkpolicy -A

Serviço inacessível

Um serviço ClusterIP ou LoadBalancer existe mas os clientes não recebem resposta.

Árvore de decisão

1. O serviço tem endpoints?

kubectl get endpoints <service-name> -n <namespace>
ResultadoCausaCorreção
Nenhum endpoint listadoNenhum pod corresponde ao seletor do serviçoCorrija os labels dos pods para corresponder ao spec.selector do serviço
Endpoints existem mas IPs estão erradosPods existem mas não estão ReadyVerifique as readiness probes, corrija o health check
Endpoints existem e parecem corretosO problema está em outro lugarContinue para o passo 2

2. Os labels dos pods correspondem ao seletor do serviço?

# Show service selector
kubectl get svc <service-name> -n <ns> -o jsonpath='{.spec.selector}'

# Show pod labels
kubectl get pods -n <ns> --show-labels

Os labels do seletor devem ser um subconjunto exato dos labels dos pods. Um único erro de digitação quebra tudo.

3. Os pods estão realmente Ready?

kubectl get pods -n <ns> -o wide | grep -v "1/1"

Se os pods mostram 0/1 ou Running mas não Ready, a readiness probe está falhando. O serviço não enviará tráfego para pods que não estão Ready.

4. A porta está correta?

kubectl get svc <service-name> -n <ns> -o yaml | grep -A 5 "ports:"
aviso

A port do serviço é onde os clientes se conectam. O targetPort deve corresponder à porta em que seu container realmente escuta. Essas são frequentemente diferentes e mal configuradas.

5. Teste a conectividade de dentro do cluster:

# Run a debug pod
kubectl run nettest --image=nicolaka/netshoot --rm -it -- bash

# From inside the debug pod
curl -v http://<service-name>.<namespace>.svc.cluster.local:<port>

Ingress não funciona

O tráfego externo não está chegando ao seu aplicativo através de um recurso ingress.

Árvore de decisão

1. O ingress controller está rodando?

# For NGINX ingress
kubectl get pods -n ingress-nginx

# For Application Gateway Ingress Controller (AGIC)
kubectl get pods -n kube-system -l app=ingress-appgw

Se o pod do controller não está Running, resolva isso primeiro. Nada mais importa.

2. O recurso ingress existe e tem um endereço?

kubectl get ingress -A
kubectl describe ingress <name> -n <ns>
SintomaCausaCorreção
Coluna ADDRESS vaziaO controller não reconciliou o recursoVerifique os logs do controller para erros
ADDRESS mostra um IP mas requisições dão timeoutO load balancer está saudável mas o backend nãoVerifique o serviço e os pods do backend
404 do ingress controllerNenhuma regra corresponde ao host/caminhoCorrija o host e o caminho na spec do ingress
502 Bad GatewayO serviço backend existe mas os pods não estão respondendoVerifique a saúde dos pods, readiness probes e targetPort

3. O TLS está configurado corretamente?

# Check the secret exists
kubectl get secret <tls-secret-name> -n <ns>

# Verify the certificate
kubectl get secret <tls-secret-name> -n <ns> -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates -subject
dica

Certificados expirados são a causa número um de falhas de TLS no ingress. Configure o cert-manager com Let's Encrypt para automatizar a renovação. Nunca gerencie certificados TLS manualmente.

4. O DNS está apontando para o ingress?

nslookup myapp.example.com
# The IP should match the ingress ADDRESS
kubectl get ingress <name> -n <ns> -o jsonpath='{.status.loadBalancer.ingress[0].ip}'

Falhas de resolução DNS

Pods não conseguem resolver nomes de serviço, hostnames externos ou ambos.

Árvore de decisão

1. O CoreDNS está rodando?

kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=50

Se os pods do CoreDNS estão em CrashLoopBackOff, o DNS do cluster inteiro está quebrado. Resolva isso imediatamente.

2. Os pods conseguem resolver nomes internos?

kubectl run dnstest --image=nicolaka/netshoot --rm -it -- \
nslookup kubernetes.default.svc.cluster.local
ResultadoCausaCorreção
Resolução bem-sucedidaDNS interno funciona, o problema é externoContinue para o passo 3
connection timed out; no servers could be reachedCoreDNS está inacessívelVerifique os pods do CoreDNS e o serviço kube-dns em kube-system
server can't findNome do serviço está errado ou não existeVerifique se o serviço existe no namespace esperado

3. Os pods conseguem resolver nomes externos?

kubectl run dnstest --image=nicolaka/netshoot --rm -it -- \
nslookup microsoft.com

Se a resolução interna funciona mas a externa falha, verifique a configuração do CoreDNS:

kubectl get configmap coredns -n kube-system -o yaml

4. Um DNS customizado está sobrescrevendo o Azure DNS?

az network vnet show -g myRG -n myVNet --query "dhcpOptions.dnsServers"
aviso

Se você definiu servidores DNS customizados na VNet, todas as consultas DNS dos pods vão para esses servidores primeiro. Se esses servidores não conseguem resolver nomes internos do Kubernetes, a descoberta de serviços quebra completamente. Use a abordagem de encaminhamento condicional: encaminhe cluster.local para o CoreDNS, todo o resto para seu DNS customizado.


Egress bloqueado

Pods não conseguem acessar serviços externos, registries ou APIs do Azure.

Árvore de decisão

1. Verifique as regras NSG na subnet:

az network nsg list -g MC_myRG_myCluster_eastus2 -o table
az network nsg rule list -g MC_myRG_myCluster_eastus2 --nsg-name <nsg-name> -o table

2. Verifique se o Azure Firewall ou um NVA está bloqueando tráfego:

# Show the route table on the AKS subnet
az network route-table list -g MC_myRG_myCluster_eastus2 -o table
az network route-table route list -g MC_myRG_myCluster_eastus2 --route-table-name <table> -o table

Se uma UDR envia 0.0.0.0/0 para um firewall, esse firewall deve permitir o tráfego de saída obrigatório do AKS. Veja as regras obrigatórias na seção de Recursos.

3. Verifique network policies bloqueando egress:

kubectl get networkpolicy -n <ns> -o yaml

Procure por policyTypes que incluam Egress. Se uma política de egress existe, ela deve permitir explicitamente o destino.

4. Teste a conectividade de saída a partir de um pod:

kubectl run egresstest --image=nicolaka/netshoot --rm -it -- bash

# Test HTTPS
curl -v https://mcr.microsoft.com
# Test DNS
nslookup mcr.microsoft.com
# Test specific port
nc -zv <destination-ip> <port>
informação

Clusters AKS com outboundType: userDefinedRouting exigem que você permita explicitamente todo o egress. Os destinos mínimos obrigatórios incluem mcr.microsoft.com, management.azure.com, login.microsoftonline.com e as service tags da sua região Azure. A falta de qualquer um desses causa falhas no provisionamento de nós.


Cluster privado não conecta

Você não consegue executar comandos kubectl em um cluster AKS privado.

Árvore de decisão

1. Sua máquina consegue resolver o nome DNS do API server?

nslookup <cluster-name>.<private-dns-zone>.privatelink.<region>.azmk8s.io

Se isso falhar, sua máquina não consegue ver a zona DNS privada. Você precisa de encaminhamento DNS ou um link direto para a zona DNS privada.

2. Você está em uma rede que consegue alcançar o API server?

Clusters privados não têm IP público no API server. Você precisa estar em:

  • A mesma VNet ou uma VNet com peering
  • Uma VPN conectada à VNet
  • Um circuito ExpressRoute conectado à VNet
  • Uma VM jumpbox dentro da VNet

3. A zona DNS privada está vinculada à sua VNet?

az network private-dns zone list -g MC_myRG_myCluster_eastus2 -o table
az network private-dns link vnet list -g MC_myRG_myCluster_eastus2 -z <zone-name> -o table

4. Faixas de IP autorizadas estão bloqueando você?

az aks show -g myRG -n myCluster --query "apiServerAccessProfile" -o yaml

Se authorizedIpRanges está definido, o IP do seu cliente deve estar na lista. Use --api-server-authorized-ip-ranges "" para limpá-las temporariamente para depuração.

dica

Para acesso diário a clusters privados, use az aks command invoke. Ele executa comandos kubectl através do plano de controle do Azure sem precisar de acesso VPN ou jumpbox.

az aks command invoke -g myRG -n myCluster --command "kubectl get pods -A"

Network policy bloqueando tráfego

Os pods estão rodando e os serviços têm endpoints, mas o tráfego ainda está bloqueado.

Árvore de decisão

1. Quais políticas afetam o pod alvo?

# List all network policies in the namespace
kubectl get networkpolicy -n <ns>

# Check which ones select your pod
kubectl get networkpolicy -n <ns> -o json | \
jq '.items[] | select(.spec.podSelector.matchLabels | to_entries[] | .key as $k | .value as $v | "'<pod-labels>'" | contains($k + "=" + $v)) | .metadata.name'

Abordagem mais simples: leia cada política no namespace e verifique se seu podSelector corresponde aos labels do seu pod.

2. Entenda o comportamento de negação padrão:

CenárioResultado
Nenhuma network policy no namespaceTodo tráfego permitido (padrão)
Política com podSelector: {} e Ingress em policyTypesTodo ingress bloqueado para todos os pods, a menos que explicitamente permitido
Política selecionando pods específicos com tipo IngressApenas esses pods têm ingress restrito; outros pods não são afetados
Política com ambos Ingress e Egress em policyTypesAmbas as direções bloqueadas para os pods selecionados, a menos que permitido

3. Erros comuns:

ErroO que aconteceCorreção
Permitir ingress pela porta mas protocolo erradoTCP é o padrão. Se seu app usa UDP, você deve especificar protocol: UDPAdicione protocolo explícito à regra de porta
namespaceSelector faltando no ingress de outro namespaceTráfego de outros namespaces é bloqueado mesmo se o seletor de pod corresponderAdicione namespaceSelector com os labels do namespace de origem
Política de egress sem regra de egress para DNSPods não conseguem resolver nenhum nome DNS, causando falha em toda conectividade externaPermita egress para kube-system na porta 53 (TCP e UDP)
aviso

Se você adicionar uma network policy com policyTypes: ["Ingress"] e uma lista ingress: [] vazia, você criou uma negação padrão para todos os pods correspondentes. Esta é a causa mais comum de interrupção acidental por network policies.


Script de diagnóstico rápido

Execute isso para coletar o estado da rede de uma só vez:

#!/bin/bash
NS=${1:-default}
echo "=== Nodes ==="
kubectl get nodes -o wide
echo ""
echo "=== Services in $NS ==="
kubectl get svc -n "$NS" -o wide
echo ""
echo "=== Endpoints in $NS ==="
kubectl get endpoints -n "$NS"
echo ""
echo "=== Ingress in $NS ==="
kubectl get ingress -n "$NS"
echo ""
echo "=== Network Policies in $NS ==="
kubectl get networkpolicy -n "$NS"
echo ""
echo "=== CoreDNS pods ==="
kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
echo ""
echo "=== Recent CoreDNS logs ==="
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=20
echo ""
echo "=== DNS test (internal) ==="
kubectl run dnscheck --image=busybox:1.36 --rm -it --restart=Never -- \
nslookup kubernetes.default.svc.cluster.local 2>&1 || true
echo ""
echo "=== DNS test (external) ==="
kubectl run dnscheck2 --image=busybox:1.36 --rm -it --restart=Never -- \
nslookup microsoft.com 2>&1 || true

Recursos