NodeLocal DNSCache einrichten

In diesem Dokument wird beschrieben, wie Sie NodeLocal DNSCache verwenden, um die DNS-Lookup-Latenz zu reduzieren und die Leistung Ihrer Anwendung in Ihrem GKE-Cluster (Google Kubernetes Engine) zu verbessern.

NodeLocal DNSCache ist ein GKE-Add-on, das die DNS-Leistung verbessert, indem es einen DNS-Cache direkt auf jedem Clusterknoten als DaemonSet ausführt. Wenn Ihre Pods eine DNS-Anfrage stellen, wird die Anfrage zuerst an den lokalen Cache auf demselben Knoten gesendet. Durch die lokale Verarbeitung von Anfragen werden die durchschnittlichen DNS-Lookup-Zeiten erheblich verkürzt und die Last auf den zentralen DNS-Anbieter Ihres Clusters reduziert, z. B. kube-dns oder Cloud DNS for GKE. Eine detaillierte Erläuterung der DNS-Architektur und der Vorteile von NodeLocal DNSCache finden Sie unter Service Discovery.

In GKE Autopilot-Clustern ist NodeLocal DNSCache standardmäßig aktiviert und kann nicht deaktiviert werden. In GKE Standard-Clustern mit Version 1.34.1-gke.3720000 und höher ist NodeLocal DNSCache standardmäßig aktiviert, kann aber deaktiviert werden.

Dieses Dokument richtet sich an GKE-Nutzer, einschließlich Entwickler, Administratoren und Architekten. Weitere Informationen zu gängigen Rollen und Beispielaufgaben in Cloud de Confiance by S3NSfinden Sie unter Häufig verwendete GKE-Nutzerrollen und -Aufgaben.

In diesem Dokument wird davon ausgegangen, dass Sie mit den folgenden Themen vertraut sind:

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 und dem konfigurierten DNS-Anbieter 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.
  • 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 die Abfrage ausgeführt wird. Der lokale Metadatenserver greift auf Cloud DNS zu.

Der Pfad einer DNS-Anfrage, wie im vorherigen Abschnitt beschrieben.

Wenn Sie NodeLocal DNSCache in einem vorhandenen Cluster aktivieren, erstellt GKE alle Clusterknoten mit GKE-Version 1.15 und höher gemäß dem Knoten-Upgrade Prozessneu.

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 conntrack Tabelleneinträge. Dieses Verhalten verhindert unterbrochene und abgelehnte Verbindungen, die durch erschöpfte conntrack-Tabellen und Race-Bedingungen verursacht werden.
  • 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 Metadaten server weitergeleitet, wobei kube-dns umgangen wird.
  • Die lokalen DNS-Caches übernehmen automatisch Stub-Domains und Upstream-Name server, die im Abschnitt Benutzerdefinierte Resolver für Stub Domains hinzufügen 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 und stubDomains 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 ist.
  • NodeLocal DNSCache-Pods überwachen Port 53, 9253, 9353 und 8080 auf den Knoten. Wenn Sie einen anderen hostNetwork-Pod ausführen oder hostPorts mit diesen Ports konfigurieren, schlägt NodeLocal DNSCache fehl und DNS-Fehler treten auf. NodeLocal DNSCache-Pods verwenden nicht den hostNetwork Modus, wenn sie GKE Dataplane V2 verwenden und nicht verwenden Cloud DNS for GKE.
  • 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.

Hinweis

Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:

  • Aktivieren Sie die Google Kubernetes Engine API.
  • Google Kubernetes Engine API aktivieren
  • Wenn Sie die Google Cloud CLI für diese Aufgabe verwenden möchten, installieren und dann initialisieren Sie die gcloud CLI. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die neueste Version mit dem gcloud components update Befehl ab. Ältere gcloud CLI-Versionen unterstützen möglicherweise nicht die Ausführung der Befehle in diesem Dokument.

NodeLocal DNSCache aktivieren

Bei Standardclustern ist NodeLocal DNSCache ab Version 1.34.1-gke.3720000 standardmäßig aktiviert. Wenn Ihr Cluster eine frühere Version als 1.34.1-gke.3720000 hat, können Sie NodeLocal DNSCache in neuen oder vorhandenen Clustern mit der Google Cloud CLI aktivieren. Sie können NodeLocal DNSCache auch nur in neuen Clustern mit der Cloud de Confiance Console aktivieren.

gcloud

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 \
    --location=COMPUTE_LOCATION \
    --update-addons=NodeLocalDNS=ENABLED

Ersetzen Sie Folgendes:

Console

Führen Sie die folgenden Schritte aus, um NodeLocal DNSCache in einem neuen Cluster zu aktivieren:

  1. Öffnen Sie in der Cloud de Confiance Console die Seite Google Kubernetes Engine.

    Zur Seite "Kubernetes-Cluster"

  2. Klicken Sie auf den Namen des Clusters, den Sie ändern möchten.

  3. Klicken Sie unter Netzwerk im Feld DNS-Anbieter auf DNS-Anbieter bearbeiten.

  4. Klicken Sie das Kästchen NodeLocal DNSCache aktivieren an.

  5. Klicken Sie auf Änderungen speichern.

Für diese Änderung müssen die Knoten neu erstellt werden, was zu Unterbrechungen bei Ihren laufenden Arbeitslasten führen kann. Details zu dieser spezifischen Änderung finden Sie in der entsprechenden Zeile in der Tabelle Manuelle Änderungen, mit denen die Knoten mit einer Knoten Upgrade-Strategie und unter Berücksichtigung der Wartungs richtlinien neu erstellt werden. Weitere Informationen zu Knoten-Updates finden Sie unter Unterbrechungen durch Knoten-Updates planen.

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 mit GKE-Version 1.15 oder höher.

