Depurando Problemas de Rede no Kubernetes: Técnicas Essenciais

Depure problemas de rede no Kubernetes em conectividade de pods, serviços, DNS, NetworkPolicies e roteamento Ingress.

Depurando Problemas de Rede no Kubernetes: Técnicas Essenciais

Os problemas de rede no Kubernetes geralmente se manifestam como timeouts, Connection refused, falhas de DNS, endpoints de serviço vazios ou respostas Ingress incorretas. Para corrigi-los rapidamente, trace o caminho: pod de origem, pod de destino, Serviço, DNS, NetworkPolicy e, em seguida, Ingress ou balanceador de carga.

Este guia fornece uma sequência prática de verificações e os comandos kubectl que expõem onde o tráfego para.

Entendendo os Fundamentos de Rede do Kubernetes

Antes de mergulhar na depuração, é importante compreender os conceitos centrais de rede no Kubernetes:

  • Rede de Pods: Cada pod recebe seu próprio endereço IP exclusivo. Pods no mesmo nó podem se comunicar diretamente. Pods em nós diferentes se comunicam por meio de uma rede virtual (plugin CNI).
  • Serviços: Os Serviços fornecem um endereço IP estável e um nome DNS para um conjunto de pods. Eles atuam como uma camada de abstração, permitindo que outros pods ou clientes externos acessem os backends do aplicativo sem precisar saber os IPs individuais dos pods.
  • DNS: O DNS do Kubernetes (geralmente CoreDNS) resolve nomes de Serviço para IPs de cluster, permitindo a descoberta de serviços.
  • Políticas de Rede: Esses recursos controlam o tráfego de pods quando seu plugin CNI os aplica. Um cluster sem suporte a NetworkPolicy aceitará os objetos, mas pode não aplicar as regras.
  • Ingress: Os controladores Ingress gerenciam o acesso externo a serviços dentro do cluster, normalmente HTTP e HTTPS. Eles fornecem roteamento, balanceamento de carga e terminação SSL.

Problemas Comuns de Rede e Estratégias de Depuração

1. Falhas de Comunicação Pod-a-Pod

Quando os pods não conseguem se comunicar entre si, mesmo dentro do mesmo namespace, é um indicador primário de um problema de rede.

Sintomas:

  • Erros de aplicativo indicando timeouts ou recusas de conexão.
  • Comandos curl ou ping de um pod para outro falham.

Etapas de Depuração:

  1. Verifique os IPs dos Pods: Certifique-se de que os pods de origem e destino tenham endereços IP válidos. Use kubectl exec <nome-do-pod> -- ip addr.
  2. Verifique a Conectividade de Rede (dentro do pod): Do pod de origem, tente pingar o endereço IP do pod de destino. Se isso falhar, o problema pode ser com o plugin CNI ou a rede do nó.
    kubectl exec <nome-do-pod-origem> -- ping <ip-do-pod-destino>
    
  3. Inspecione as Políticas de Rede: As Políticas de Rede são um culpado comum. Verifique se alguma política está bloqueando inadvertidamente o tráfego entre os pods.
    kubectl get networkpolicies -n <namespace>
    
    Examine as regras podSelector e ingress/egress para entender qual tráfego é permitido ou negado. Uma vez que um pod é selecionado por uma política de entrada, apenas o tráfego de entrada explicitamente permitido é permitido.
  4. Status do Plugin CNI: Certifique-se de que seu plugin de Interface de Rede de Contêiner (CNI) (por exemplo, Calico, Flannel, Cilium) esteja funcionando corretamente em todos os nós. Verifique os logs dos pods do daemonset CNI.
    kubectl get pods -n kube-system -l k8s-app=<rótulo-do-plugin-cni>
    kubectl logs <nome-do-pod-plugin-cni> -n kube-system
    

2. Problemas de Descoberta de Serviço

Quando os pods não conseguem alcançar outros serviços por seus nomes DNS ou IPs de cluster, isso indica um problema com o DNS do Kubernetes ou a configuração do objeto Serviço.

Sintomas:

  • Erros de aplicativo como Name or service not known.
  • Comandos nslookup ou dig dentro de um pod falham ao resolver nomes de serviço.

Etapas de Depuração:

  1. Verifique a Resolução DNS: De um pod, teste a resolução DNS para um serviço conhecido.
    kubectl exec <nome-do-pod> -- nslookup <nome-do-serviço>.<namespace>.svc.cluster.local
    
    Se isso falhar, verifique os pods do CoreDNS em busca de erros.
    kubectl get pods -n kube-system -l k8s-app=kube-dns
    kubectl logs <nome-do-pod-coredns> -n kube-system
    
  2. Verifique o Objeto Serviço: Certifique-se de que o objeto Serviço esteja configurado corretamente e tenha endpoints apontando para pods saudáveis.
    kubectl get service <nome-do-serviço> -n <namespace> -o yaml
    kubectl get endpoints <nome-do-serviço> -n <namespace>
    
    A saída de endpoints deve listar os endereços IP dos pods que suportam o serviço.
  3. Sondagens de Prontidão do Pod: Se os pods não estiverem passando em suas sondagens de prontidão, eles não serão adicionados aos endpoints do Serviço. Verifique as configurações da sonda de prontidão e os logs do pod para problemas.

