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.

Beziehung zwischen kube-dns-Pods und 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"]

Fehlerbehebung

Informationen zur Fehlerbehebung bei kube-dns finden Sie auf den folgenden Seiten:

Beschränkungen

In den folgenden Abschnitten finden Sie Informationen zu kube-dns-Einschränkungen.

Limit für Suchdomains

Es sind maximal 32 DNS-Suchdomains für /etc/resolv.conf zulässig. Wenn Sie mehr als 32 Suchdomains definieren, schlägt die Pod-Erstellung mit dem folgenden Fehler fehl:

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.

Diese Fehlermeldung wird von kube-apiserver als Reaktion auf einen Versuch zurückgegeben, einen Pod zu erstellen.

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
  • Überschreiten des Limits von 20 Abfragen pro Sekunde für jeden kube-dns-Pod.
  • 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 Upstream-DNS-Resolver mit einer großen oder „unendlichen“ 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.

kube-dns- oder dnsmasq-Messwerte protokollieren

Sie können Messwerte zu DNS-Abfragen im GKE-Cluster abrufen. So können Sie schnell kube-dns- oder dnsmasq-Messwerte abrufen, ohne das Deployment zu ändern.

  1. Listen Sie die Pods unter dem kube-dns-Deployment auf.

    $ kubectl get pods -n kube-system --selector=k8s-app=kube-dns
    

    Die Ausgabe sollte in etwa so aussehen:

    NAME                        READY     STATUS    RESTARTS   AGE
    kube-dns-548976df6c-98fkd   4/4       Running   0          48m
    kube-dns-548976df6c-x4xsh   4/4       Running   0          47m
    
  2. Wählen Sie einen Pod aus und legen Sie seinen Namen auf eine Variable fest.

    POD="kube-dns-548976df6c-98fkd"
    
  3. Richten Sie die Portweiterleitung für den ausgewählten kube-dns-Pod ein.

    $ kubectl port-forward pod/${POD} -n kube-system 10054:10054 10055:10055
    

    Die Ausgabe sollte in etwa so aussehen:

    Forwarding from 127.0.0.1:10054 -> 10054
    Forwarding from 127.0.0.1:10055 -> 10055
    
  4. Rufen Sie die Messwerte ab, indem Sie den folgenden curl-Befehl für den Endpunkt ausführen.

    $ curl http://127.0.0.1:10054/metrics; curl http://127.0.0.1:10055/metrics

    Port 10054 enthält dnsmasq-Messwerte und Port 10055 kube-dns-Messwerte.

    Die Ausgabe sollte in etwa so aussehen:

    kubedns_dnsmasq_errors 0
    kubedns_dnsmasq_evictions 0
    kubedns_dnsmasq_hits 3.67351e+06
    kubedns_dnsmasq_insertions 254114
    kubedns_dnsmasq_max_size 1000
    kubedns_dnsmasq_misses 3.278166e+06
    
    

Nächste Schritte