Salta al contenuto

Come posso risolvere gli errori DNS di Amazon EKS?

10 minuti di lettura
0

Le applicazioni o i pod che utilizzano CoreDNS nel mio cluster Amazon Elastic Kubernetes Service (Amazon EKS) non riescono a risolvere i nomi DNS interni o esterni.

Breve descrizione

I pod che vengono eseguiti all'interno del cluster Amazon EKS utilizzano l'indirizzo IP del cluster CoreDNS come server dei nomi per eseguire query sui record DNS interni ed esterni. In caso di problemi con i pod CoreDNS, la configurazione del servizio o la connettività, le applicazioni potrebbero non riuscire nelle risoluzioni DNS.

L'oggetto servizio kube-dns astrae i pod CoreDNS. Per risolvere i problemi relativi ai pod CoreDNS, verifica lo stato di funzionamento di tutti i componenti del servizio kube-dns, come le opzioni degli endpoint del servizio e le regole iptables.

Risoluzione

Nota: nella risoluzione che segue, il valore CoreDNS ClusterIP è 10.100.0.10.

Per verificare la configurazione DNS, completa i seguenti passaggi:

  1. Per ottenere il valore ClusterIP del servizio CoreDNS, esegui questo comando:

    kubectl get service kube-dns -n kube-system
  2. Per verificare che gli endpoint DNS siano esposti e puntino verso i pod CoreDNS, esegui questo comando:

    kubectl -n kube-system get endpoints kube-dns

    Esempio di output:

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

    Nota: se l'elenco degli endpoint è vuoto, controlla lo stato dei pod CoreDNS.

  3. Verifica che i gruppi di sicurezza e la lista di controllo degli accessi alla rete (ACL) non blocchino i pod quando comunicano con CoreDNS.

Per ulteriori informazioni, consulta Perché i miei pod non si connettono ad altri pod in Amazon EKS?

Verifica che il pod kube-proxy funzioni

Per verificare se il pod kube-proxy ha accesso ai server API per il cluster, controlla nei log la presenza di eventuali errori di timeout relativi al piano di controllo (control-plane). Inoltre, controlla la presenza di errori 403 (Unauthorized).

Per ottenere i log di kube-proxy, esegui questo comando:

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

Nota: kube-proxy ottiene gli endpoint dal piano di controllo (control-plane) e crea le regole iptables su ogni nodo.

Controlla l'utilizzo della CPU del pod CoreDNS al momento del problema

Il componente aggiuntivo CoreDNS di Amazon EKS aggiunge solo la quota di 170 MiB alla memoria del pod CoreDNS. Il pod CoreDNS non definisce una quota per la CPU, quindi il container può utilizzare tutte le risorse CPU disponibili sul nodo in cui viene eseguito. Se l'utilizzo della CPU del nodo è del 100%, potresti riscontrare errori di timeout DNS nei log delle applicazioni Amazon EKS. Questo perché il pod CoreDNS non dispone di risorse CPU sufficienti per gestire tutte le query DNS.

Per verificare l'utilizzo attuale della CPU e della memoria dei pod CoreDNS, esegui questo comando:

kubectl top pods -n kube-system -l k8s-app=kube-dns

Per verificare l'utilizzo attuale della CPU e della memoria dei nodi del cluster Amazon EKS, esegui questo comando:

kubectl top nodes

Connettiti al pod dell'applicazione per risolvere il problema DNS