3. Problemas do Controlador Ingress

O acesso externo aos seus serviços é gerenciado por recursos Ingress e controladores Ingress. Problemas aqui podem tornar seu aplicativo inacessível de fora do cluster.

Sintomas:

  • Erros 502 Bad Gateway, 404 Not Found ou 503 Service Unavailable ao acessar aplicativos por meio de sua URL externa.
  • Logs do controlador Ingress mostrando erros relacionados a serviços de backend.

Etapas de Depuração:

  1. Verifique os Pods do Controlador Ingress: Certifique-se de que os pods do controlador Ingress (por exemplo, Nginx Ingress, Traefik) estejam em execução e saudáveis.
    kubectl get pods -l app.kubernetes.io/component=controller # Ajuste o rótulo com base no seu controlador ingress
    kubectl logs <nome-do-pod-controlador-ingress> -n <namespace-do-ingress>
    
  2. Verifique o Recurso Ingress: Verifique a configuração do seu recurso Ingress.
    kubectl get ingress <nome-do-ingress> -n <namespace> -o yaml
    
    Certifique-se de que a seção rules mapeie corretamente nomes de host e caminhos para o service.name e service.port apropriados.
  3. Verifique o Serviço e os Endpoints: Assim como na descoberta de serviço, certifique-se de que o serviço de backend para o qual o Ingress aponta esteja configurado corretamente e tenha endpoints saudáveis.
    kubectl get service <nome-do-serviço-backend> -n <namespace>
    kubectl get endpoints <nome-do-serviço-backend> -n <namespace>
    
  4. Firewall e Balanceador de Carga: Se estiver acessando de fora do cluster, certifique-se de que quaisquer firewalls externos ou balanceadores de carga do provedor de nuvem estejam configurados corretamente para encaminhar o tráfego para o serviço do controlador Ingress (geralmente um serviço do tipo LoadBalancer).

4. Aplicação de Política de Rede

As Políticas de Rede podem ser poderosas, mas também uma fonte de problemas de conectividade se mal configuradas. Elas operam pelo princípio do menor privilégio; se uma política não permite explicitamente o tráfego, ele é negado.

Etapas de Depuração:

  1. Identifique as Políticas Aplicadas: Determine quais Políticas de Rede estão afetando os pods em questão.
    kubectl get networkpolicy -n <namespace>
    
  2. Inspecione os Seletores de Política: Examine cuidadosamente o podSelector em cada NetworkPolicy relevante. Este seletor determina a quais pods a política se aplica. Se um pod é selecionado por várias políticas, o tráfego permitido é a união dessas regras de política, não a regra única mais restritiva.
  3. Revise as Regras de Entrada/Saída: Analise as seções ingress e egress da Política de Rede. Se você está tentando estabelecer uma conexão do Pod A para o Pod B, você precisa garantir:
    • Uma Política de Rede aplicada ao Pod B permite tráfego de entrada do Pod A (ou um seletor de rótulo mais amplo que inclua o Pod A).
    • Uma Política de Rede aplicada ao Pod A permite tráfego de saída para o Pod B (ou um seletor de rótulo mais amplo que inclua o Pod B).
  4. Teste com uma Política Ampla: Como uma etapa temporária de solução de problemas, você pode criar uma Política de Rede que permita todo o tráfego de e para pods ou namespaces específicos para ver se a conectividade é restaurada. Isso ajuda a isolar se o problema é realmente com as Políticas de Rede.
    # Exemplo: Permitir toda entrada e saída para pods com rótulo app=my-app
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-all-for-my-app
      namespace: default
    spec:
      podSelector:
        matchLabels:
          app: my-app
      policyTypes:
      - Ingress
      - Egress
      ingress:
        - {}
      egress:
        - {}
    
    Aviso: Esta política allow-all deve ser usada apenas para depuração temporária. Remova-a assim que terminar o teste.

Ferramentas e Comandos Essenciais

  • kubectl exec: Execute comandos dentro de um pod (por exemplo, ping, curl, nslookup).
  • kubectl logs: Visualize logs de pods, especialmente para componentes do plano de controle e plugins de rede.
  • kubectl describe: Obtenha informações detalhadas sobre pods, serviços, ingress e políticas de rede, que geralmente revelam status e eventos.
  • kubectl get: Liste recursos e seu status básico.
  • tcpdump: Um poderoso analisador de pacotes de linha de comando. Você pode executá-lo dentro de um pod ou em um nó para capturar o tráfego de rede.
    # Exemplo: Capturar tráfego na interface eth0 dentro de um pod
    kubectl exec <nome-do-pod> -- tcpdump -i eth0 -nn port 80
    

Conclusão

Depure a rede do Kubernetes de dentro para fora. Prove a conectividade IP do pod primeiro, depois os endpoints do Serviço, depois o DNS, depois a NetworkPolicy e, finalmente, o comportamento do Ingress ou balanceador de carga externo. Essa ordem impede que você corra atrás de um sintoma de Ingress quando o Serviço não tem endpoints prontos.