Wenn Sie Anwendungen in Standardclustern ausführen, ist kube-dns der Standard-DNS-Anbieter, mit dem Sie Service Discovery und Kommunikation ermöglichen können. In diesem Dokument wird beschrieben, wie Sie DNS mit kube-dns verwalten, einschließlich der Architektur, Konfiguration und Best Practices für die Optimierung der DNS-Auflösung in Ihrer GKE-Umgebung.
Dieses Dokument richtet sich an Entwickler, Administratoren und Architekten, die für die Verwaltung von DNS in GKE verantwortlich sind. Weitere Informationen zu gängigen Rollen und Aufgaben in Google Cloudfinden Sie unter Häufig verwendete GKE-Nutzerrollen und -Aufgaben.
Machen Sie sich vor Beginn mit Kubernetes-Diensten und allgemeinen DNS-Konzepten vertraut.
kube-dns-Architektur verstehen
kube-dns wird in Ihrem GKE-Cluster ausgeführt, um die DNS-Auflösung zwischen Pods und Diensten zu ermöglichen.
Das folgende Diagramm zeigt, wie Ihre Pods mit dem kube-dns-Dienst interagieren:
Schlüsselkomponenten
kube-dns umfasst die folgenden Hauptkomponenten:
kube-dnsPods:In diesen Pods wird diekube-dns-Serversoftware ausgeführt. Mehrere Replikate dieser Pods werden im Namespacekube-systemausgeführt und bieten Hochverfügbarkeit und Redundanz.kube-dns-Dienst:In der folgenden Tabelle werden die Skalierbarkeits- und Konfigurationslimits der Legacy- und CoreDNS-basierten Versionen vonkube-dnsverglichen:Funktion Legacy (kube-dns 1.35 und früher) kube-dns auf CoreDNS (1.36 und höher) Endpunkt-Awareness Bis zu 1.000 Endpunkte pro Dienst. Wenn ein Dienst mehr als 1.000 Pods hat, kennt kube-dns die zusätzlichen Endpunkte nicht. Alle Endpunkte sind bekannt. In dieser Version werden EndpointSlices verwendet, um die Richtigkeit zu gewährleisten und die Effizienz für große Dienste zu verbessern. Vorgelagerte Nameserver Auf 3 beschränkt Unterstützt bis zu 15 Geräte Gleichzeitige ausgehende TCP-Verbindungen Auf 200 begrenzt Unterstützt bis zu 1.500 kube-dns-autoscaler:Dieser Pod passt die Anzahl derkube-dns-Replikate basierend auf der Größe des Clusters an, einschließlich der Anzahl der Knoten und CPU-Kerne. So kannkube-dnsunterschiedliche DNS-Anfragelasten bewältigen.
Interne DNS-Auflösung
Wenn ein Pod einen DNS-Namen innerhalb der Clusterdomain auflösen muss, z. B. myservice.my-namespace.svc.cluster.local, läuft der folgende Prozess ab:
- Pod-DNS-Konfiguration:Die
kubeletauf jedem Knoten konfiguriert die/etc/resolv.conf-Datei des Pods. In dieser Datei wirdClusterIPdeskube-dns-Dienstes als Nameserver verwendet. - DNS-Abfrage: Der Pod sendet eine DNS-Abfrage an den
kube-dns-Dienst. Namensauflösung:
- GKE-Version 1.36 oder höher: Die CoreDNS-basierte Implementierung verwendet EndpointSlices, damit
kube-dnsalle Pods in einem Dienst kennt. Dadurch werden die Richtigkeit und Effizienz für umfangreiche Dienste verbessert. - GKE-Version 1.35 oder früher:
kube-dnslöst Namen basierend auf der älteren Cloud Endpoints API auf, die auf 1.000 Endpunkte beschränkt ist. Wenn ein Dienst mehr als 1.000 unterstützende Pods hat, kenntkube-dnsdie zusätzlichen Endpunkte nicht.
- GKE-Version 1.36 oder höher: Die CoreDNS-basierte Implementierung verwendet EndpointSlices, damit
Kommunikation:Der Pod verwendet dann die aufgelöste IP-Adresse, um mit dem Zieldienst zu kommunizieren.
Externe DNS-Auflösung
Wenn ein Pod einen externen DNS-Namen oder einen Namen außerhalb der Clusterdomain auflösen muss, fungiert kube-dns als rekursiver Resolver. Die Anfrage wird an Upstream-DNS-Server weitergeleitet, die in der Datei ConfigMap konfiguriert sind. Sie können auch benutzerdefinierte Resolver für bestimmte Domains konfigurieren, die auch als Stub-Domains bezeichnet werden. Diese Konfiguration weist kube-dns an, Anfragen für diese Domains an bestimmte vorgelagerte DNS-Server weiterzuleiten.
Pod-DNS konfigurieren
In GKE konfiguriert der kubelet-Agent auf jedem Knoten die DNS-Einstellungen für die Pods, die auf diesem Knoten ausgeführt werden.
/etc/resolv.conf-Datei konfigurieren
Wenn GKE einen Pod erstellt, ändert der kubelet-Agent die /etc/resolv.conf-Datei des Pods. In dieser Datei wird der DNS-Server für die Namensauflösung konfiguriert und es werden Suchdomains angegeben. Standardmäßig konfiguriert kubelet den Pod so, dass der interne DNS-Dienst des Clusters, kube-dns, als Nameserver verwendet wird. Außerdem werden Suchdomains in die Datei eingefügt. Mit diesen Suchdomains können Sie in DNS-Abfragen nicht qualifizierte Namen verwenden. Wenn ein Pod beispielsweise myservice abfragt, versucht Kubernetes zuerst, myservice.default.svc.cluster.local aufzulösen, dann myservice.svc.cluster.local und dann andere Domains aus der Liste search.
Das folgende Beispiel zeigt eine Standardkonfiguration für /etc/resolv.conf:
nameserver 10.0.0.10
search default.svc.cluster.local svc.cluster.local cluster.local c.my-project-id.internal google.internal
options ndots:5
Diese Datei enthält die folgenden Einträge:
nameserver: Definiert dieClusterIPdeskube-dns-Dienstes.search: Definiert die Suchdomains, die bei DNS-Lookups an nicht qualifizierte Namen angehängt werden.options ndots:5: Legt den Schwellenwert fest, ab dem GKE einen Namen als voll qualifiziert betrachtet. Ein Name gilt als vollständig qualifiziert, wenn er fünf oder mehr Punkte enthält.
Pods, die mit hostNetwork: true konfiguriert sind, übernehmen ihre DNS-Konfiguration vom Host und fragen kube-dns nicht direkt ab, es sei denn, sie verwenden ClusterFirstWithHostNet dnsPolicy.
kube-dns anpassen
kube-dns bietet eine robuste Standard-DNS-Auflösung. Sie können das Verhalten an bestimmte Anforderungen anpassen, z. B. die Effizienz der Auflösung verbessern oder bevorzugte DNS-Resolver verwenden. Sowohl Stub-Domains als auch Upstream-Nameserver werden konfiguriert, indem die ConfigMap kube-dns im Namespace kube-system geändert wird.
ConfigMap kube-dns ändern
So ändern Sie die ConfigMap kube-dns:
Öffnen Sie die ConfigMap zum Bearbeiten:
kubectl edit configmap kube-dns -n kube-systemFügen Sie im Abschnitt
datadie FelderstubDomainsundupstreamNameserversso hinzu:apiVersion: v1 kind: ConfigMap metadata: labels: addonmanager.kubernetes.io/mode: EnsureExists name: kube-dns namespace: kube-system data: stubDomains: | { "example.com": [ "8.8.8.8", "8.8.4.4" ], "internal": [ # Required if your upstream nameservers can't resolve GKE internal domains "169.254.169.254" # IP of the metadata server ] } upstreamNameservers: | [ "8.8.8.8", # Google Public DNS "8.8.4.4" # Google Public DNS Backup ]Speichern Sie die ConfigMap.
kube-dnslädt die Konfiguration automatisch neu.
Stub-Domains
Mit Stub-Domains können Sie benutzerdefinierte DNS-Resolver für bestimmte Domains definieren. Wenn ein Pod einen Namen in dieser Stub-Domain abfragt, leitet kube-dns die Anfrage an den angegebenen Resolver weiter, anstatt den Standardauflösungsmechanismus zu verwenden.
Sie fügen einen stubDomains-Abschnitt in die kube-dns ConfigMap ein.
In diesem Abschnitt werden die Domain und die entsprechenden vorgelagerten Nameserver angegeben.
kube-dns leitet dann Anfragen für Namen innerhalb dieser Domain an die angegebenen Server weiter. Sie können beispielsweise alle DNS-Abfragen für internal.mycompany.com an 192.168.0.10 weiterleiten, indem Sie "internal.mycompany.com": ["192.168.0.10"] zu stubDomains hinzufügen.
Wenn Sie einen benutzerdefinierten Resolver für eine Stub-Domain festlegen, z. B. example.com, leitet kube-dns alle Anfragen zur Namensauflösung für diese Domain, einschließlich Subdomains wie *.example.com, an die angegebenen Server weiter.
Vorgelagerte Nameserver
Sie können kube-dns so konfigurieren, dass benutzerdefinierte vorgelagerte Nameserver zum Auflösen externer Domainnamen verwendet werden. Mit dieser Konfiguration wird kube-dns angewiesen, alle DNS-Anfragen mit Ausnahme der Anfragen für die interne Domain des Clusters (*.cluster.local) an die angegebenen Upstream-Server weiterzuleiten. Interne Domains wie metadata.internal und *.google.internal können möglicherweise nicht von Ihren benutzerdefinierten vorgelagerten Servern aufgelöst werden. Wenn Sie die Workload Identity-Föderation für GKE aktivieren oder Arbeitslasten haben, die von diesen Domains abhängen, fügen Sie eine Stubs-Domain für internal in ConfigMap hinzu. Verwenden Sie 169.254.169.254, die IP-Adresse des Metadatenservers, als Resolver für diese Stub-Domain.
Benutzerdefiniertes kube-dns-Deployment verwalten
In einem Standardcluster wird kube-dns als Deployment ausgeführt. Ein benutzerdefiniertes kube-dns-Deployment bedeutet, dass Sie als Clusteradministrator das Deployment steuern und an Ihre Anforderungen anpassen können, anstatt das von GKE bereitgestellte Standard-Deployment zu verwenden.
Gründe für ein benutzerdefiniertes Deployment
Eine benutzerdefinierte kube-dns-Bereitstellung kann aus folgenden Gründen sinnvoll sein:
- Ressourcenzuweisung: Feinabstimmung von CPU- und Arbeitsspeicherressourcen für
kube-dns-Pods, um die Leistung in Clustern mit hohem DNS-Traffic zu optimieren. - Image-Version:Verwenden Sie eine bestimmte Version des
kube-dns-Images oder wechseln Sie zu einem alternativen DNS-Anbieter wie CoreDNS. - Erweiterte Konfiguration:Hier können Sie Protokollierungsstufen, Sicherheitsrichtlinien und das DNS-Caching-Verhalten anpassen.
Autoscaling für benutzerdefinierte Deployments
Die integrierte kube-dns-autoscaler funktioniert mit dem Standard-kube-dns-Deployment.
Wenn Sie eine benutzerdefinierte kube-dns-Bereitstellung erstellen, wird sie nicht vom integrierten Autoscaler verwaltet. Daher müssen Sie ein separates Autoscaling einrichten, das speziell für die Überwachung und Anpassung der Replikatanzahl Ihres benutzerdefinierten Deployments konfiguriert ist.
Bei diesem Ansatz erstellen und stellen Sie Ihre eigene Autoscaling-Konfiguration in Ihrem Cluster bereit.
Wenn Sie ein benutzerdefiniertes Deployment verwalten, sind Sie für alle seine Komponenten verantwortlich, z. B. dafür, dass das Autoscaler-Image auf dem neuesten Stand ist. Die Verwendung veralteter Komponenten kann zu Leistungseinbußen oder DNS-Fehlern führen.
Eine ausführliche Anleitung zum Konfigurieren und Verwalten Ihres eigenen kube-dns-Deployments finden Sie unter Benutzerdefiniertes kube-dns-Deployment einrichten.
Fehlerbehebung
Informationen zur Fehlerbehebung bei kube-dns finden Sie auf den folgenden Seiten:
- Informationen zur Fehlerbehebung bei
kube-dnsin GKE finden Sie unter Fehlerbehebung beikube-dnsin GKE. - Allgemeine Informationen zur Diagnose von Kubernetes DNS-Problemen finden Sie unter Debugging bei der DNS-Auflösung.
DNS-Auflösung optimieren
In diesem Abschnitt werden häufige Probleme und Best Practices für die Verwaltung von DNS in GKE beschrieben.
Limit für die dnsConfig Suchdomains eines Pods
In Kubernetes ist die Anzahl der DNS-Suchdomains auf 32 begrenzt. Wenn Sie versuchen, mehr als 32 Suchdomains in der dnsConfig eines Pods zu definieren, erstellt die kube-apiserver den Pod nicht und gibt einen Fehler ähnlich dem folgenden aus:
The Pod "dns-example" is invalid: spec.dnsConfig.searches: Invalid value: []string{"ns1.svc.cluster-domain.example", "my.dns.search.suffix1", "ns2.svc.cluster-domain.example", "my.dns.search.suffix2", "ns3.svc.cluster-domain.example", "my.dns.search.suffix3", "ns4.svc.cluster-domain.example", "my.dns.search.suffix4", "ns5.svc.cluster-domain.example", "my.dns.search.suffix5", "ns6.svc.cluster-domain.example", "my.dns.search.suffix6", "ns7.svc.cluster-domain.example", "my.dns.search.suffix7", "ns8.svc.cluster-domain.example", "my.dns.search.suffix8", "ns9.svc.cluster-domain.example", "my.dns.search.suffix9", "ns10.svc.cluster-domain.example", "my.dns.search.suffix10", "ns11.svc.cluster-domain.example", "my.dns.search.suffix11", "ns12.svc.cluster-domain.example", "my.dns.search.suffix12", "ns13.svc.cluster-domain.example", "my.dns.search.suffix13", "ns14.svc.cluster-domain.example", "my.dns.search.suffix14", "ns15.svc.cluster-domain.example", "my.dns.search.suffix15", "ns16.svc.cluster-domain.example", "my.dns.search.suffix16", "my.dns.search.suffix17"}: must not have more than 32 search paths.
Der kube-apiserver gibt diese Fehlermeldung als Reaktion auf einen Versuch zurück, einen Pod zu erstellen. Entfernen Sie die zusätzlichen Suchpfade aus der Konfiguration, um dieses Problem zu beheben.
Upstream-nameservers-Limit für kube-dns
In älteren Versionen von kube-dns (Version 1.35 und früher) ist die Anzahl der upstreamNameservers auf drei begrenzt. Wenn Sie mehr als drei definieren, wird in Cloud Logging ein Fehler wie der folgende angezeigt:
Invalid configuration: upstreamNameserver cannot have more than three entries (value was &TypeMeta{Kind:,APIVersion:,}), ignoring update
In diesem Fall ignoriert kube-dns die upstreamNameservers-Konfiguration und verwendet weiterhin die vorherige gültige Konfiguration. Entfernen Sie die zusätzlichen upstreamNameservers aus der kube-dns ConfigMap, um dieses Problem zu beheben.
kube-dns vergrößern
In Standardclustern können Sie einen niedrigeren Wert für nodesPerReplica verwenden, damit beim Hochskalieren von Clustern mehr kube-dns-Pods erstellt werden. Wir empfehlen dringend, einen expliziten Wert für das Feld max festzulegen, damit die GKE-Steuerungsebene-VM nicht durch die große Anzahl von kube-dns-Pods überlastet wird, die die Kubernetes API beobachten.
Sie können den Wert des Felds max auf die Anzahl der Knoten im Cluster festlegen.
Wenn der Cluster mehr als 500 Knoten hat, legen Sie den Wert des Felds max auf 500 fest.
Sie können die Anzahl der kube-dns-Replikate ändern, indem Sie die ConfigMap kube-dns-autoscaler bearbeiten.
kubectl edit configmap kube-dns-autoscaler --namespace=kube-system
Die Ausgabe sieht etwa so aus:
linear: '{"coresPerReplica":256, "nodesPerReplica":16,"preventSinglePointFailure":true}'
Die Anzahl der kube-dns-Replikate wird mit der folgenden Formel berechnet:
replicas = max( ceil( cores * 1/coresPerReplica ) , ceil( nodes * 1/nodesPerReplica ) )
Um die Anzahl der Ergebnisse zu erhöhen, ändern Sie den Wert des Felds nodesPerReplica in einen kleineren Wert und geben Sie einen Wert für das Feld max an.
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
Bei dieser Konfiguration wird für jeweils acht Knoten im Cluster ein kube-dns-Pod erstellt. Ein Cluster mit 24 Knoten hat drei Replikate und ein Cluster mit 40 Knoten hat fünf Replikate. Wenn der Cluster über 120 Knoten hat, steigt die Anzahl der kube-dns-Replikate nicht über 15 (Wert des Felds max) an.
Legen Sie eine Mindestanzahl von Replikat für das Feld kube-dns fest, um eine grundlegende DNS-Verfügbarkeit in Ihrem Cluster zu gewährleisten.
Die Ausgabe für kube-dns-autoscaler ConfigMap mit dem konfigurierten Feld min sieht in etwa so aus:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
DNS-Lookup-Zeiten verbessern
Mehrere Faktoren können zu einer hohen Latenz bei DNS-Lookups oder DNS-Auflösungsfehlern mit dem Standardanbieter kube-dns führen. In Anwendungen können diese Probleme als getaddrinfo EAI_AGAIN-Fehler auftreten, die auf einen vorübergehenden Fehler bei der Namensauflösung hinweisen. Mögliche Ursachen:
- Häufige DNS-Lookups innerhalb Ihrer Arbeitslast.
- Hohe Pod-Dichte pro Knoten.
- Die Ausführung von
kube-dnsauf Spot-VMs oder VMs auf Abruf, was zu unerwarteten Knotenlöschungen führen kann. - Verbindungslimits:Bei Legacy-Versionen von
kube-dns(GKE-Version 1.35 und früher) sind maximal 200 gleichzeitige TCP-Verbindungen möglich.kube-dnsin CoreDNS (GKE-Version 1.36 und höher) entfernt diese festen Limits für eingehende Verbindungen und bietet eine deutlich höhere Kapazität für ausgehende Verbindungen.
So verbessern Sie die DNS-Lookup-Zeiten:
- Vermeiden Sie die Ausführung kritischer Systemkomponenten wie
kube-dnsauf Spot-VMs oder VMs auf Abruf. Erstellen Sie mindestens einen Knotenpool mit Standard-VMs, der keine Spot-VMs oder VMs auf Abruf enthält. Verwenden Sie Markierungen und Toleranzen, um dafür zu sorgen, dass kritische Arbeitslasten auf diesen zuverlässigen Knoten geplant werden. - NodeLocal DNSCache aktivieren. NodeLocal DNSCache speichert DNS-Antworten direkt auf jedem Knoten im Cache. Dadurch werden die Latenz und die Last für den
kube-dns-Dienst reduziert. Wenn Sie NodeLocal DNSCache aktivieren und Netzwerkrichtlinien mit Standardablehnungsregeln verwenden, fügen Sie eine Richtlinie hinzu, damit Arbeitslasten DNS-Abfragen an dienode-local-dns-Pods senden können. - Skalieren Sie
kube-dnshoch. - Achten Sie darauf, dass Ihre Anwendung
dns.resolve*-basierte Funktionen anstelle vondns.lookup-basierten Funktionen verwendet, dadns.lookupsynchron ist. - Verwenden Sie voll qualifizierte Domainnamen (FQDNs), z. B.
https://google.com./anstelle vonhttps://google.com/.
Bei GKE-Clusterupgrades können DNS-Auflösungsfehler auftreten, da gleichzeitig Upgrades von Komponenten der Steuerungsebene, einschließlich kube-dns, durchgeführt werden.
Diese Fehler betreffen in der Regel nur einen kleinen Prozentsatz der Knoten. Testen Sie Cluster-Upgrades gründlich in einer Nicht-Produktionsumgebung, bevor Sie sie auf Produktionscluster anwenden.
Sichtbarkeit von Diensten sicherstellen
kube-dns erstellt nur DNS-Einträge für Services, die Endpunkte haben. Wenn ein Service keine Endpunkte hat, erstellt kube-dns keine DNS-Einträge für diesen Service.
Abweichungen bei der DNS-Gültigkeitsdauer (TTL) verwalten
Wenn kube-dns eine DNS-Antwort von einem vorgelagerten DNS-Resolver mit einer großen oder unendlichen TTL empfängt, behält es diesen TTL-Wert bei. Dieses Verhalten kann zu einer Diskrepanz zwischen dem im Cache gespeicherten Eintrag und der tatsächlichen IP-Adresse führen.
GKE behebt dieses Problem in bestimmten Versionen der Steuerungsebene, z. B. 1.21.14-gke.9100 und höher oder 1.22.15-gke.2100 und höher. In diesen Versionen wird ein maximaler TTL-Wert von 30 Sekunden für jede DNS-Antwort mit einer höheren TTL festgelegt. Dieses Verhalten ähnelt NodeLocal DNSCache.
kube-dns-Messwerte ansehen
Sie können Messwerte zu DNS-Abfragen direkt aus den kube-dns-Pods abrufen.
Wie Sie diese Messwerte abrufen, hängt von Ihrer GKE-Version ab.
GKE-Version 1.36 und höher
Wenn auf Ihrem Cluster GKE-Version 1.36 oder höher ausgeführt wird (kube-dns auf CoreDNS), können Sie die DNS-Leistung mit vordefinierten Dashboards in Cloud Monitoring überwachen oder Messwerte manuell aus den Pods abrufen.
Messwerte in der Google Cloud Console ansehen
- Rufen Sie in der Google Cloud Console die Seite Dashboards auf.
- Wählen Sie das Dashboard GKE DNS Observability – Cluster View aus.
Alternativ können Sie diese Messwerte direkt in der Google Cloud Console abfragen. Rufen Sie dazu Monitoring > Metrics Explorer auf und suchen Sie nach den entsprechenden Messwertnamen.
Messwerte manuell abrufen
So rufen Sie Messwerte manuell aus dem Pod ab:
Suchen Sie die
kube-dns-Pods.kubectl get pods -n kube-system --selector=k8s-app=kube-dnsLeiten Sie Port 9153 an einen der Pods weiter.
kubectl port-forward pod/POD_NAME -n kube-system 9153:9153Ersetzen Sie
POD_NAMEdurch den Namen eines derkube-dns-Pods aus der vorherigen Ausgabe.Rufen Sie die Messwerte auf.
curl http://127.0.0.1:9153/metrics
GKE-Version 1.35 und früher
Diese Version von kube-dns verwendet Pods mit mehreren Containern. So rufen Sie Messwerte ab:
Suchen Sie die
kube-dns-Pods im Namespacekube-system.kubectl get pods -n kube-system --selector=k8s-app=kube-dnsLeiten Sie die Ports 10055 (für den
kube-dns-Container) und 10054 (für dendnsmasq-Container) weiter:#For the kube-dns container kubectl port-forward pod/POD_NAME -n kube-system 10055:10055 #For the dnsmasq container kubectl port-forward pod/POD_NAME -n kube-system 10054:10054Ersetzen Sie
POD_NAMEdurch den Namen eines derkube-dns-Pods aus der vorherigen Ausgabe. Führen Sie diese Portweiterleitungsbefehle in separaten Terminalsitzungen aus.Auf die Messwerte zugreifen
#Metrics from the kube-dns container curl http://127.0.0.1:10055/metrics #Metrics from the dnsmasq container curl http://127.0.0.1:10054/metrics
Nächste Schritte
- Übersicht über Cluster-DNS in GKE
- Eine Übersicht zur Verwendung von DNS in Kubernetes-Clustern finden Sie unter DNS für Dienste und Pods.
- Informationen zum Einrichten von NodeLocal DNSCache
- Benutzerdefiniertes kube-dns-Deployment einrichten