Auf dieser Seite wird erläutert, wie Sie die DNS-Lookup-Latenz in einem GKE-Cluster (Google Kubernetes Engine) mithilfe von NodeLocal DNSCache verbessern.
Hinweis: Für GKE Autopilot-Cluster ist NodeLocal DNSCache standardmäßig aktiviert und kann nicht überschrieben werden.
Architektur
NodeLocal DNSCache ist ein GKE-Add-on, das Sie neben kube-dns ausführen können.
GKE implementiert NodeLocal DNSCache als DaemonSet, das auf jedem Knoten in Ihrem Cluster einen DNS-Cache ausführt.
Wenn ein Pod eine DNS-Anfrage stellt, wird die Anfrage an den DNS-Cache gesendet, der auf demselben Knoten wie der Pod ausgeführt wird. Wenn der Cache die DNS-Anfrage nicht auflösen kann, leitet er die Anfrage basierend auf dem Abfrageziel an einen der folgenden Orte weiter:
- kube-dns: Alle Abfragen für die Cluster-DNS-Domain (
cluster.local
) werden an kube-dns weitergeleitet. Die node-local-dns-Pods verwenden den kube-dns-upstream-Dienst, um auf kube-dns-Pods zuzugreifen. Im folgenden Diagramm lautet die IP-Adresse des kube-dns-Dienstes10.0.0.10:53
. - Benutzerdefinierte Stub-Domains oder Upstream-Nameserver: Abfragen werden direkt von NodeLocal DNSCache-Pods weitergeleitet.
- Cloud DNS: Alle anderen Abfragen werden an den lokalen Metadatenserver weitergeleitet, der auf demselben Knoten wie der Pod ausgeführt wird, von dem die Abfrage stammt. Der lokale Metadatenserver greift auf Cloud DNS zu.
Wenn Sie NodeLocal DNSCache in einem vorhandenen Cluster aktivieren, erstellt GKE alle Clusterknoten mit GKE-Version 1.15 und höher gemäß dem Knotenaktualisierungsprozess neu.
Nachdem GKE die Knoten neu erstellt hat, fügt GKE den Knoten automatisch das Label addon.gke.io/node-local-dns-ds-ready=true
hinzu. Sie dürfen dieses Label den Clusterknoten nicht manuell hinzufügen.
Vorteile von NodeLocal DNSCache
NodeLocal DNSCache bietet folgende Vorteile:
- Kürzere durchschnittliche DNS-Lookup-Zeit
- Verbindungen von Pods zu ihrem lokalen Cache erstellen keine Tabelleneinträge vom Typ conntrack. Dadurch werden unterbrochene und abgelehnte Verbindungen aufgrund von erschöpften conntrack-Tabellen und Race-Bedingungen verhindert.
- Sie können NodeLocal DNSCache mit Cloud DNS for GKE verwenden.
- DNS-Abfragen für externe URLs (URLs, die nicht auf Clusterressourcen verweisen) werden direkt an den lokalen Cloud DNS-Metadatenserver weitergeleitet, wobei kube-dns umgangen wird.
- Die lokalen DNS-Caches übernehmen automatisch Stub-Domains und Upstream-Nameserver, die in der kube-dns ConfigMap angegeben sind.
Anforderungen und Einschränkungen
- NodeLocal DNSCache verbraucht Rechenressourcen auf jedem Knoten Ihres Clusters.
- NodeLocal DNSCache wird mit Windows Server-Knotenpools nicht unterstützt.
- Für NodeLocal DNSCache ist eine GKE Version ab 1.15 erforderlich.
- NodeLocal DNSCache greift über TCP auf kube-dns-Pods zu.
- NodeLocal DNSCache greift über TCP und UDP auf GKE-Versionen 1.18 oder höher auf
upstreamServers
undstubDomains
zu. Der DNS-Server muss über TCP und UDP erreichbar sein. - DNS-Einträge werden für die folgenden Zeiträume im Cache gespeichert:
- Die Gültigkeitsdauer (TTL) des Eintrags oder 30 Sekunden, wenn die TTL mehr als 30 Sekunden beträgt.
- 5 Sekunden, wenn die DNS-Antwort
NXDOMAIN
lautet.
- NodeLocal DNSCache-Pods überwachen Port 53, 9253, 9353 und 8080 auf den Knoten. Wenn Sie einen anderen
hostNetwork
-Pod ausführen oder mit diesen Ports einhostPorts
konfigurieren, schlägt NodeLocal DNSCache fehl und DNS-Fehler treten auf. NodeLocal DNSCache-Pods verwenden nicht den ModushostNetwork
, wenn Sie GKE Dataplane V2 und Cloud DNS for GKE verwenden. - Der lokale DNS-Cache wird nur in Knotenpools mit GKE-Versionen ab 1.15 ausgeführt. Wenn Sie NodeLocal DNSCache in einem Cluster mit Knoten aktivieren, auf denen niedrigere Versionen laufen, verwenden Pods auf diesen Knoten kube-dns.
NodeLocal DNSCache aktivieren
Für Autopilot-Cluster ist NodeLocal DNSCache standardmäßig aktiviert und kann nicht überschrieben werden.
Bei Standardclustern können Sie NodeLocal DNSCache in neuen oder vorhandenen Clustern mithilfe der Google Cloud CLI aktivieren. Sie können NodeLocal DNSCache in neuen Clustern mit der Google Cloud Console aktivieren.
gcloud
NodeLocal DNSCache in einem neuen Cluster aktivieren
Verwenden Sie das Flag --addons
mit dem Argument NodeLocalDNS
, um NodeLocal DNSCache in einem neuen Cluster zu aktivieren:
gcloud container clusters create CLUSTER_NAME \
--location=COMPUTE_LOCATION \
--addons=NodeLocalDNS
Dabei gilt:
CLUSTER_NAME
: Der Name des neuen Clusters.COMPUTE_LOCATION
: Der Compute Engine-Standort für den Cluster.
NodeLocal DNSCache in einem vorhandenen Cluster aktivieren
Verwenden Sie das Flag --update-addons
mit dem Argument NodeLocalDNS=ENABLED
, um NodeLocal DNSCache in einem vorhandenen Cluster zu aktivieren:
gcloud container clusters update CLUSTER_NAME \
--update-addons=NodeLocalDNS=ENABLED
Dabei gilt:
CLUSTER_NAME
: Der Name Ihres Clusters.
Console
Führen Sie die folgenden Schritte aus, um NodeLocal DNSCache in einem neuen Cluster zu aktivieren:
Rufen Sie in der Google Cloud Console die Seite Google Kubernetes Engine auf.
Klicken Sie neben "Standard" auf Konfigurieren.
Konfigurieren Sie den Cluster wie gewünscht.
Klicken Sie im Navigationsbereich auf Netzwerk.
Klicken Sie im Bereich Erweiterte Netzwerkoptionen das Kästchen NodeLocal DNSCache aktivieren an.
Klicken Sie auf Erstellen.
Prüfen, ob NodeLocal DNSCache aktiviert ist
Rufen Sie eine Liste der node-local-dns
-Pods ab, um festzustellen, ob NodeLocal DNSCache ausgeführt wird:
kubectl get pods -n kube-system -o wide | grep node-local-dns
Die Ausgabe sieht etwa so aus:
node-local-dns-869mt 1/1 Running 0 6m24s 10.128.0.35 gke-test-pool-69efb6b8-5d7m <none> <none>
node-local-dns-htx4w 1/1 Running 0 6m24s 10.128.0.36 gke-test-pool-69efb6b8-wssk <none> <none>
node-local-dns-v5njk 1/1 Running 0 6m24s 10.128.0.33 gke-test-pool-69efb6b8-bhz3 <none> <none>
Die Ausgabe zeigt einen node-local-dns
-Pod für jeden Knoten, auf dem eine GKE-Version ab 1.15 ausgeführt wird.
NodeLocal DNSCache deaktivieren
Sie können NodeLocal DNSCache mit dem folgenden Befehl deaktivieren:
gcloud container clusters update CLUSTER_NAME \
--update-addons=NodeLocalDNS=DISABLED
Dabei gilt:
CLUSTER_NAME
: der Name des Clusters, der deaktiviert werden soll.
Probleme bei NodeLocal DNSCache beheben
Allgemeine Informationen zur Diagnose von Kubernetes DNS-Problemen finden Sie unter Debugging bei der DNS-Auflösung.
NodeLocal DNSCache ist nicht sofort aktiviert
Wenn Sie NodeLocal DNSCache in einem vorhandenen Cluster aktivieren, aktualisiert GKE die Knoten möglicherweise nicht sofort, wenn der Cluster ein konfiguriertes Wartungsfenster oder einen Ausschluss hat. Weitere Informationen finden Sie unter Hinweise: Neuerstellung und Wartungsfenster von Knoten.
Wenn Sie nicht warten möchten, können Sie die Änderungen manuell auf die Knoten anwenden. Dazu rufen Sie den Befehl gcloud container clusters upgrade
auf und übergeben das Flag --cluster-version
mit der GKE-Version, die vom Knotenpool bereits ausgeführt wird. Für diese Problemumgehung muss die Google Cloud CLI verwendet werden.
NodeLocal DNSCache mit Cloud DNS
Wenn Sie NodeLocal DNSCache mit Cloud DNS verwenden, verwendet der Cluster die Nameserver-IP-Adresse 169.254.20.10
, wie im folgenden Diagramm dargestellt:
Daher kann die IP-Adresse des kube-dns
-Dienstes von der Nameserver-IP-Adresse abweichen, die Ihre Pods verwenden. Dieser Unterschied bei den IP-Adressen ist zu erwarten, da die IP-Adresse des Nameservers 169.254.20.10
erforderlich ist, damit Cloud DNS ordnungsgemäß funktioniert.
Prüfen Sie die IP-Adressen mit den folgenden Befehlen:
Rufen Sie die IP-Adresse des
kube-dns
-Dienstes auf:kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
Die Ausgabe ist die IP-Adresse von
kube-dns
, z. B.10.0.0.10:53
.Öffnen Sie eine Shell-Sitzung im Pod:
kubectl exec -it POD_NAME -- /bin/bash
Lesen Sie in der Pod-Shell-Sitzung den Inhalt der Datei
/etc/resolv.conf
:cat /etc/resolv.conf
Die Ausgabe ist
169.254.20.10
Netzwerkrichtlinie mit NodeLocal DNSCache
Wenn Sie Netzwerkrichtlinien mit NodeLocal DNSCache verwenden und nicht Cloud DNS oder GKE Dataplane V2 einsetzen, müssen Sie Regeln konfigurieren, damit Ihre Arbeitslasten und die node-local-dns
-Pods DNS-Abfragen senden können.
Verwenden Sie eine ipBlock
-Regel in Ihrem Manifest, um die Kommunikation zwischen -Pods und kube-dns zu ermöglichen.
Das folgende Manifest beschreibt eine Netzwerkrichtlinie, die eine ipBlock
-Regel verwendet:
spec:
egress:
- ports:
- port: 53
protocol: TCP
- port: 53
protocol: UDP
to:
- ipBlock:
cidr: KUBE_DNS_SVC_CLUSTER_IP/32
podSelector: {}
policyTypes:
- Egress
Ersetzen Sie KUBE_DNS_SVC_CLUSTER_IP
durch die IP-Adresse des Dienstes "kube-dns". Sie können die IP-Adresse des Dienstes "kube-dns" mit dem folgenden Befehl abrufen:
kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
Bekannte Probleme
DNS-Zeitlimit in ClusterFirstWithHostNet dnsPolicy bei Verwendung von NodeLocal DNSCache und GKE Dataplane V2
In Clustern, in denen GKE Dataplane V2 und NodeLocal DNSCache verwendet werden, können Pods, bei denen hostNetwork
auf true
und dnsPolicy
auf ClusterFirstWithHostNet
festgelegt sind, keine Cluster-DNS-Back-Ends erreichen. DNS-Logs können Einträge wie die folgenden enthalten:
nslookup: write to 'a.b.c.d': Operation not permitted
;; connection timed out; no servers could be reached
Die Ausgabe gibt an, dass die DNS-Anfragen die Backend-Server nicht erreichen können.
Das Problem lässt sich dadurch umgehen, dass Sie dnsPolicy
und dnsConfig
für hostNetwork
-Pods festlegen:
spec:
dnsPolicy: "None"
dnsConfig:
nameservers:
- KUBE_DNS_UPSTREAM
searches:
- cluster.local
- svc.cluster.local
- NAMESPACE.svc.cluster.local
- c.PROJECT_ID.internal
- google.internal
options:
- name: ndots
value: "5"
Dabei gilt:
NAMESPACE
ist der Namespace des PodshostNetwork
.PROJECT_ID
ist die ID Ihres Google Cloud-Projekts.KUBE_DNS_UPSTREAM
ist die ClusterIP des Upstream-kube-dns-Dienstes. Sie können diesen Wert mit dem folgenden Befehl abrufen:kubectl get svc -n kube-system kube-dns-upstream -o jsonpath="{.spec.clusterIP}"
DNS-Anfragen vom Pod können jetzt kube-dns erreichen und NodeLocal DNSCache umgehen.
NodeLocal DNSCache-Zeitüberschreitungsfehler
In Clustern mit aktiviertem NodeLocal DNSCache können die Logs Einträge wie die folgenden enthalten:
[ERROR] plugin/errors: 2 <hostname> A: read tcp <node IP: port>-><kubedns IP>:53: i/o timeout
Die Ausgabe enthält die IP-Adresse des Cluster-IP-Dienstes kube-dns-upstream
. In diesem Beispiel wurde innerhalb von zwei Sekunden keine Antwort auf eine DNS-Anfrage von kube-dns empfangen. Dies könnte einen der folgenden Gründe haben:
- Ein zugrunde liegendes Problem mit der Netzwerkverbindung.
- Erhebliche Erhöhung der DNS-Abfragen von der Arbeitslast oder aufgrund einer Skalierung des Knotenpools
Daher können die vorhandenen kube-dns
-Pods nicht alle Anfragen gleichzeitig verarbeiten. Die Problemumgehung besteht darin, die Anzahl der kube-dns-Replikate zu erhöhen. Optimieren Sie dazu die Autoscaling-Parameter.
kube-dns hochskalieren
Sie können einen niedrigeren Wert für nodesPerReplica
verwenden, damit mehr kube-dns-Pods erstellt werden, wenn Clusterknoten vertikal skaliert werden. Es wird dringend empfohlen, einen expliziten max
-Wert festzulegen, damit die GKE-Steuerungsebenen-VM (Virtuelle Maschine) aufgrund der großen Anzahl von kube-dns-Pods, die die Kubernetes API überwachen, nicht überlastet ist.
Sie können max
auf die Anzahl der Knoten im Cluster festlegen. Wenn der Cluster mehr als 500 Knoten hat, legen Sie max
auf 500 fest.
Bei Standardclustern können Sie die Anzahl der kube-dns-Replikate ändern. Bearbeiten Sie dazu die ConfigMap kube-dns-autoscaler
. Diese Konfiguration wird in Autopilot-Clustern nicht unterstützt.
kubectl edit configmap kube-dns-autoscaler --namespace=kube-system
Die Ausgabe sieht in 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(kerns × 1/coresPerReplica), ceil(nodes × 1/nodesPerReplica), maxValue)
Ändern Sie zum Hochskalieren nodesPerReplica
in einen kleineren Wert und fügen Sie einen max
-Wert ein.
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
Mit der Konfiguration wird ein kube-dns-Pod pro acht Knoten im Cluster erstellt. Ein Cluster mit 24 Knoten hat 3 Replikate und ein Cluster mit 40 Knoten hat 5 Replikate. Wenn der Cluster über 120 Knoten hat, steigt die Anzahl der kube-dns-Replikate nicht über 15 (max
-Wert) an.
Legen Sie eine Mindestanzahl von Replikat für kube-dns fest, um eine grundlegende DNS-Verfügbarkeit in Ihrem Cluster zu gewährleisten.
Die ConfigMap-Ausgabe kube-dns-autoscaler
mit dem Feld min
würde in etwa so aussehen:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
Nächste Schritte
- Deployment von verwaltetem DNS in GKE
- Eine Übersicht zur Verwendung von DNS in Kubernetes-Clustern finden Sie unter DNS for Services and Pods
- Cloud DNS für GKE verwenden