Diagnose von Service-DNS-Zugriffen

KubernetesBeginner
Jetzt üben

Einführung

Im vorherigen Lab haben Sie gesehen, wie ein Service Pods einen stabilen Einstiegspunkt innerhalb des Clusters bietet. Kubernetes weist zudem jedem Service einen DNS-Namen zu. Ein Pod im selben Namespace kann in der Regel den kurzen Service-Namen verwenden, während ein Pod in einem anderen Namespace häufig einen längeren Namen benötigt, der den Namespace des Service enthält.

In diesem Lab erstellen Sie einen Web-Service, testen den DNS-Zugriff innerhalb desselben Namespace, reproduzieren einen Fehler bei der Verwendung von Kurznamen über Namespaces hinweg, korrigieren die Anfrage mit dem FQDN des Service und untersuchen die Objekte, die Ihnen bei der Diagnose helfen, ob ein DNS-Problem tatsächlich auf den Service, die Endpunkte oder CoreDNS zurückzuführen ist.

Vorbereiten eines Web-Service

In diesem Schritt erstellen Sie den Ziel-Service, den die späteren DNS-Tests auflösen werden. Die Workload ist bewusst einfach gehalten, da der Schwerpunkt auf der DNS-Namensgebung liegt und nicht auf der Anwendungsbereitstellung.

Beginnen Sie in /home/labex/project:

mkdir -p /home/labex/project
cd /home/labex/project

Überprüfen Sie, ob der Kubernetes API-Server erreichbar ist. Falls die VM gerade erst gestartet wurde und der Node noch nicht bereit ist, warten Sie einige Sekunden und führen Sie den Befehl erneut aus.

kubectl get nodes --request-timeout=5s

Die erwartete Ausgabe enthält:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Warten Sie, bis das Cluster-Netzwerk bereit ist. Da dieses Lab Datenverkehr zwischen Pods sendet, muss das Pod-Netzwerk einwandfrei funktionieren, bevor DNS-Zugriffstests aussagekräftig sind.

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Erwartete Ausgabe:

pod/calico-node-... condition met

Erstellen Sie einen Namespace namens ckad-prep-dns und legen Sie diesen als aktuellen Namespace fest:

kubectl create namespace ckad-prep-dns
kubectl config set-context --current --namespace=ckad-prep-dns

Erstellen Sie ein Deployment und machen Sie es über einen Service namens dns-web verfügbar:

kubectl create deployment dns-web --image=nginx:1.25 --port=80
kubectl expose deployment dns-web --port=80 --target-port=80

Warten Sie, bis der Web-Pod verfügbar ist:

kubectl rollout status deployment/dns-web --timeout=120s

Untersuchen Sie den Service und dessen EndpointSlice. Der Service ist das stabile DNS-Ziel; das EndpointSlice zeigt die aktuellen Backend-Pod-Adressen, die vom Service ausgewählt wurden.

kubectl get service dns-web
kubectl get endpointslice -l kubernetes.io/service-name=dns-web

Die erwartete Ausgabe enthält:

NAME      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
dns-web   ClusterIP   ...          <none>        80/TCP    ...

NAME          ADDRESSTYPE   PORTS   ENDPOINTS   AGE
dns-web-...   IPv4          80      ...         ...

Auflösen des Service innerhalb desselben Namespace

In diesem Schritt erstellen Sie einen Client-Pod im selben Namespace wie der Service und verwenden den kurzen Service-Namen. Dies ist der einfachste Fall für Service-DNS.

Erstellen Sie einen Client-Pod, der dauerhaft läuft:

kubectl run same-ns-client --image=busybox:1.36 --restart=Never --command -- sleep 3600

Warten Sie, bis der Client-Pod bereit ist:

kubectl wait --for=condition=Ready pod/same-ns-client --timeout=120s

Erwartete Ausgabe:

pod/same-ns-client condition met

Verwenden Sie nslookup innerhalb des Client-Pods, um den kurzen Service-Namen dns-web aufzulösen. Der Kurzname funktioniert hier, da sich der Client-Pod und der Service im selben Namespace befinden. Da nslookup von BusyBox möglicherweise zusätzliche NXDOMAIN-Zeilen für andere Suchsuffixe ausgibt und nach der Anzeige der korrekten Adresse einen Exit-Code ungleich Null zurückgibt, verwendet der Befehl || true. Achten Sie auf die Zeilen Name und Address.

kubectl exec same-ns-client -- sh -c 'nslookup dns-web || true'

Die erwartete Ausgabe enthält:

Name:      dns-web.ckad-prep-dns.svc.cluster.local
Address: ...

Senden Sie nun eine HTTP-Anfrage an den kurzen Service-Namen:

kubectl exec same-ns-client -- wget -qO- http://dns-web | grep '<title>Welcome to nginx'

Erwartete Ausgabe:

<title>Welcome to nginx!</title>

