Questa pagina mostra come risolvere i problemi relativi a kube-dns in Google Kubernetes Engine (GKE).
Identificare l'origine dei problemi DNS in kube-dns
Errori come dial tcp: i/o timeout
, no such
host
o Could not resolve host
spesso indicano problemi con la capacità di kube-dns di risolvere le query.
Se hai riscontrato uno di questi errori, ma non ne conosci la causa, utilizza le sezioni seguenti per aiutarti a individuarla. Le sezioni seguenti sono organizzate in modo da iniziare con i passaggi che hanno maggiori probabilità di aiutarti, quindi prova ogni sezione in ordine.
Verifica che i pod kube-dns siano in esecuzione
I pod kube-dns sono fondamentali per la risoluzione dei nomi all'interno del cluster. Se non sono in esecuzione, è probabile che si verifichino problemi con la risoluzione DNS.
Per verificare che i pod kube-dns siano in esecuzione senza riavvii recenti, visualizza lo stato di questi pod:
kubectl get pods -l k8s-app=kube-dns -n kube-system
L'output è simile al seguente:
NAME READY STATUS RESTARTS AGE
kube-dns-POD_ID_1 5/5 Running 0 16d
kube-dns-POD_ID_2 0/5 Terminating 0 16d
In questo output, POD_ID_1
e POD_ID_2
rappresentano identificatori univoci che vengono aggiunti automaticamente ai pod kube-dns.
Se l'output mostra che nessuno dei tuoi pod kube-dns ha lo stato
Running
, segui questi passaggi:
Utilizza i log di controllo dell'attività di amministrazione per verificare se sono state apportate modifiche recenti, ad esempio upgrade della versione del cluster o del pool di nodi oppure modifiche a kube-dns ConfigMap. Per saperne di più sui log di controllo, vedi Informazioni sui log di controllo di GKE. Se trovi modifiche, ripristinale e visualizza di nuovo lo stato dei pod.
Se non trovi modifiche recenti pertinenti, verifica se si verifica un errore di esaurimento della memoria sul nodo su cui viene eseguito il pod kube-dns. Se nei messaggi di log di Cloud Logging visualizzi un errore simile al seguente, significa che questi pod stanno riscontrando un errore OOM:
Warning: OOMKilling Memory cgroup out of memory
Questo messaggio indica che Kubernetes ha terminato un processo a causa dell'eccessivo consumo di risorse. Kubernetes pianifica i pod in base alle richieste di risorse, ma consente ai pod di consumare fino ai limiti delle risorse. Se i limiti sono superiori alle richieste o non sono presenti limiti, l'utilizzo delle risorse del pod può superare le risorse del sistema.
Per risolvere questo errore, puoi eliminare i workload problematici o impostare limiti di memoria o CPU. Per scoprire di più sull'impostazione dei limiti, consulta la sezione Gestione delle risorse per pod e container nella documentazione di Kubernetes. Per saperne di più sugli eventi OOM, vedi Risolvere i problemi relativi agli eventi OOM.
Se non trovi messaggi di errore OOM, riavvia il deployment di kube-dns:
kubectl rollout restart deployment/kube-dns --namespace=kube-system
Dopo aver riavviato il deployment, controlla se i pod kube-dns sono in esecuzione.
Se questi passaggi non funzionano o tutti i tuoi pod kube-dns hanno lo stato
Running
, ma riscontri ancora problemi DNS, verifica che il file /etc/resolv.conf
sia configurato correttamente.
Verifica che /etc/resolv.conf
sia configurato correttamente
Esamina il file /etc/resolv.conf
dei pod che presentano problemi DNS e assicurati che le voci che contiene siano corrette:
Visualizza il file
/etc/resolv.conf
del pod:kubectl exec -it POD_NAME -- cat /etc/resolv.conf
Sostituisci POD_NAME con il nome del pod che presenta problemi di DNS. Se ci sono più pod che presentano problemi, ripeti i passaggi di questa sezione per ogni pod.
Se il binario del pod non supporta il comando
kubectl exec
, questo comando potrebbe non riuscire. In questo caso, crea un pod semplice da utilizzare come ambiente di test. Questa procedura consente di eseguire un pod di test nello stesso spazio dei nomi del pod problematico.Verifica che l'indirizzo IP del server dei nomi nel file
/etc/resolv.conf
sia corretto:- I pod che utilizzano una rete host devono utilizzare i valori nel file
/etc/resolv.conf
del nodo. L'indirizzo IP del server dei nomi deve essere169.254.169.254
. Per i pod che non utilizzano una rete host, l'indirizzo IP del servizio kube-dns deve corrispondere all'indirizzo IP del server dei nomi. Per confrontare gli indirizzi IP, completa i seguenti passaggi:
Ottieni l'indirizzo IP del servizio kube-dns:
kubectl get svc kube-dns -n kube-system
L'output è simile al seguente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 192.0.2.10 <none> 53/UDP,53/TCP 64d
Prendi nota del valore nella colonna IP cluster. In questo esempio, è
192.0.2.10
.Confronta l'indirizzo IP del servizio kube-dns con l'indirizzo IP del file
/etc/resolv.conf
:# cat /etc/resolv.conf search default.svc.cluster.local svc.cluster.local cluster.local c.PROJECT_NAME google.internal nameserver 192.0.2.10 options ndots:5
In questo esempio, i due valori corrispondono, quindi un indirizzo IP del nameserver errato non è la causa del problema.
Tuttavia, se gli indirizzi IP non corrispondono, significa che un campo
dnsConfig
è configurato nel manifest del pod dell'applicazione.Se il valore nel campo
dnsConfig.nameservers
è corretto, esamina il server DNS e assicurati che funzioni correttamente.Se non vuoi utilizzare il server dei nomi personalizzato, rimuovi il campo ed esegui un riavvio graduale del pod:
kubectl rollout restart deployment POD_NAME
Sostituisci
POD_NAME
con il nome del tuo pod.
- I pod che utilizzano una rete host devono utilizzare i valori nel file
Verifica le voci
search
endots
in/etc/resolv.conf
. Assicurati che non ci siano errori ortografici, configurazioni obsolete e che la richiesta non riuscita faccia riferimento a un servizio esistente nello spazio dei nomi corretto.
Esegui una ricerca DNS
Dopo aver verificato che /etc/resolv.conf
sia configurato correttamente e che il
record DNS sia corretto, utilizza lostrumento a riga di comandoo dig per eseguire ricerche
DNS dal pod che segnala errori DNS:
Esegui una query direttamente su un pod aprendo una shell al suo interno:
kubectl exec -it POD_NAME -n NAMESPACE_NAME -- SHELL_NAME
Sostituisci quanto segue:
POD_NAME
: il nome del pod che segnala errori DNS.NAMESPACE_NAME
: lo spazio dei nomi a cui appartiene il pod.SHELL_NAME
: il nome della shell che vuoi aprire. Ad esempio,sh
o/bin/bash
.
Questo comando potrebbe non riuscire se il pod non consente il comando
kubectl exec
o se il pod non dispone del binario dig. In questo caso, crea un pod di test con un'immagine in cui è installato dig:kubectl run "test-$RANDOM" ti --restart=Never --image=thockin/dnsutils - bash
Controlla se il pod è in grado di risolvere correttamente il servizio DNS interno del cluster:
dig kubernetes
Poiché il file
/etc/resolv.conf
punta all'indirizzo IP del servizio kube-dns, quando esegui questo comando, il server DNS è il servizio kube-dns.Dovresti visualizzare una risposta DNS riuscita con l'indirizzo IP del servizio API Kubernetes (spesso qualcosa come
10.96.0.1
). Se visualizziSERVFAIL
o nessuna risposta, di solito ciò indica che il pod kube-dns non è in grado di risolvere i nomi dei servizi interni.Verifica se il servizio kube-dns può risolvere un nome di dominio esterno:
dig example.com
Se riscontri difficoltà con un determinato pod kube-dns che risponde alle query DNS, verifica se il pod può risolvere un nome di dominio esterno:
dig example.com @KUBE_DNS_POD_IP
Sostituisci
KUBE_DNS_POD_IP
con l'indirizzo IP del pod kube-dns. Se non conosci il valore di questo indirizzo IP, esegui il seguente comando:kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
L'indirizzo IP si trova nella colonna
IP
.Se la risoluzione del comando ha esito positivo, vengono visualizzati
status: NOERROR
e i dettagli del record A, come mostrato nel seguente esempio:; <<>> DiG 9.16.27 <<>> example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31256 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 30 IN A 93.184.215.14 ;; Query time: 6 msec ;; SERVER: 10.76.0.10#53(10.76.0.10) ;; WHEN: Tue Oct 15 16:45:26 UTC 2024 ;; MSG SIZE rcvd: 56
Esci dalla shell:
exit
Se uno di questi comandi non va a buon fine, esegui un riavvio in sequenza del deployment kube-dns:
kubectl rollout restart deployment/kube-dns --namespace=kube-system
Dopo aver completato il riavvio, riprova i comandi dig e verifica se ora hanno esito positivo. Se i test continuano a non andare a buon fine, procedi con l'acquisizione di un pacchetto.
Acquisire un'acquisizione di pacchetti
Acquisisci un pacchetto per verificare se le query DNS vengono ricevute e risposte in modo appropriato dai pod kube-dns:
Utilizzando SSH, connettiti al nodo che esegue il pod kube-dns. Ad esempio:
Nella console Google Cloud , vai alla pagina Istanze VM.
Individua il nodo a cui vuoi connetterti. Se non conosci il nome del nodo sul pod kube-dns, esegui il seguente comando:
kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
Il nome del nodo è elencato nella colonna Nodo.
Nella colonna Connetti, fai clic su SSH.
Nel terminale, avvia toolbox, uno strumento di debug preinstallato:
toolbox
Al prompt root, installa il pacchetto
tcpdump
:apt update -y && apt install -y tcpdump
Utilizzando
tcpdump
, acquisisci un pacchetto del traffico DNS:tcpdump -i eth0 port 53" -w FILE_LOCATION
Sostituisci
FILE_LOCATION
con un percorso in cui vuoi salvare l'acquisizione.Esamina l'acquisizione dei pacchetti. Controlla se sono presenti pacchetti con indirizzi IP di destinazione che corrispondono all'indirizzo IP del servizio kube-dns. In questo modo, le richieste DNS raggiungono la destinazione corretta per la risoluzione. Se non vedi il traffico DNS arrivare sui pod corretti, potrebbe essere presente un criterio di rete che blocca le richieste.
Verificare la presenza di un criterio di rete
A volte, le norme di rete restrittive possono interrompere il traffico DNS. Per verificare se esiste una policy di rete nello spazio dei nomi kube-system, esegui questo comando:
kubectl get networkpolicy -n kube-system
Se trovi una policy di rete, esaminala e assicurati che consenta la comunicazione DNS necessaria. Ad esempio, se hai un criterio di rete che blocca tutto il traffico in uscita, il criterio bloccherebbe anche le richieste DNS.
Se l'output è No resources found in kube-system namespace
, non
hai norme di rete e puoi escludere questa causa del tuo
problema. L'analisi dei log può aiutarti a trovare altri punti di errore.
Abilitare il logging temporaneo delle query DNS
Per aiutarti a identificare problemi come risposte DNS errate, attiva temporaneamente la registrazione di debug delle query DNS. Per abilitare le query, crea un pod basato su un pod kube-dns esistente. Eventuali modifiche al deployment di kube-dns vengono annullate automaticamente.
L'attivazione della registrazione temporanea delle query DNS è una procedura che richiede molte risorse, pertanto ti consigliamo di eliminare il pod che crei non appena raccogli un campione di log adeguato.
Per abilitare la registrazione temporanea delle query DNS, completa i seguenti passaggi:
Recupera un pod kube-dns e memorizzalo nella variabile denominata
POD
:POD=$(kubectl -n kube-system get pods --selector=k8s-app=kube-dns -o jsonpath="{.items[0].metadata.name}")
Crea un pod denominato
kube-dns-debug
. Questo pod è una copia del pod archiviato nella variabilePOD
, ma con la registrazione dnsmasq abilitata. Questo comando non modifica il pod kube-dns originale:kubectl apply -f <(kubectl get pod -n kube-system ${POD} -o json | jq -e ' ( (.spec.containers[] | select(.name == "dnsmasq") | .args) += ["--log-queries"] ) | (.metadata.name = "kube-dns-debug") | (del(.metadata.labels."pod-template-hash")) ')
Esamina i log:
kubectl logs -f --tail 100 -c dnsmasq -n kube-system kube-dns-debug
Puoi anche visualizzare le query in Cloud Logging.
Dopo aver visualizzato i log delle query DNS, elimina il pod
kube-dns-debug
:kubectl -n kube-system delete pod kube-dns-debug
Esamina il pod kube-dns
Esamina in che modo i pod kube-dns ricevono e risolvono le query DNS con Cloud Logging.
Per visualizzare le voci di log relative al pod kube-dns, completa i seguenti passaggi:
Nella console Google Cloud , vai alla pagina Esplora log.
Nel riquadro della query, inserisci il seguente filtro per visualizzare gli eventi correlati al container kube-dns:
resource.type="k8s_container" resource.labels.namespace_name="kube-system" resource.labels.Pod_name:"kube-dns" resource.labels.cluster_name="CLUSTER_NAME" resource.labels.location="CLUSTER_LOCATION"
Sostituisci quanto segue:
CLUSTER_NAME
: il nome del cluster a cui appartiene il pod kube-dns.CLUSTER_LOCATION
: la posizione del cluster.
Fai clic su Esegui query.
Rivedi l'output. L'output di esempio seguente mostra un possibile errore che potresti visualizzare:
{ "timestamp": "2024-10-10T15:32:16.789Z", "severity": "ERROR", "resource": { "type": "k8s_container", "labels": { "namespace_name": "kube-system", "Pod_name": "kube-dns", "cluster_name": "CLUSTER_NAME", "location": "CLUSTER_LOCATION" } }, "message": "Failed to resolve 'example.com': Timeout." },
In questo esempio, kube-dns non è riuscito a risolvere
example.com
in un tempo ragionevole. Questo tipo di errore può essere causato da diversi problemi. Ad esempio, il server upstream potrebbe essere configurato in modo errato in kube-dns ConfigMap oppure potrebbe esserci un traffico di rete elevato.
Se Cloud Logging non è abilitato, visualizza i log di Kubernetes:
Pod=$(kubectl get Pods -n kube-system -l k8s-app=kube-dns -o name | head -n1)
kubectl logs -n kube-system $Pod -c dnsmasq
kubectl logs -n kube-system $Pod -c kubedns
kubectl logs -n kube-system $Pod -c sidecar
Esamina le modifiche recenti apportate a kube-dns ConfigMap
Se improvvisamente si verificano errori di risoluzione DNS nel cluster, una causa è una modifica di configurazione errata apportata a kube-dns ConfigMap. In particolare, le modifiche alla configurazione dei domini stub e delle definizioni dei server upstream possono causare problemi.
Per verificare la presenza di aggiornamenti alle impostazioni del dominio stub, completa i seguenti passaggi:
Nella console Google Cloud , vai alla pagina Esplora log.
Nel riquadro della query, inserisci la seguente query:
resource.labels.cluster_name="clouddns" resource.type="k8s_container" resource.labels.namespace_name="kube-system" labels.k8s-pod/k8s-app="kube-dns" jsonPayload.message=~"Updated stubDomains to"
Fai clic su Esegui query.
Rivedi l'output. Se sono stati eseguiti aggiornamenti, l'output è simile al seguente:
Updated stubDomains to map[example.com: [8.8.8.8 8.8.4.4 1.1.3.3 1.0.8.111]]
Se vedi un aggiornamento, espandi il risultato per scoprire di più sulle modifiche. Verifica che tutti i domini stub e i relativi server DNS upstream siano definiti correttamente. Le voci errate qui possono causare errori di risoluzione per questi domini.
Per verificare la presenza di modifiche al server upstream, completa i seguenti passaggi:
Nella console Google Cloud , vai alla pagina Esplora log.
Nel riquadro della query, inserisci la seguente query:
resource.labels.cluster_name="clouddns" resource.type="k8s_container" resource.labels.namespace_name="kube-system" labels.k8s-pod/k8s-app="kube-dns" jsonPayload.message=~"Updated upstreamNameservers to"
Fai clic su Esegui query.
Rivedi l'output. Se sono state apportate modifiche, l'output è simile al seguente:
Updated upstreamNameservers to [8.8.8.8]
Espandi il risultato per scoprire di più sulle modifiche. Verifica che l'elenco dei server DNS upstream sia accurato e che questi server siano raggiungibili dal tuo cluster. Se questi server non sono disponibili o sono configurati in modo errato, la risoluzione DNS generale potrebbe non riuscire.
Se hai verificato la presenza di modifiche ai domini stub e ai server upstream, ma non hai trovato risultati, controlla tutte le modifiche con il seguente filtro:
resource.type="k8s_cluster"
protoPayload.resourceName:"namespaces/kube-system/configmaps/kube-dns"
protoPayload.methodName=~"io.k8s.core.v1.configmaps."
Esamina le modifiche elencate per verificare se hanno causato l'errore.
Contattare l'assistenza clienti Google Cloud
Se hai seguito le sezioni precedenti, ma non riesci ancora a diagnosticare la causa del problema, contatta l'assistenza clienti Google Cloud.
Risolvere i problemi comuni
Se hai riscontrato un errore o un problema specifico, segui i consigli riportati nelle sezioni seguenti.
Problema: timeout DNS intermittenti
Se noti timeout intermittenti della risoluzione DNS che si verificano quando si verifica un aumento del traffico DNS o quando iniziano le ore lavorative, prova le seguenti soluzioni per ottimizzare il rendimento del DNS:
Controlla il numero di pod kube-dns in esecuzione sul cluster e confrontalo con il numero totale di nodi GKE. Se le risorse non sono sufficienti, valuta la possibilità di scalare orizzontalmente i pod kube-dns.
Per migliorare il tempo medio di ricerca DNS, abilita NodeLocal DNS Cache.
La risoluzione DNS per i nomi esterni può sovraccaricare il pod kube-dns. Per ridurre il numero di query, modifica l'impostazione
ndots
nel file/etc/resolv.conf
.ndots
rappresenta il numero di punti che devono essere presenti in un nome di dominio per risolvere una query prima della query assoluta iniziale.L'esempio seguente è il file
/etc/resolv.conf
di un pod dell'applicazione:search default.svc.cluster.local svc.cluster.local cluster.local c.PROJECT_ID.internal google.internal nameserver 10.52.16.10 options ndots:5
In questo esempio, kube-dns cerca cinque punti nel dominio interrogato. Se il pod effettua una chiamata di risoluzione DNS per
example.com
, i log sono simili al seguente esempio:"A IN example.com.default.svc.cluster.local." NXDOMAIN "A IN example.com.svc.cluster.local." NXDOMAIN "A IN example.com.cluster.local." NXDOMAIN "A IN example.com.google.internal." NXDOMAIN "A IN example.com.c.PROJECT_ID.internal." NXDOMAIN "A IN example.com." NOERROR
Per risolvere il problema, modifica il valore di ndots in
1
per cercare solo un singolo punto o aggiungi un punto (.
) alla fine del dominio che interroghi o utilizzi. Ad esempio:dig example.com.
Problema: le query DNS non riescono a intermittenza da alcuni nodi
Se noti che le query DNS non riescono in modo intermittente da alcuni nodi, potresti riscontrare i seguenti sintomi:
- Quando esegui i comandi dig sull'indirizzo IP del servizio kube-dns o sull'indirizzo IP del pod, le query DNS non riescono in modo intermittente con timeout.
- L'esecuzione di comandi dig da un pod sullo stesso nodo del pod kube-dns non va a buon fine.
Per risolvere il problema, completa i seguenti passaggi:
- Esegui un test di connettività. Imposta il pod o il nodo problematico come origine e la destinazione come indirizzo IP del pod kube-dns. In questo modo puoi verificare se sono presenti le regole firewall richieste per consentire questo traffico.
Se il test non va a buon fine e il traffico viene bloccato da una regola firewall, utilizza Cloud Logging per elencare le modifiche manuali apportate alle regole firewall. Cerca modifiche che bloccano un tipo specifico di traffico:
Nella console Google Cloud , vai alla pagina Esplora log.
Nel riquadro della query, inserisci la seguente query:
logName="projects/project-name/logs/cloudaudit.googleapis.com/activity" resource.type="gce_firewall_rule"
Fai clic su Esegui query. Utilizza l'output della query per determinare se sono state apportate modifiche. Se rilevi errori, correggili e riapplica la regola firewall.
Assicurati di non apportare modifiche alle regole firewall automatizzate.
Se non sono state apportate modifiche alle regole firewall, controlla la versione pool di nodi e assicurati che sia compatibile con il control plane e con gli altri node pool funzionanti. Se uno dei pool di nodi del cluster è precedente di più di due versioni secondarie rispetto al control plane, questo potrebbe causare problemi. Per maggiori informazioni su questa incompatibilità, consulta Versione del nodo non compatibile con la versione del control plane.
Per determinare se le richieste vengono inviate all'IP del servizio kube-dns corretto, acquisisci il traffico di rete sul nodo problematico e filtra per la porta 53 (traffico DNS). Acquisisci il traffico sui pod kube-dns stessi per vedere se le richieste raggiungono i pod previsti e se vengono risolte correttamente.
Passaggi successivi
Per informazioni generali sulla diagnosi dei problemi DNS di Kubernetes, consulta Debug della risoluzione DNS.
Se non riesci a trovare una soluzione al tuo problema nella documentazione, consulta la sezione Richiedere assistenza per ulteriore aiuto, inclusi consigli sui seguenti argomenti:
- Aprire una richiesta di assistenza contattando l'assistenza clienti cloud.
- Ricevere assistenza dalla community
ponendo domande su StackOverflow e utilizzando il tag
google-kubernetes-engine
per cercare problemi simili. Puoi anche unirti al canale Slack#kubernetes-engine
per ulteriore assistenza della community. - Apertura di bug o richieste di funzionalità utilizzando lo strumento di monitoraggio dei problemi pubblico.