Como solucionar falhas de DNS no Amazon EKS?

10 minuto de leitura
0

As aplicações ou pods que usam o CoreDNS no meu cluster do Amazon Elastic Kubernetes Service (Amazon EKS) falham nas resoluções de nomes DNS internos ou externos.

Breve descrição

Os pods executados dentro de um cluster do Amazon EKS usam o endereço IP do cluster do CoreDNS como servidor de nomes para consultar registros DNS internos e externos. Se houver problemas com os pods, configuração do serviço ou conectividade do CoreDNS, as aplicações poderão falhar nas resoluções de DNS.

Um objeto de serviço chamado kube-dns abstrai os pods do CoreDNS. Para solucionar problemas com pods do CoreDNS, verifique o status de funcionamento de todos os componentes do serviço kube-dns, como opções de endpoint de serviço e regras de iptables.

Resolução

A resolução a seguir se aplica ao ClusterIP 10.100.0.10 do CoreDNS.

Conclua as seguintes etapas:

  1. Obtenha o ClusterIP do serviço CoreDNS:

    kubectl get service kube-dns -n kube-system
  2. Verifique se os endpoints de DNS estão expostos e se apontam para os pods do CoreDNS:

    kubectl -n kube-system get endpoints kube-dns

    Exemplo de saída:

    NAME       ENDPOINTS                                                        AGE
    kube-dns   192.168.2.218:53,192.168.3.117:53,192.168.2.218:53 + 1 more...   90d

    Observação: se a lista de endpoints estiver vazia, verifique o status dos pods do CoreDNS.

  3. Verifique se há um grupo de segurança ou uma lista de controle de acesso à rede (ACL da rede) bloqueando os pods quando eles se comunicam com o CoreDNS.

    Para obter mais informações, consulte Por que meus pods não se conectam a outros pods no Amazon EKS?

Verifique se o pod do kube-proxy está funcionando

Para verificar se o pod do kube-proxy consegue acessar os servidores de API do seu cluster, verifique se há erros de tempo limite em seus logs do ambiente de gerenciamento. Além disso, verifique se há ocorrências do erro 403 unauthorized.

Obtenha os logs do kube-proxy:

kubectl logs -n kube-system --selector 'k8s-app=kube-proxy'

Observação: o kube-proxy obtém os endpoints a partir do ambiente de gerenciamento e cria as regras do iptables em cada nó.

Verifique a utilização da CPU dos pods do CoreDNS no momento do problema

O complemento CoreDNS do Amazon EKS adiciona apenas o limite de 170 Mi à memória do pod do CoreDNS. O pod do CoreDNS não define um limite para a CPU, portanto, o contêiner pode usar todos os recursos de CPU disponíveis no nó em que é executado. Se a utilização da CPU do nó atingir 100%, você poderá receber erros de tempo limite de DNS nos logs da sua aplicação do Amazon EKS. Isso ocorre porque o pod do CoreDNS não tem recursos de CPU suficientes para lidar com todas as consultas de DNS.

Conecte-se ao pod da aplicação para solucionar o problema de DNS

Conclua as seguintes etapas:

  1. Para executar comandos dentro dos pods da aplicação, execute o comando a seguir para acessar um shell dentro do pod em execução:

    $ kubectl exec -it your-pod-name -- sh

    Se o pod da aplicação não tiver um binário de shell disponível, você receberá um erro semelhante ao exemplo a seguir:

    "OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown command terminated with exit code 126

    Para depurá-lo, substitua a imagem usada em seu arquivo manifesto por outra imagem, como a imagem busybox do site do Docker.

  2. Verifique se o endereço IP do cluster do serviço kube-dns está no arquivo /etc/resolv.conf do pod. Execute o seguinte comando no shell que está dentro do pod:

    cat /etc/resolv.conf

    O exemplo de arquivo resolv.conf a seguir mostra um pod configurado para apontar as solicitações de DNS para 10.100.0.10. O endereço IP deve corresponder ao ClusterIP do serviço kube‑dns:

    nameserver 10.100.0.10
    search default.svc.cluster.local svc.cluster.local cluster.local ec2.internal
    options ndots:5

    Observação: é possível gerenciar a configuração de DNS do pod com o campo dnsPolicy na especificação do pod. Se você não preencher esse campo, a política de DNS ClusterFirst será usada por padrão. Para obter mais informações sobre a política de DNS ClusterFirst, consulte Pod's DNS policy no site do Kubernetes.

  3. Para verificar se o pod consegue usar o ClusterIP padrão para resolver um domínio interno, execute o comando a seguir no shell que está dentro do pod:

    nslookup kubernetes.default 10.100.0.10

    Exemplo de saída:

    Server:     10.100.0.10
    Address:    10.100.0.10#53
    Name:       kubernetes.default.svc.cluster.local
    Address:    10.100.0.1
  4. Para verificar se o pod consegue usar o ClusterIP padrão para resolver um domínio externo, execute o comando a seguir no shell que está dentro do pod:

    nslookup amazon.com 10.100.0.10

    Exemplo de saída:

    Server:     10.100.0.10
    Address:    10.100.0.10#53
    Non-authoritative answer:
    Name:   amazon.com
    Address: 176.32.98.166
    Name:    amazon.com
    Address: 205.251.242.103
    Name:    amazon.com
    Address: 176.32.103.205
  5. Verifique se o seu pod pode usar o endereço IP do pod do CoreDNS para resolver diretamente. Execute os seguintes comandos no shell que está dentro do pod:

    nslookup kubernetes COREDNS_POD_IP
    
    nslookup amazon.com COREDNS_POD_IP

    Observação: substitua o COREDNS_POD_IP por um dos endereços IP do endpoint do get endpoints do kubectl.