Diagnose eines Fehlers bei Kurznamen über Namespaces hinweg

In diesem Schritt erstellen Sie einen Client-Pod in einem anderen Namespace und reproduzieren einen häufigen DNS-Fehler. Ein kurzer Service-Name wird zuerst relativ zum Namespace des Client-Pods aufgelöst, daher findet dns-web den Service in ckad-prep-dns nicht, wenn der Client in einem anderen Namespace ausgeführt wird.

Erstellen Sie einen zweiten Namespace und einen Client-Pod darin:

kubectl create namespace ckad-prep-dns-client
kubectl run remote-client --namespace ckad-prep-dns-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --namespace ckad-prep-dns-client --for=condition=Ready pod/remote-client --timeout=120s

Die erwartete Ausgabe enthält:

namespace/ckad-prep-dns-client created
pod/remote-client created
pod/remote-client condition met

Versuchen Sie, den Kurznamen vom Remote-Namespace aus aufzulösen. Das || true sorgt dafür, dass das Lab fortgesetzt wird, da dieser Fehler erwartet wird.

kubectl exec --namespace ckad-prep-dns-client remote-client -- nslookup dns-web || true

Die erwartete Ausgabe enthält einen Fehler wie:

** server can't find dns-web...

Lösen Sie nun den vollqualifizierten Service-Namen (FQDN) auf. Das vollständige Muster lautet <service>.<namespace>.svc.cluster.local.

kubectl exec --namespace ckad-prep-dns-client remote-client -- nslookup dns-web.ckad-prep-dns.svc.cluster.local

Die erwartete Ausgabe enthält:

Name:      dns-web.ckad-prep-dns.svc.cluster.local
Address 1: ...

Verwenden Sie denselben vollqualifizierten Namen für den HTTP-Zugriff:

kubectl exec --namespace ckad-prep-dns-client remote-client -- wget -qO- http://dns-web.ckad-prep-dns.svc.cluster.local | grep '<title>Welcome to nginx'

Erwartete Ausgabe:

<title>Welcome to nginx!</title>

Überprüfen des DNS-Fehlerbehebungspfads

In diesem Schritt untersuchen Sie die Objekte, die dabei helfen, ein DNS-Namensproblem von einem Service- oder Backend-Problem zu unterscheiden. Eine praktische Reihenfolge für die Fehlerbehebung ist: Bestätigen Sie den Service-Namen und den Namespace, bestätigen Sie, dass Endpunkte vorhanden sind, und prüfen Sie dann, ob CoreDNS verfügbar ist.

Untersuchen Sie zuerst den Service in seinem tatsächlichen Namespace:

kubectl get service dns-web --namespace ckad-prep-dns

Die erwartete Ausgabe enthält:

NAME      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
dns-web   ClusterIP   ...          <none>        80/TCP    ...

Untersuchen Sie als Nächstes das EndpointSlice. Wenn DNS aufgelöst wird, aber der HTTP-Verkehr fehlschlägt, sind fehlende Endpunkte ein häufiger Grund.

kubectl get endpointslice --namespace ckad-prep-dns -l kubernetes.io/service-name=dns-web

Die erwartete Ausgabe enthält mindestens einen Endpunkt:

NAME          ADDRESSTYPE   PORTS   ENDPOINTS   AGE
dns-web-...   IPv4          80      ...         ...

Überprüfen Sie die CoreDNS-Pods. CoreDNS ist der Cluster-DNS-Dienst, der DNS-Anfragen von Pods beantwortet.

kubectl get pods --namespace kube-system -l k8s-app=kube-dns

Die erwartete Ausgabe enthält laufende CoreDNS-Pods:

NAME                       READY   STATUS    RESTARTS   AGE
coredns-...                1/1     Running   ...        ...

Untersuchen Sie abschließend die DNS-Suchkonfiguration des Remote-Clients. Die search-Zeile erklärt, warum der Kurzname dns-web im Client-Namespace gesucht wurde, bevor Sie den vollständigen Namen verwendet haben.

kubectl exec --namespace ckad-prep-dns-client remote-client -- cat /etc/resolv.conf

Die erwartete Ausgabe enthält einen Suchpfad ähnlich diesem:

search ckad-prep-dns-client.svc.cluster.local svc.cluster.local cluster.local
nameserver ...

Zusammenfassung

Sie haben die Diagnose von Kubernetes-Service-DNS-Zugriffen in einer einsteigerfreundlichen Abfolge geübt. Sie haben einen Service erstellt, bestätigt, dass ein Client im selben Namespace den kurzen Service-Namen verwenden kann, einen Fehler bei Kurznamen über Namespaces hinweg reproduziert, diesen mit dem vollständigen Service-DNS-Namen behoben und den Service, das EndpointSlice, die CoreDNS-Pods sowie den DNS-Suchpfad des Clients untersucht, um zu verstehen, woher DNS-Zugriffsprobleme stammen.