Auf dieser Seite wird beschrieben, wie Sie Probleme mit kube-dns in der Google Kubernetes Engine (GKE) beheben.
Quelle von DNS-Problemen in kube-dns ermitteln
Fehler wie dial tcp: i/o timeout
, no such
host
oder Could not resolve host
deuten oft auf Probleme bei der Abfrageauflösung durch kube-dns hin.
Wenn einer dieser Fehler angezeigt wird, Sie aber nicht wissen, was die Ursache ist, finden Sie in den folgenden Abschnitten weitere Informationen. Die folgenden Abschnitte sind so angeordnet, dass mit den Schritten begonnen wird, die Ihnen am ehesten weiterhelfen. Probieren Sie daher jeden Abschnitt der Reihe nach aus.
Prüfen, ob kube-dns-Pods ausgeführt werden
Kube-dns-Pods sind entscheidend für die Namensauflösung innerhalb des Clusters. Wenn sie nicht ausgeführt werden, treten wahrscheinlich Probleme mit der DNS-Auflösung auf.
Prüfen Sie den Status dieser Pods, um sicherzustellen, dass die kube-dns-Pods ohne Neustarts ausgeführt werden:
kubectl get pods -l k8s-app=kube-dns -n kube-system
Die Ausgabe sieht in etwa so aus:
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 dieser Ausgabe stehen POD_ID_1
und POD_ID_2
für eindeutige IDs, die den kube-dns-Pods automatisch angehängt werden.
Wenn in der Ausgabe angezeigt wird, dass einer Ihrer kube-dns-Pods keinen Status von Running
hat, führen Sie die folgenden Schritte aus:
Anhand der Audit-Logs für Administratoraktivitäten können Sie prüfen, ob es in letzter Zeit Änderungen gab, z. B. Upgrades der Cluster- oder Knotenpoolversion oder Änderungen an der ConfigMap „kube-dns“. Weitere Informationen zu Audit-Logs finden Sie unter Informationen zum GKE-Audit-Logging. Wenn Sie Änderungen feststellen, heben Sie sie auf und prüfen Sie den Status der Pods noch einmal.
Wenn Sie keine relevanten Änderungen in letzter Zeit feststellen, prüfen Sie, ob auf dem Knoten, auf dem der kube-dns-Pod ausgeführt wird, ein OOM-Fehler auftritt. Wenn Sie in Ihren Cloud Logging-Logmeldungen einen Fehler ähnlich dem folgenden sehen, tritt bei diesen Pods ein OOM-Fehler auf:
Warning: OOMKilling Memory cgroup out of memory
Informationen zum Beheben dieses Fehlers finden Sie unter Fehlermeldung: „Warning: OOMKilling Memory cgroup out of memory“.
Wenn Sie keine OOM-Fehlermeldungen finden, starten Sie das kube-dns-Deployment neu:
kubectl rollout restart deployment/kube-dns --namespace=kube-system
Prüfen Sie nach dem Neustart des Deployments, ob Ihre kube-dns-Pods ausgeführt werden.
Wenn diese Schritte nicht funktionieren oder alle Ihre kube-dns-Pods den Status Running
haben, Sie aber weiterhin DNS-Probleme haben, prüfen Sie, ob die /etc/resolv.conf
-Datei richtig konfiguriert ist.
Prüfen, ob /etc/resolv.conf
richtig konfiguriert ist
Prüfen Sie die Datei /etc/resolv.conf
der Pods, bei denen DNS-Probleme auftreten, und achten Sie darauf, dass die darin enthaltenen Einträge korrekt sind:
Rufen Sie die Datei
/etc/resolv.conf
des Pods auf:kubectl exec -it POD_NAME -- cat /etc/resolv.conf
Ersetzen Sie POD_NAME durch den Namen des Pods, bei dem DNS-Probleme auftreten. Wenn bei mehreren Pods Probleme auftreten, wiederholen Sie die Schritte in diesem Abschnitt für jeden Pod.
Wenn die Pod-Binärdatei den Befehl
kubectl exec
nicht unterstützt, schlägt dieser Befehl möglicherweise fehl. In diesem Fall erstellen Sie einen einfachen Pod als Testumgebung. So können Sie einen Test-Pod im selben Namespace wie den problematischen Pod ausführen.Prüfen Sie, ob die Nameserver-IP-Adresse in der Datei
/etc/resolv.conf
korrekt ist:- Pods, die ein Hostnetzwerk verwenden, sollten die Werte in der
/etc/resolv.conf
-Datei des Knotens verwenden. Die IP-Adresse des Nameservers sollte169.254.169.254
sein. Bei Pods, die kein Hostnetzwerk verwenden, sollte die IP-Adresse des kube-dns-Dienstes mit der IP-Adresse des Nameservers übereinstimmen. So vergleichen Sie die IP-Adressen:
Rufen Sie die IP-Adresse des Dienstes „kube-dns“ ab:
kubectl get svc kube-dns -n kube-system
Die Ausgabe sieht in etwa so aus:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 192.0.2.10 <none> 53/UDP,53/TCP 64d
Notieren Sie sich den Wert in der Spalte „Cluster-IP“. In diesem Beispiel ist das
192.0.2.10
.Vergleichen Sie die IP-Adresse des Dienstes „kube-dns“ mit der IP-Adresse aus der Datei
/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 diesem Beispiel stimmen die beiden Werte überein. Die Ursache des Problems ist also nicht eine falsche Nameserver-IP-Adresse.
Wenn die IP-Adressen jedoch nicht übereinstimmen, bedeutet das, dass im Manifest des Anwendungs-Pods ein Feld vom Typ
dnsConfig
konfiguriert ist.Wenn der Wert im Feld
dnsConfig.nameservers
korrekt ist, prüfen Sie Ihren DNS-Server und achten Sie darauf, dass er ordnungsgemäß funktioniert.Wenn Sie den benutzerdefinierten Nameserver nicht verwenden möchten, entfernen Sie das Feld und führen Sie einen schrittweisen Neustart des Pods aus:
kubectl rollout restart deployment POD_NAME
Ersetzen Sie
POD_NAME
durch den Namen Ihres Clusters.
- Pods, die ein Hostnetzwerk verwenden, sollten die Werte in der
Prüfen Sie die Einträge
search
undndots
in/etc/resolv.conf
. Achten Sie darauf, dass keine Rechtschreibfehler vorhanden sind, dass veraltete Konfigurationen nicht verwendet werden und dass die fehlgeschlagene Anfrage auf einen vorhandenen Dienst im richtigen Namespace verweist.
DNS-Suche ausführen
Nachdem Sie bestätigt haben, dass /etc/resolv.conf
richtig konfiguriert ist und der DNS-Eintrag korrekt ist, führen Sie mit dem Befehlszeilentool „dig“ DNS-Suchanfragen vom Pod aus, für den DNS-Fehler gemeldet werden:
Sie können einen Pod direkt abfragen, indem Sie eine Shell darin öffnen:
kubectl exec -it POD_NAME -n NAMESPACE_NAME -- SHELL_NAME
Ersetzen Sie Folgendes:
POD_NAME
: der Name des Pods, für den DNS-Fehler gemeldet werden.NAMESPACE_NAME
: der Namespace, zu dem der Pod gehört.SHELL_NAME
: Der Name der Shell, die Sie öffnen möchten. Beispiel:sh
oder/bin/bash
Dieser Befehl schlägt möglicherweise fehl, wenn der Befehl
kubectl exec
in Ihrem Pod nicht zulässig ist oder der Pod die Binärdatei „dig“ nicht hat. Erstellen Sie in diesem Fall einen Test-Pod mit einem Image, in dem dig installiert ist:kubectl run "test-$RANDOM" ti --restart=Never --image=thockin/dnsutils - bash
Prüfen Sie, ob der Pod den internen DNS-Dienst des Clusters korrekt auflösen kann:
dig kubernetes
Da die Datei
/etc/resolv.conf
auf die IP-Adresse des kube-dns-Dienstes verweist, ist der DNS-Server beim Ausführen dieses Befehls der kube-dns-Dienst.Sie sollten eine erfolgreiche DNS-Antwort mit der IP-Adresse des Kubernetes API-Dienstes sehen (häufig
10.96.0.1
). WennSERVFAIL
oder keine Antwort angezeigt wird, kann der kube-dns-Pod die internen Dienstnamen in der Regel nicht auflösen.Prüfen Sie, ob der kube-dns-Dienst einen externen Domainnamen auflösen kann:
dig example.com
Wenn Sie Probleme damit haben, dass ein bestimmter kube-dns-Pod auf DNS-Anfragen antwortet, prüfen Sie, ob dieser Pod einen externen Domainnamen auflösen kann:
dig example.com @KUBE_DNS_POD_IP
Ersetzen Sie
KUBE_DNS_POD_IP
durch die IP-Adresse des kube-dns-Pods. Wenn Sie den Wert dieser IP-Adresse nicht kennen, führen Sie den folgenden Befehl aus:kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
Die IP-Adresse befindet sich in der Spalte
IP
.Wenn die Auflösung des Befehls erfolgreich war, sehen Sie
status: NOERROR
und Details zum A-Eintrag, wie im folgenden Beispiel gezeigt:; <<>> 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
Beenden Sie die Shell:
exit
Wenn einer dieser Befehle fehlschlägt, führen Sie einen schrittweisen Neustart des kube-dns-Deployments aus:
kubectl rollout restart deployment/kube-dns --namespace=kube-system
Führen Sie nach dem Neustart die „dig“-Befehle noch einmal aus und prüfen Sie, ob sie jetzt erfolgreich ausgeführt werden. Wenn sie immer noch fehlschlagen, fahren Sie mit dem Erfassen von Paketen fort.
Pakete erfassen
Führen Sie eine Paketerfassung durch, um zu prüfen, ob die DNS-Abfragen von den kube-dns-Pods empfangen und richtig beantwortet werden:
Stellen Sie mit SSH eine Verbindung zum Knoten her, auf dem der kube-dns-Pod ausgeführt wird. Beispiel:
Rufen Sie in der Google Cloud Console die Seite VM-Instanzen auf.
Suchen Sie den Knoten, mit dem Sie eine Verbindung herstellen möchten. Wenn Sie den Namen des Knotens in Ihrem kube-dns-Pod nicht kennen, führen Sie den folgenden Befehl aus:
kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
Der Name des Knotens wird in der Spalte Knoten aufgeführt.
Klicken Sie in der Spalte Verbinden auf SSH.
Starten Sie im Terminal Toolbox, ein vorinstalliertes Tool zur Fehlerbehebung:
toolbox
Installieren Sie das Paket
tcpdump
an der Root-Eingabeaufforderung:apt update -y && apt install -y tcpdump
Erstellen Sie mit
tcpdump
eine Paketerfassung Ihres DNS-Traffics:tcpdump -i eth0 port 53" -w FILE_LOCATION
Ersetzen Sie
FILE_LOCATION
durch einen Pfad, unter dem Sie die Aufnahme speichern möchten.Sehen Sie sich die Paketerfassung an. Prüfen Sie, ob es Pakete mit Ziel-IP-Adressen gibt, die mit der IP-Adresse des kube-dns-Dienstes übereinstimmen. So wird sichergestellt, dass die DNS-Anfragen das richtige Ziel für die Auflösung erreichen. Wenn DNS-Traffic nicht an den richtigen Pods ankommt, kann das auf eine Netzwerkrichtlinie hinweisen, die die Anfragen blockiert.
Auf Netzwerkrichtlinien prüfen
Restriktive Netzwerkrichtlinien können den DNS-Traffic manchmal beeinträchtigen. Führen Sie den folgenden Befehl aus, um zu prüfen, ob eine Netzwerkrichtlinie im Namespace „kube-system“ vorhanden ist:
kubectl get networkpolicy -n kube-system
Wenn Sie eine Netzwerkrichtlinie finden, prüfen Sie, ob sie die erforderliche DNS-Kommunikation zulässt. Wenn Sie beispielsweise eine Netzwerkrichtlinie haben, die den gesamten ausgehenden Traffic blockiert, werden auch DNS-Anfragen blockiert.
Wenn die Ausgabe No resources found in kube-system namespace
ist, haben Sie keine Netzwerkrichtlinien und können diese als Ursache des Problems ausschließen. Wenn Sie Protokolle untersuchen, können Sie weitere Fehlerquellen finden.
Logging vorübergehender DNS-Abfragen aktivieren
Wenn Sie Probleme wie falsche DNS-Antworten ermitteln möchten, aktivieren Sie vorübergehend das Debug-Logging von DNS-Abfragen.
Da dies ein ressourcenintensives Verfahren ist, empfehlen wir, diese Protokollierung zu deaktivieren, nachdem Sie eine geeignete Stichprobe von Protokollen erfasst haben.
Den kube-dns-Pod untersuchen
Informationen dazu, wie kube-dns-Pods DNS-Anfragen mit Cloud Logging empfangen und lösen
So rufen Sie Logeinträge für den kube-dns-Pod auf:
Rufen Sie in der Google Cloud Console die Seite Log-Explorer auf.
Geben Sie im Abfragebereich den folgenden Filter ein, um Ereignisse im Zusammenhang mit dem kube-dns-Container aufzurufen:
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"
Ersetzen Sie Folgendes:
CLUSTER_NAME
: Der Name des Clusters, zu dem der kube-dns-Pod gehört.CLUSTER_LOCATION
: Der Standort Ihres Clusters.
Klicken Sie auf Abfrage ausführen.
Sehen Sie sich die Ausgabe an. Die folgende Beispielausgabe zeigt einen möglichen Fehler:
{ "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 diesem Beispiel konnte kube-dns
example.com
nicht in angemessener Zeit auflösen. Dieser Fehler kann durch mehrere Probleme verursacht werden. Möglicherweise ist der Upstream-Server beispielsweise in der kube-dns-ConfigMap falsch konfiguriert oder es gibt einen hohen Netzwerkverkehr.
Wenn Cloud Logging nicht aktiviert ist, rufen Sie stattdessen die Kubernetes-Logs auf:
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
Kürzlich vorgenommene Änderungen an der kube-dns-ConfigMap untersuchen
Wenn in Ihrem Cluster plötzlich DNS-Auflösungsfehler auftreten, kann das eine falsche Konfigurationsänderung an der kube-dns-ConfigMap sein. Insbesondere Konfigurationsänderungen an den Definitionen für Stub-Domains und vorgelagerte Server können zu Problemen führen.
So prüfen Sie, ob es Updates für die Einstellungen der Stubdomain gibt:
Rufen Sie in der Google Cloud Console die Seite Log-Explorer auf.
Geben Sie im Bereich „Abfrage“ die folgende Abfrage ein:
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"
Klicken Sie auf Abfrage ausführen.
Sehen Sie sich die Ausgabe an. Wenn es Updates gab, sieht die Ausgabe in etwa so aus:
Updated stubDomains to map[example.com: [8.8.8.8 8.8.4.4 1.1.3.3 1.0.8.111]]
Wenn Sie eine Aktualisierung sehen, maximieren Sie das Ergebnis, um mehr über die Änderungen zu erfahren. Prüfen Sie, ob alle Stub-Domains und die zugehörigen vorgelagerten DNS-Server korrekt definiert sind. Falsche Einträge hier können zu Auflösungsfehlern für diese Domains führen.
So prüfen Sie, ob Änderungen am Upstream-Server vorgenommen wurden:
Rufen Sie in der Google Cloud Console die Seite Log-Explorer auf.
Geben Sie im Bereich „Abfrage“ die folgende Abfrage ein:
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"
Klicken Sie auf Abfrage ausführen.
Sehen Sie sich die Ausgabe an. Wenn es Änderungen gegeben hat, sieht die Ausgabe in etwa so aus:
Updated upstreamNameservers to [8.8.8.8]
Maximieren Sie das Ergebnis, um weitere Informationen zu den Änderungen zu erhalten. Prüfen Sie, ob die Liste der Upstream-DNS-Server korrekt ist und ob diese Server über Ihren Cluster erreichbar sind. Wenn diese Server nicht verfügbar oder falsch konfiguriert sind, schlägt die allgemeine DNS-Auflösung möglicherweise fehl.
Wenn Sie nach Änderungen an den Stub-Domains und Upstream-Servern gesucht, aber keine Ergebnisse gefunden haben, prüfen Sie mit dem folgenden Filter, ob Änderungen vorliegen:
resource.type="k8s_cluster"
protoPayload.resourceName:"namespaces/kube-system/configmaps/kube-dns"
protoPayload.methodName=~"io.k8s.core.v1.configmaps."
Prüfen Sie die aufgeführten Änderungen, um festzustellen, ob sie den Fehler verursacht haben.
Cloud Customer Care kontaktieren
Wenn Sie die vorherigen Abschnitte durchgearbeitet haben, die Ursache des Problems aber immer noch nicht gefunden haben, wenden Sie sich an den Cloud-Kundenservice.
Häufige Probleme beheben
Wenn ein bestimmter Fehler oder ein bestimmtes Problem auftritt, folgen Sie der Anleitung in den folgenden Abschnitten.
Problem: Intermittierende DNS-Zeitüberschreitungen
Wenn Sie zeitweise Zeitüberschreitungen bei der DNS-Auflösung feststellen, die bei einem Anstieg des DNS-Traffics oder zu Beginn der Geschäftszeiten auftreten, können Sie die DNS-Leistung mit den folgenden Lösungen optimieren:
Prüfen Sie die Anzahl der kube-dns-Pods, die im Cluster ausgeführt werden, und vergleichen Sie sie mit der Gesamtzahl der GKE-Knoten. Wenn nicht genügend Ressourcen vorhanden sind, sollten Sie die kube-dns-Pods skalieren.
Aktivieren Sie NodeLocal DNSCache, um die durchschnittliche DNS-Lookup-Zeit zu verbessern.
Die DNS-Auflösung in externe Namen kann den kube-dns-Pod überlasten. Wenn Sie die Anzahl der Abfragen reduzieren möchten, passen Sie die Einstellung
ndots
in der Datei/etc/resolv.conf
an.ndots
steht für die Anzahl der Punkte, die in einem Domainnamen enthalten sein müssen, um eine Abfrage vor der ursprünglichen absoluten Abfrage aufzulösen.Im folgenden Beispiel sehen Sie die
/etc/resolv.conf
-Datei eines Anwendungs-Pods: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 diesem Beispiel sucht kube-dns nach fünf Punkten in der abgefragten Domain. Wenn der Pod einen DNS-Auflösungsaufruf für
example.com
ausführt, sehen Ihre Protokolle in etwa so aus:"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
Ändern Sie dazu entweder den Wert von „nddots“ in
1
, um nur nach einem einzelnen Punkt zu suchen, oder fügen Sie am Ende der Domain, die Sie abfragen oder verwenden, einen Punkt (.
) an. Beispiel:dig example.com.
Problem: DNS-Abfragen von einigen Knoten schlagen gelegentlich fehl
Wenn DNS-Abfragen von einigen Knoten zeitweise fehlschlagen, können die folgenden Symptome auftreten:
- Wenn Sie Dig-Befehle an die IP-Adresse des kube-dns-Dienstes oder die Pod-IP-Adresse ausführen, schlagen die DNS-Abfragen zeitweise mit Zeitüberschreitungen fehl.
- Das Ausführen von dig-Befehlen aus einem Pod auf demselben Knoten wie der kube-dns-Pod schlägt fehl.
So beheben Sie das Problem:
- Führen Sie einen Konnektivitätstest durch. Legen Sie den problematischen Pod oder Knoten als Quelle und die IP-Adresse des kube-dns-Pods als Ziel fest. So können Sie prüfen, ob die erforderlichen Firewallregeln vorhanden sind, um diesen Traffic zuzulassen.
Wenn der Test nicht erfolgreich ist und der Traffic durch eine Firewallregel blockiert wird, listen Sie in Cloud Logging alle manuellen Änderungen an den Firewallregeln auf. Suchen Sie nach Änderungen, die eine bestimmte Art von Traffic blockieren:
Rufen Sie in der Google Cloud Console die Seite Log-Explorer auf.
Geben Sie im Bereich „Abfrage“ die folgende Abfrage ein:
logName="projects/project-name/logs/cloudaudit.googleapis.com/activity" resource.type="gce_firewall_rule"
Klicken Sie auf Abfrage ausführen. Anhand der Ausgabe der Abfrage können Sie feststellen, ob Änderungen vorgenommen wurden. Falls Fehler auftreten, beheben Sie sie und wenden Sie die Firewallregel noch einmal an.
Nehmen Sie keine Änderungen an automatisierten Firewallregeln vor.
Wenn die Firewallregeln nicht geändert wurden, prüfen Sie die Knotenpoolversion und achten Sie darauf, dass sie mit der Steuerungsebene und anderen funktionierenden Knotenpools kompatibel ist. Wenn einer der Knotenpools eines Clusters mehr als zwei Nebenversionen älter als die Steuerungsebene ist, kann dies zu Problemen führen. Weitere Informationen zu dieser Inkompatibilität finden Sie unter Knotenversion ist nicht mit Version der Steuerungsebene kompatibel.
Um festzustellen, ob die Anfragen an die richtige kube-dns-Dienst-IP-Adresse gesendet werden, erfassen Sie den Netzwerkverkehr auf dem problematischen Knoten und filtern Sie nach Port 53 (DNS-Traffic). Erfassen Sie den Traffic in den kube-dns-Pods selbst, um zu sehen, ob die Anfragen die gewünschten Pods erreichen und ob sie erfolgreich aufgelöst werden.
Nächste Schritte
- Allgemeine Informationen zur Diagnose von Kubernetes DNS-Problemen finden Sie unter Debugging bei der DNS-Auflösung.
- Wenn Sie weitere Unterstützung benötigen, wenden Sie sich an den Cloud Customer Care.