Completa i seguenti passaggi:

  1. Per eseguire comandi all'interno dei pod dell'applicazione, esegui questo comando:

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

    Nota: sostituisci your-pod-name con il nome del tuo pod.
    Il comando precedente consente di accedere a una shell all'interno del pod in esecuzione. Se il pod dell'applicazione non ha una shell binaria disponibile, ricevi un errore simile al seguente:
    "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"
    Per risolverlo, aggiorna l'immagine che utilizzi nel file manifesto pod-manifest.yaml con un'altra immagine. Un esempio di immagine è busybox sul sito web Docker.

  2. Per verificare che l'indirizzo IP del cluster del servizio kube-dns sia presente nel file /etc/resolv.conf del pod, esegui questo comando nella shell del pod:

    cat /etc/resolv.conf

    L'esempio di file resolv.conf che segue mostra un pod configurato per puntare verso 10.100.0.10 per le richieste DNS. L'indirizzo IP deve corrispondere al valore ClusterIP del servizio kube-dns:

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

    Nota: puoi gestire la configurazione DNS del pod con il campo dnsPolicy nelle specifiche del pod. Se non compili questo campo, per impostazione predefinita Amazon EKS utilizza la policy DNS ClusterFirst. Per ulteriori informazioni sulla policy DNS ClusterFirst, consulta Pod's DNS policy (Policy DNS del pod) sul sito web Kubernetes.

  3. Per verificare che il pod possa utilizzare il valore ClusterIP predefinito per risolvere un dominio interno, esegui questo comando nella shell del pod:

    nslookup kubernetes.default 10.100.0.10

    Esempio di output:

    Server:     10.100.0.10
    Address:    10.100.0.10#53
    Name:       kubernetes.default.svc.cluster.local
    Address:    10.100.0.1
  4. Per verificare che il pod possa utilizzare il valore ClusterIP predefinito per risolvere un dominio esterno, esegui questo comando nella shell del pod:

    nslookup amazon.com 10.100.0.10

    Esempio di output:

    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. Per ottenere gli endpoint kube-dns, esegui questo comando:

    kubectl get endpoints kube-dns -n kube-system
  6. Per verificare che il pod possa utilizzare l'indirizzo IP del pod CoreDNS per la risoluzione diretta, esegui questo comando nella shell del pod:

    nslookup kubernetes COREDNS_POD_IP
    nslookup amazon.com COREDNS_POD_IP

    Nota: sostituisci COREDNS_POD_IP con gli indirizzi IP degli endpoint kube-dns.

Ottieni log più dettagliati dai pod CoreDNS per risolvere ulteriori problemi