NodeLocal DNSCache deaktivieren

Hinweis: Für GKE Autopilot-Cluster ist NodeLocal DNSCache standardmäßig aktiviert und kann nicht deaktiviert werden.

NodeLocal DNSCache in einem neuen Cluster deaktivieren

Sie können NodeLocal DNSCache deaktivieren, wenn Sie einen neuen GKE Standard-Cluster mit Version 1.34.1-gke.3720000 oder höher erstellen. Führen Sie dazu den folgenden Befehl aus:

gcloud container clusters create CLUSTER_NAME  \
    --location=COMPUTE_LOCATION \
    --addons=NodeLocalDNS=DISABLED

Ersetzen Sie Folgendes:

NodeLocal DNSCache in einem vorhandenen Cluster deaktivieren

Sie können NodeLocal DNSCache in Ihrem vorhandenen GKE-Cluster mit dem folgenden Befehl deaktivieren:

gcloud container clusters update CLUSTER_NAME \
    --location=COMPUTE_LOCATION \
    --update-addons=NodeLocalDNS=DISABLED

Ersetzen Sie Folgendes:

  • CLUSTER_NAME: Der Name des Clusters, der deaktiviert werden soll.
  • COMPUTE_LOCATION: der Compute Engine-Standort für den Cluster.

Für diese Änderung müssen die Knoten neu erstellt werden, was zu Unterbrechungen bei Ihren laufenden Arbeitslasten führen kann. Details zu dieser spezifischen Änderung finden Sie in der entsprechenden Zeile in der Tabelle Manuelle Änderungen, mit denen die Knoten mit einer Knoten Upgrade-Strategie und unter Berücksichtigung der Wartungs richtlinien neu erstellt werden. Weitere Informationen zu Knoten-Updates finden Sie unter Unterbrechungen durch Knoten-Updates planen.

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:

Architektur von NodeLocal DNSCache mit Cloud DNS

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 Nameserver-IP-Adresse 169.254.20.10 erforderlich ist, damit Cloud DNS ordnungsgemäß funktioniert.

Prüfen Sie die IP-Adressen mit den folgenden Befehlen:

  1. 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.

  2. Öffnen Sie eine Shell-Sitzung im Pod:

    kubectl exec -it POD_NAME -- /bin/bash
    
  3. 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 Ihren 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 kube-dns-Dienstes. Sie können die IP-Adresse des kube-dns-Dienstes mit dem folgenden Befehl abrufen:

kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"

Bekannte Probleme

In diesem Abschnitt werden bekannte Probleme mit NodeLocal DNSCache aufgeführt.

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 das Feld hostNetwork auf true und das Feld dnsPolicy auf ClusterFirstWithHostNet festgelegt sind, keine Cluster-DNS-Back-Ends erreichen. DNS-Logs können Einträge wie die folgenden enthalten:

dnslookup: 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 die Felder dnsPolicy und dnsConfig für hostNetwork-Pods festlegen:

spec:
 dnsPolicy: "None"
 dnsConfig:
   nameservers:
     - KUBE_DNS_UPSTREAM
   searches:
     - NAMESPACE.svc.cluster.local
     - svc.cluster.local
     - cluster.local
     - c.PROJECT_ID.internal
     - google.internal
   options:
     - name: ndots
       value: "5"

Ersetzen Sie Folgendes:

  • NAMESPACE: Der Namespace des hostNetwork-Pods.
  • PROJECT_ID: Die ID Ihres Cloud de Confiance Projekts.
  • KUBE_DNS_UPSTREAM: 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 kube-dns-upstream-Cluster-IP-Dienstes. In diesem Beispiel wurde innerhalb von zwei Sekunden keine Antwort auf eine DNS-Anfrage von kube-dns empfangen. Dieses Problem kann folgende Ursachen 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, indem Sie kube-dnsskalieren.

kube-dns skalieren

Sie können einen niedrigeren Wert für das Feld 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 das Feld max auf die Anzahl der Knoten im Cluster festlegen. Wenn der Cluster mehr als 500 Knoten hat, legen Sie für das Feld max den Wert 500 fest.

Bei Standardclustern können Sie die Anzahl der kube-dns Replikate ändern. Bearbeiten Sie dazu die kube-dns-autoscaler ConfigMap. Diese Konfiguration wird in Autopilot-Clustern nicht unterstützt.

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))

Wenn Sie die Felder min und max in der ConfigMap definieren, werden die Replikate durch diese Werte begrenzt. Wenn Sie die Anzahl der Replikate erhöhen möchten, ä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}'

Die Konfiguration erstellt einen kube-dns-Pod für jeweils acht Knoten im Cluster. Ein Cluster mit 24 Knoten hat drei Replikate und ein Cluster mit 40 Knoten hat fünf Replikate. Wenn der Cluster mehr als 120 Knoten hat, steigt die Anzahl der kube-dns-Replikate nicht über 15 hinaus, was der max-Wert ist.

Legen Sie eine Mindestanzahl von Replikat für kube-dns fest, um eine grundlegende DNS-Verfügbarkeit in Ihrem Cluster zu gewährleisten.

Die Ausgabe für die ConfigMap kube-dns-autoscaler mit einem definierten Feld min sieht etwa so aus:

linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'

Nächste Schritte