Obtenha logs detalhados dos pods do CoreDNS para depurar

Conclua as seguintes etapas:

  1. Ative o log de depuração dos pods do CoreDNS e, em seguida, adicione o plug‑in log ao ConfigMap do CoreDNS:

    kubectl -n kube-system edit configmap coredns

    Observação: para obter mais informações, consulte plug-in log no site do CoreDNS.

  2. Na tela do editor que aparece na saída, adicione a string de log:

    kind: ConfigMap
    apiVersion: v1
    data:
      Corefile: |
        .:53 {
            log    # Enabling CoreDNS Logging
            errors
            health
            kubernetes cluster.local in-addr.arpa ip6.arpa {
              pods insecure
              upstream
              fallthrough in-addr.arpa ip6.arpa
            }
            ...
    ...

    Observação: demora alguns minutos para recarregar a configuração do CoreDNS. Para aplicar as alterações imediatamente, reinicie os pods um por um.

  3. Verifique se os logs do CoreDNS falham ou se recebem ocorrências do pod da aplicação:

    kubectl logs --follow -n kube-system --selector 'k8s-app=kube-dns'

Atualize o valor de ndots

O valor de ndots é o número de pontos que deve aparecer em um nome de domínio para resolução de uma consulta antes que uma consulta absoluta inicial seja feita.

Por exemplo, você define a opção ndots como o valor padrão 5 em um nome de domínio que não é totalmente qualificado. Assim, todos os domínios externos que não se enquadram no domínio interno cluster.local são anexados a domínios de pesquisa antes da consulta.

O exemplo a seguir tem a configuração do arquivo /etc/resolv.conf do pod da aplicação:

nameserver 10.100.0.10
search default.svc.cluster.local svc.cluster.local cluster.local ec2.internal
options ndots:5

O CoreDNS procura cinco pontos no domínio consultado. Se o pod fizer uma chamada de resolução de DNS para amazon.com, os logs serão parecidos com o exemplo a seguir:

[INFO] 192.168.3.71:33238 - 36534 "A IN amazon.com.default.svc.cluster.local. udp 54 false 512" NXDOMAIN qr,aa,rd 147 0.000473434s
[INFO] 192.168.3.71:57098 - 43241 "A IN amazon.com.svc.cluster.local. udp 46 false 512" NXDOMAIN qr,aa,rd 139 0.000066171s
[INFO] 192.168.3.71:51937 - 15588 "A IN amazon.com.cluster.local. udp 42 false 512" NXDOMAIN qr,aa,rd 135 0.000137489s
[INFO] 192.168.3.71:52618 - 14916 "A IN amazon.com.ec2.internal. udp 41 false 512" NXDOMAIN qr,rd,ra 41 0.001248388s
[INFO] 192.168.3.71:51298 - 65181 "A IN amazon.com. udp 28 false 512" NOERROR qr,rd,ra 106 0.001711104s

Observação: NXDOMAIN significa que o registro do domínio não foi encontrado e NOERROR significa que ele foi encontrado.

Cada domínio de pesquisa é precedido por amazon.com antes de fazer a chamada final no domínio absoluto que está ao final. Um nome de domínio final acrescido de um ponto (.) no final é um nome de domínio totalmente qualificado. Portanto, para cada consulta de nome de domínio externo, pode haver de quatro a cinco chamadas adicionais que podem sobrecarregar o pod do CoreDNS.

Para resolver esse problema, altere ndots para 1 para buscar por apenas um ponto. Ou acrescente um ponto (.) no final do domínio sendo consultado ou usado:

nslookup example.com.

Leve em consideração o limite do resolvedor da VPC (AmazonProvidedDNS)

O resolvedor da Amazon Virtual Private Cloud (Amazon VPC) aceita um limite rígido máximo de 1024 pacotes por segundo por interface de rede. Se mais de um pod do CoreDNS estiver no mesmo nó, as chances de atingir o limite serão maiores nas consultas de domínio externo.

Para usar as regras do PodAntiAffinity para programar os pods do CoreDNS em instâncias separadas, adicione as opções a seguir à implantação do CoreDNS:

podAntiAffinity:
  preferredDuringSchedulingIgnoredDuringExecution:
  - podAffinityTerm:
      labelSelector:
        matchExpressions:
        - key: k8s-app
          operator: In
          values:
          - kube-dns
      topologyKey: kubernetes.io/hostname
    weight: 100

Observação: para obter mais informações sobre o PodAntiAffinity, consulte Inter-pod affinity and anti-affinity no site do Kubernetes.

Use o tcpdump para capturar pacotes do CoreDNS a partir dos nós de processamento do Amazon EKS

Como auxílio para diagnosticar problemas de resolução de DNS, use a ferramenta tcpdump para realizar uma captura de pacotes:

  1. Localize um nó de processamento onde um pod do CoreDNS esteja em execução:

    kubectl get pod -n kube-system -l k8s-app=kube-dns -o wide
  2. Use o SSH para se conectar ao nó de processamento onde um nó do CoreDNS está em execução e, em seguida, instale a ferramenta tcpdump:

    sudo yum install tcpdump –y
  3. Localize o ID do processo do pod do CoreDNS no nó de processamento:

    ps ax | grep coredns
  4. A partir do nó de processamento, realize uma captura de pacotes na rede do pod do CoreDNS para monitorar o tráfego de rede na porta UDP 53:

    sudo nsenter -n -t PID tcpdump udp port 53
  5. Em um terminal separado, obtenha os endereços IP dos pods e do serviço CoreDNS:

    kubectl describe svc kube-dns -n kube-system

    Observação: o endereço IP do serviço está localizado no campo IP e os endereços IP dos pods estão localizados no campo Endpoints.

  6. Inicie um pod para testar o serviço DNS. O exemplo a seguir usa uma imagem de contêiner do Ubuntu:

    kubectl run ubuntu --image=ubuntu sleep 1d
    
    kubectl exec -it ubuntu sh
  7. Use a ferramenta nslookup para realizar uma consulta ao DNS com um domínio, como amazon.com:

    nslookup amazon.com

    Execute a mesma consulta explicitamente com o endereço IP do serviço CoreDNS:

    nslookup amazon.com COREDNS_SERVICE_IP

    Realize a consulta novamente com cada endereço IP dos pods do CoreDNS:

    nslookup amazon.com COREDNS\_POD\_IP

    Observação: em caso de execução de vários pods do CoreDNS, realize várias consultas para que ao menos uma delas seja enviada ao pod do qual você está capturando o tráfego.

  8. Examine os resultados da captura de pacotes.

    Se o pod do CoreDNS monitorado apresentar tempos limite de consulta de DNS e você não vir a consulta na captura de pacotes, verifique sua conectividade de rede. Verifique a acessibilidade da rede entre os nós de processamento.

    Se você vir um tempo limite de consulta de DNS ao utilizar o endereço IP de um pod cujo tráfego você não está capturando, execute outra captura de pacotes no nó de processamento relacionado a esse pod.

    Para salvar os resultados de uma captura de pacote, adicione o sinalizador -w FILE_NAME ao comando tcpdump. O exemplo a seguir grava os resultados em um arquivo chamado capture.pcap:

    tcpdump -w capture.pcap udp port 53

Informações relacionadas

CoreDNS GA for Kubernetes cluster DNS

no site do Kubernetes

AWS OFICIAL
AWS OFICIALAtualizada há 8 meses