Completa i seguenti passaggi:

  1. Per attivare il log di risoluzione degli errori del pod CoreDNS e aggiungere il plugin dei log alla ConfigMap di CoreDNS, esegui questo comando:
    kubectl -n kube-system edit configmap coredns
    Nota: per ulteriori informazioni, consulta log sul sito web CoreDNS.
  2. Nella schermata dell'editor dell'output del comando, aggiungi la seguente stringa di log:
    kind: ConfigMap
    apiVersion: v1
    data:
      Corefile: |
        .:53 {
            log    # Activating CoreDNS Logging
            errors
            health
            kubernetes cluster.local in-addr.arpa ip6.arpa {
              pods insecure
              upstream
              fallthrough in-addr.arpa ip6.arpa
            }
            ...
    ...
    Nota: sono necessari alcuni minuti per ricaricare la configurazione di CoreDNS. Per applicare immediatamente le modifiche, riavvia i pod uno per uno.
  3. Per verificare se i log di CoreDNS hanno esito negativo o ricevono traffico dal pod dell'applicazione, esegui questo comando:
    kubectl logs --follow -n kube-system --selector 'k8s-app=kube-dns'

Aggiorna il valore ndots

Il valore ndots è il numero di punti che devono apparire in un nome per risolvere una query prima della query assoluta iniziale. Ad esempio, puoi impostare ndots sul valore predefinito 5 in un nome di dominio non completo. In questo scenario, tutti i domini esterni che non fanno parte del dominio interno cluster.local vengono aggiunti ai domini di ricerca prima di eseguire la query.

L'esempio di seguito ha l'impostazione del file /etc/resolv.conf del pod dell'applicazione:

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

Nell'esempio di configurazione precedente, CoreDNS cerca cinque punti nel dominio su cui è stata eseguita la query. Se il pod effettua una chiamata di risoluzione DNS per amazon.com, i log hanno un aspetto simile al seguente esempio:

[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

Nota: NXDOMAIN significa che il pod non ha trovato il record di dominio. NOERROR significa che il pod ha trovato correttamente il record di dominio.

Ogni dominio di ricerca ha il prefisso amazon.com prima di eseguire l'ultima chiamata al dominio assoluto alla fine. Un nome canonico a cui viene aggiunto un punto (.) alla fine è un nome di dominio completo. Per ogni query relativa a un nome di dominio esterno, potrebbero esserci quattro o cinque chiamate aggiuntive, con conseguente sovraccarico del pod CoreDNS.

Per risolvere il problema, modifica ndots in 1 per cercare un solo punto. In alternativa, aggiungi un punto alla fine del dominio su cui esegui query o che utilizzi. Esempio:

nslookup example.com.

Controlla le quote del risolutore VPC AmazonProvidedDNS

Il risolutore Amazon Virtual Private Cloud (Amazon VPC) può accettare una quota massima di 1.024 pacchetti al secondo per ogni interfaccia di rete elastica. Se più di un pod CoreDNS si trova sullo stesso nodo, potresti raggiungere questa quota per le query di domini esterni.

Per utilizzare le regole PodAntiAffinity per pianificare i pod CoreDNS su istanze separate, aggiungi le seguenti opzioni alla distribuzione di CoreDNS:

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

Nota: per ulteriori informazioni su PodAntiAffinity, consulta Inter-pod affinity and anti-affinity (Affinità e anti-affinità tra pod) sul sito web Kubernetes.

Utilizza tcpdump per acquisire pacchetti CoreDNS dai nodi worker di Amazon EKS

Per diagnosticare i problemi di risoluzione DNS, completa i seguenti passaggi per eseguire un'acquisizione di pacchetti utilizzando lo strumento tcpdump:

  1. Per individuare un nodo worker in cui è in esecuzione un pod CoreDNS, esegui questo comando:

    kubectl get pod -n kube-system -l k8s-app=kube-dns -o wide
  2. Per connetterti al nodo worker e installare lo strumento tcpdump utilizzando SSH, esegui questo comando:

    sudo yum install tcpdump - y
  3. Per individuare l'ID del processo del pod CoreDNS sul nodo worker, esegui questo comando:

    ps ax | grep coredns
  4. Dal nodo worker, esegui questo comando per acquisire pacchetti sul traffico di rete del pod CoreDNS sulla porta UDP 53:

    sudo nsenter -n -t PID tcpdump udp port 53
  5. Da un terminale separato, esegui questo comando per ottenere il servizio CoreDNS e l'indirizzo IP del pod:

    kubectl describe svc kube-dns -n kube-system

    Nota: annota l'indirizzo IP del servizio nel campo IP e l'indirizzo IP del pod nel campo Endpoint.

  6. Avvia un pod per verificare il servizio DNS. L'esempio seguente utilizza un'immagine del container Ubuntu:

    kubectl run ubuntu --image=ubuntu sleep 1d
    kubectl exec -it ubuntu sh
  7. Esegui questo comando per eseguire una query DNS sul dominio amazon.com utilizzando lo strumento nslookup:

    nslookup amazon.com

    Per eseguire esplicitamente la stessa query sull'indirizzo IP del servizio CoreDNS, esegui questo comando:

    nslookup amazon.com COREDNS_SERVICE_IP

    Nota: sostituisci COREDNS_SERVICE_IP con l'indirizzo IP del tuo servizio CoreDNS.
    Per eseguire la query su ogni indirizzo IP del pod CoreDNS, esegui questo comando:

    nslookup amazon.com COREDNS_POD_IP

    Nota: sostituisci COREDNS_POD_IP con l'indirizzo IP del tuo pod CoreDNS. Se utilizzi più pod CoreDNS, esegui più query. In questo modo, Amazon EKS invia almeno una query al pod da cui acquisisci il traffico.

  8. Esamina i risultati dell'acquisizione dei pacchetti.
    Se il pod CoreDNS presenta timeout delle query DNS e non vedi la query nell'acquisizione dei pacchetti, controlla la connettività di rete. Controlla la raggiungibilità della rete tra i nodi worker.
    Se vedi timeout delle query DNS sull'indirizzo IP di un pod che non hai acquisito, esegui un'altra acquisizione di pacchetti sul nodo worker correlato.
    Per salvare i risultati di un'acquisizione di pacchetti, aggiungi il flag -w FILE_NAME al comando tcpdump. L'esempio seguente scrive i risultati nel file capture.pcap:

    tcpdump -w capture.pcap udp port 53

Informazioni correlate

CoreDNS GA for Kubernetes cluster DNS (Disponibilità generale di CoreDNS GA per la risoluzione DNS dei cluster Kubernetes) sul sito web Kubernetes