kube-dns verwenden


Auf dieser Seite wird beschrieben, wie Google Kubernetes Engine (GKE) Service Discovery mithilfe des Standard-DNS-Anbieters für GKE-Cluster implementiert.

Bei Autopilot-Clustern können Sie die Standardkonfiguration von kube-dns nicht ändern.

Architektur

Wenn Sie einen Cluster erstellen, stellt GKE automatisch kube-dns-Pods im Namespace kube-system bereit. Pods greifen über einen entsprechenden Dienst, der die kube-dns-Pods gruppiert und ihnen eine einzelne IP-Adresse (ClusterIP) zuweist, auf das kube-dns-Deployment zu. Standardmäßig verwenden alle Pods in einem Cluster diesen Dienst, um DNS-Abfragen zuzuordnen. Das folgende Diagramm zeigt die Beziehung zwischen Pods und dem kube-dns-Dienst.

kube-dns-Pods-Beziehung mit dem kube-dns-Dienst

kube-dns skaliert, um die DNS-Anforderungen des Clusters zu erfüllen. Diese Skalierung wird vom kube-dns-autoscaler gesteuert, einem Pod, der standardmäßig in allen GKE-Clustern bereitgestellt wird. Der kube-dns-autoscaler passt die Anzahl der Replikate im kube-dns-Deployment entsprechend der Anzahl der Knoten und Kerne im Cluster an.

kube-dns unterstützt bis zu 1.000 Endpunkte pro monitorlosem Dienst.

Pod-DNS konfigurieren

Der auf jedem Knoten ausgeführte kubelet-Agent konfiguriert das etc/resolv.conf des Pods für die Verwendung der ClusterIP des kube-dns-Dienstes. Die folgende Beispielkonfiguration zeigt, dass die IP-Adresse des kube-dns-Dienstes 10.0.0.10 ist. Diese IP-Adresse unterscheidet sich in anderen Clustern.

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

kube-dns ist der autoritative Nameserver für die Cluster-Domain (cluster.local) und löst externe Namen rekursiv auf. Kurznamen, die nicht voll qualifiziert sind, wie myservice, werden zuerst mit lokalen Suchpfaden vervollständigt.

Benutzerdefinierte Resolver für Stub-Domains hinzufügen

Sie können die ConfigMap für kube-dns ändern, um Stub-Domains als Teil der DNS-Infrastruktur in Ihren Clustern festzulegen.

Mit Stub-Domains können Sie benutzerdefinierte Resolver pro Domain konfigurieren, sodass kube-dns bei der Auflösung dieser Domains DNS-Anfragen an bestimmte vorgelagerte DNS-Server weiterleitet.

Das folgende ConfigMap-Manifest für kube-dns enthält eine stubDomains-Konfiguration, die benutzerdefinierte Resolver für die Domain example.com festlegt.

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",
        "1.1.1.1",
        "1.0.0.1"
      ]
    }

Führen Sie den folgenden Befehl aus, um einen Texteditor zu öffnen:

kubectl edit configmap kube-dns -n kube-system

Ersetzen Sie den Inhalt der Datei durch das Manifest und beenden Sie dann den Texteditor, um das Manifest auf den Cluster anzuwenden.

Vorgelagerte Nameserver

Wenn Sie die ConfigMap für kube-dns so ändern, dass sie upstreamNameservers enthält, leitet kube-dns alle DNS-Anfragen mit Ausnahme von *.cluster.local an diese Server weiter. Dazu gehören auch metadata.internal und *.google.internal, die nicht vom vorgelagerten Server aufgelöst werden können.

Wenn Sie die Option Workload Identity-Föderation für GKE oder Arbeitslasten aktivieren, die sich auf die metadata.internal-Auflösung verlassen, fügen Sie der ConfigMap eine *.internal hinzu, um die stubDomain-Namensauflösung beizubehalten.

data:
  stubDomains: |
    {
      "internal": [
        "169.254.169.254"
      ]
    }
  upstreamNameservers: |
    ["8.8.8.8"]

Bekannte Probleme

Limit für Suchdomains

Es sind maximal sechs DNS-Suchdomains für /etc/resolv.conf zulässig. Wenn Sie mehr als sechs Suchdomains definieren, wird beim Ausführen des Befehls kubectl describe pod die folgende Warnung angezeigt:

Search Line limits were exceeded, some search paths have been omitted, the applied search line is: default.svc.cluster.local svc.cluster.local cluster.local c.<project ID>.internal google.internal

Diese Warnung wird in Cloud Logging im Abschnitt "Containerlogs" geloggt.

Entfernen Sie die zusätzlichen Suchpfade aus der Konfiguration, um dieses Problem zu beheben.

upstreamNameservers-Limit berücksichtigen

In Kubernetes gilt ein Limit von bis zu drei upstreamNameservers-Werten. Wenn Sie mehr als drei upstreamNameservers definieren, wird in Cloud Logging in den kube-dns-Bereitstellungslogs der folgende Fehler angezeigt:

Invalid configuration: upstreamNameserver cannot have more than three entries (value was &TypeMeta{Kind:,APIVersion:,}), ignoring update

In diesem Fall verhält sich kube-dns so, als wäre keine upstreamNameservers konfiguriert. Entfernen Sie die zusätzlichen upstreamNameservers aus der Konfiguration, um dieses Problem zu beheben.

Leistungsbeschränkungen mit kube-dns

Wenn bei dem DNS-Lookup eine hohe Latenz auftritt oder DNS-Auflösungsfehler mit dem Standardanbieter kube-dns auftreten, kann dies folgende Ursachen haben:

  • Häufige DNS-Lookups innerhalb Ihrer Arbeitslast ausführen
  • Höhere Pod-Dichte pro Knoten bereitstellen
  • Die Ausführung von kube-dns auf Spot- oder VMs auf Abruf, was zu unerwarteten Knotenlöschungen und nachfolgenden Problemen mit der DNS-Auflösung führen kann.

Zur Verbesserung der DNS-Lookup-Zeiten können Sie eine der folgenden Optionen auswählen:

  • Vermeiden Sie die Ausführung kritischer Systemkomponenten wie kube-dns auf Spot- oder VMs auf Abruf. Die Verwendung von Spot- oder VMs auf Abruf für DNS kann Fehler verursachen und den Cluster stören.
  • Erstellen Sie als Best Practices mindestens einen Knotenpool, der aus Standard-VMs (Nicht-Spot oder auf Abruf) besteht, um wichtige Systemkomponenten wie kube-dns zu hosten. Damit kritische Arbeitslasten nur für den zuverlässigen Knotenpool geplant werden, um ihre Ausführung auf Spot- oder VMs auf Abruf zu verhindern, können Sie Markierungen und Toleranzen für Spot-VMs verwenden.
  • NodeLocal DNSCache aktivieren.
  • kube-dns hochskalieren.
  • Achten Sie darauf, dass Ihre Anwendung dns.resolve*-basierte Funktionen anstelle von dns.lookup-basierten Funktionen verwendet, da dns.lookup synchron ist. dns.resolve*-Funktionen führen im Netzwerk immer eine asynchrone DNS-Abfrage aus.

Service-DNS-Einträge

kube-dns erstellt nur DNS-Einträge für Services, die Endpunkte haben.

Große TTL von DNS-Upstream-Servern

Wenn kube-dns eine DNS-Antwort von einem vorgelagerten DNS-Resolver mit einer großen oder „unbegrenzten“ TTL empfängt, behält es diesen TTL-Wert für den DNS-Eintrag im Cache bei. Der Eintrag läuft nie ab und könnte zu einer Diskrepanz zwischen dem Eintrag und der tatsächlichen IP-Adresse führen, die für den TTL-Namen aufgelöst wird.

GKE löst dieses Problem in den folgenden Versionen der Steuerungsebene durch Festlegen eines maximalen TTL-Werts von 30 Sekunden für jede DNS-Antwort mit einer TTL von mehr als 30 Sekunden:

  • 1.21.14-gke.9100
  • 1.22.15-gke.2100
  • 1.23.13-gke.500
  • 1.24.7-gke.500
  • 1.25.2-gke.500 oder höher.

Dieses Verhalten ähnelt NodeLocal DNSCache.

Nächste Schritte