Einführung
Sie können den gewünschten Zustand inzwischen mit Manifests beschreiben und Pods sowie Deployments erstellen. Die nächste wichtige Fähigkeit besteht darin zu verstehen, was zu tun ist, wenn Kubernetes diesen gewünschten Zustand nicht umsetzen kann.
In diesem Lab arbeiten Sie mit zwei kleinen Deployments: einem fehlerfreien und einem, das absichtlich einen Tippfehler im Image-Tag enthält. Sie folgen einem wiederholbaren Ablauf – von allgemeinen Symptomen zu konkreten Belegen –, reparieren das Manifest statt nur das laufende Objekt zu ändern und untersuchen anschließend die wiederhergestellte Anwendung anhand von Logs und Befehlen innerhalb ihres Containers.
Ziel ist nicht, sich jede mögliche Fehlerursache zu merken. Vielmehr sollen Sie eine ruhige Routine zur Fehleranalyse entwickeln: beobachten, eingrenzen, Belege untersuchen, den gewünschten Zustand reparieren und die Wiederherstellung überprüfen.
Einen kontrollierten Fehler erzeugen
Start der Umgebung: Dieses Lab startet einen vollständigen Kubernetes-Cluster für Sie. Die Konfiguration der Steuerungsebene, des Knotens und der Netzwerkkomponenten dauert normalerweise 2–3 Minuten. Bitte warten Sie geduldig, bis die Umgebung vollständig geladen ist, bevor Sie beginnen.
Eine echte Fehleranalyse beginnt mit einem Symptom. In diesem Schritt stellen Sie eine fehlerfreie und eine absichtlich defekte Arbeitslast bereit, um beide unter identischen Clusterbedingungen vergleichen zu können.
Wechseln Sie in den vorbereiteten Arbeitsbereich und listen Sie dessen Dateien auf. cd ändert das aktuelle Verzeichnis, ls listet die darin enthaltenen Namen auf. Die Befehle stehen in separaten Zeilen und werden der Reihe nach ausgeführt:
cd /home/labex/project/debug-lab
ls
Sie sollten healthy-web.yaml und broken-web.yaml sehen. Beide Dateien definieren Deployments mit jeweils einer Replik, aber eine enthält einen subtilen Konfigurationsfehler, den Sie später diagnostizieren werden.
Wenden Sie beide Manifests an. kubectl apply übermittelt den gewünschten Zustand an den API-Server, und jedes -f bezeichnet eine Eingabedatei. Ein Befehl kann mehrere -f-Optionen enthalten:
kubectl apply -f healthy-web.yaml -f broken-web.yaml
Warten Sie zunächst auf das bekanntermaßen fehlerfreie Deployment:
kubectl rollout status deployment/healthy-web --timeout=60s
Die Meldung deployment "healthy-web" successfully rolled out stellt eine wichtige Referenz dar: Der Cluster kann Pods einplanen und das zwischengespeicherte NGINX-Image ausführen.
Geben Sie dem anderen Deployment nun kurz Zeit für den Rollout:
kubectl rollout status deployment/broken-web --timeout=15s || true
Der Timeout ist zu erwarten. || true weist die Shell an fortzufahren, weil dieser Fehler Teil der Übung ist und kein Grund, das Lab abzubrechen.
Vergleichen Sie die Deployment-Übersicht:
kubectl get deployments
healthy-web sollte 1/1 bereit anzeigen, während broken-web 0/1 meldet. Damit haben Sie festgestellt, dass das Problem auf eine bestimmte Arbeitslast beschränkt ist und kein vollständiger Cluster-Ausfall vorliegt.
Das Problem anhand von Ressourcenübersichten eingrenzen
In diesem Schritt beginnen Sie mit einer groben Übersicht, bevor Sie sich den Details widmen. Kubernetes-Controller erzeugen eine Kette von Objekten. Deshalb wird ein Problem mit einem Deployment häufig zuerst in dessen ReplicaSet und Pod sichtbar.
Listen Sie die zugehörigen Objekttypen gemeinsam auf. Mit Kommas können Sie in einer kubectl get-Anfrage mehrere Ressourcentypen angeben, während -o wide zusätzliche Spalten wie Knoten- und IP-Informationen einblendet:
kubectl get deployments,replicasets,pods -o wide
Lesen Sie die Ausgabe von oben nach unten:
- Ein Deployment meldet die gewünschte und die verfügbare Anzahl von Replikas.
- Ein ReplicaSet gibt diese gewünschte Anzahl an die Pods weiter.
- Ein Pod meldet die Bereitschaft des Containers und eine kurze Statusursache.
Beschränken Sie die Ansicht mithilfe des Labels auf die fehlerhafte Anwendung:
kubectl get pods -l app=broken-web -o wide
Der Pod-Name enthält ein automatisch erzeugtes Suffix. Labels sind daher zuverlässiger, als ein wechselndes Namensfragment in Skripte zu übernehmen.
Fordern Sie in dieser Phase nur die relevanten Felder an. -o custom-columns='...' erstellt eine Tabelle aus ausdrücklich angegebenen Objektfeldern. Jeder Eintrag enthält eine Überschrift wie NAME, gefolgt vom JSON-Feldpfad, der den Wert liefert. Der abschließende Backslash verbindet die beiden angezeigten Shell-Zeilen zu einem einzigen Befehl:
kubectl get pods -l app=broken-web \
-o custom-columns='NAME:.metadata.name,READY:.status.containerStatuses[0].ready,WAITING_REASON:.status.containerStatuses[0].state.waiting.reason,NODE:.spec.nodeName'
Die Warteursache kann zunächst ErrImagePull lauten und später zu ImagePullBackOff werden. Beides bedeutet, dass der Container nicht gestartet wurde, weil Kubernetes sein Image nicht beziehen konnte. Das ist eine deutlich präzisere Aussage als lediglich „Der Pod ist ausgefallen“.
Den Pod mit describe untersuchen
In diesem Schritt verwenden Sie describe, um herauszufinden, warum der Container wartet. Die Übersicht hat Ihnen gesagt, was falsch ist; nun sammeln Sie die Erklärung dafür.
Speichern Sie den automatisch erzeugten Pod-Namen in einer Shell-Variable. $(...) ist eine Befehlsauswertung: Die Shell führt den darin enthaltenen kubectl-Befehl aus und weist dessen Ausgabe BROKEN_POD zu. JSONPath wählt den Namen des ersten passenden Pods aus, und echo gibt den gespeicherten Wert aus:
BROKEN_POD=$(kubectl get pods -l app=broken-web -o jsonpath='{.items[0].metadata.name}')
echo "$BROKEN_POD"
Beschreiben Sie diesen Pod:
kubectl describe pod "$BROKEN_POD"
describe verbindet nützliche Felder mit aktuellen Events. Konzentrieren Sie sich auf drei Bereiche:
- Containers → Image zeigt das exakt angeforderte Image.
- State → Waiting → Reason beschreibt den aktuellen Zustand des Containers.
- Events protokolliert die Versuche des Kubelets sowie die Fehlermeldungen.
In diesem Szenario besagt die Event-Meldung, dass das Tag 1.27-alpine-missing nicht gefunden werden kann. Der Cluster führt genau das aus, was im Manifest angefordert wurde; falsch ist der gewünschte Zustand selbst.
Bestätigen Sie das Image direkt mit JSONPath:
kubectl get pod "$BROKEN_POD" -o jsonpath='Image: {.spec.containers[0].image}{"\n"}'
JSONPath ist hilfreich, wenn eine umfangreiche YAML- oder describe-Ausgabe mehr Informationen enthält, als Sie benötigen. Hier isolieren Sie genau das Feld, das später korrigiert werden muss.
Events als Zeitachse lesen
In diesem Schritt lesen Sie Events als zeitliche Abfolge der Aktivitäten in Kubernetes. Events sind kurzlebige Diagnoseeinträge, die Informationen über Planung, Image-Abrufe, Containerstarts, Neustarts und viele andere Zustandsänderungen liefern.
Listen Sie die aktuellen Events des Namespace in chronologischer Reihenfolge auf. --sort-by sortiert Objekte nach dem angegebenen Metadatenfeld. Die Anführungszeichen sorgen dafür, dass der JSON-ähnliche Feldpfad als ein einziges Argument behandelt wird:
kubectl get events --sort-by='.metadata.creationTimestamp'
Die letzten Zeilen sind normalerweise die neuesten. Suchen Sie nach Einträgen, deren Spalte OBJECT auf den fehlerhaften Pod verweist und deren REASON Werte wie Pulling, Failed oder BackOff enthält.
Sie können die Ausgabe reduzieren, indem Sie die Events nach dem automatisch erzeugten Pod-Namen filtern. --field-selector filtert serverseitig nach Objektfeldern und nicht nach Labels. Das Komma bedeutet, dass beide Bedingungen erfüllt sein müssen. Die Backslashes setzen einen einzigen Befehl über mehrere gut lesbare Zeilen fort:
BROKEN_POD=$(kubectl get pods -l app=broken-web -o jsonpath='{.items[0].metadata.name}')
kubectl get events \
--field-selector involvedObject.kind=Pod,involvedObject.name="$BROKEN_POD" \
--sort-by='.metadata.creationTimestamp'
Betrachten Sie get, describe und events als sich ergänzende Ansichten:
getfindet das fehlerhafte Objekt schnell.describeverbindet Konfiguration, Zustand und zugehörige Events für ein einzelnes Objekt.eventsliefert eine zeitlich geordnete Ansicht, in der wiederholte Versuche erkennbar werden können.
Wiederholte BackOff-Einträge bedeuten nicht, dass Kubernetes den Pod aufgegeben hat. Sie zeigen, dass Kubernetes nach fehlgeschlagenen Abrufversuchen die nächsten Versuche zeitlich auseinanderzieht.
Den gewünschten Zustand reparieren und die Wiederherstellung überprüfen
In diesem Schritt reparieren Sie den gewünschten Zustand und überprüfen die Wiederherstellung. Sie verfügen bereits über genügend Belege: Das Manifest fordert ein nicht vorhandenes Image-Tag an. Reparieren Sie zuerst das gespeicherte Manifest und wenden Sie es anschließend an, damit Datei und laufender Cluster konsistent bleiben.
Zeigen Sie zum Vergleich die Image-Zeilen in beiden Manifests an. grep durchsucht Text, -n stellt jeder Fundstelle ihre Zeilennummer voran, und beide Dateinamen werden in einem einzigen Befehl durchsucht:
grep -n 'image:' healthy-web.yaml broken-web.yaml
Das fehlerfreie Manifest verwendet nginx:1.27-alpine; das defekte Manifest enthält zusätzlich das nicht vorhandene Suffix -missing.
Ersetzen Sie nur dieses Suffix. sed führt eine Textersetzung im Format s/old/new/ durch. -i bearbeitet die angegebene Datei direkt, anstatt nur den geänderten Text auszugeben:
sed -i 's/nginx:1.27-alpine-missing/nginx:1.27-alpine/' broken-web.yaml
Validieren Sie die reparierte Datei lokal:
kubectl apply --dry-run=client -f broken-web.yaml
Zeigen Sie den Unterschied zwischen der Datei und dem laufenden Objekt an:
kubectl diff -f broken-web.yaml || true
kubectl diff beendet sich mit dem Rückgabecode 1, wenn es einen Unterschied feststellt. || true sorgt daher dafür, dass die Lernsequenz fortgesetzt wird. Im Diff enthält eine Zeile, die mit - beginnt, das alte Image; eine Zeile mit + enthält das reparierte Image.
Wenden Sie die Reparatur an und warten Sie auf die Wiederherstellung:
kubectl apply -f broken-web.yaml
kubectl rollout status deployment/broken-web --timeout=60s
Bestätigen Sie, dass nun beide Deployments fehlerfrei sind:
kubectl get deployments
Beide sollten 1/1 bereit melden. Kubernetes hat aus der korrigierten Pod-Vorlage ein neues ReplicaSet und einen neuen Pod erstellt. Sie mussten den fehlgeschlagenen Pod nicht manuell reparieren.
Anwendungslogs lesen
In diesem Schritt verwenden Sie Anwendungslogs als neue Quelle für Belege, nachdem der Container nun startet. kubectl logs ruft die Standardausgabe und den Standardfehlerstrom des Containers ab.
Wählen Sie den neuen, von broken-web verwalteten fehlerfreien Pod aus. Dabei wiederholen Sie die zuvor verwendete Befehlsauswertung und JSONPath. --field-selector=status.phase=Running ergänzt eine serverseitige Bedingung, sodass nur ein laufender Pod ausgewählt wird:
WEB_POD=$(kubectl get pods -l app=broken-web \
--field-selector=status.phase=Running \
-o jsonpath='{.items[0].metadata.name}')
echo "$WEB_POD"
NGINX hat möglicherweise noch keinen Eintrag im Zugriffslog, weil bisher niemand eine Seite angefordert hat. Erzeugen Sie eine Anfrage aus dem Pod heraus. Bei kubectl exec POD -- COMMAND trennt -- die Optionen von kubectl von dem Befehl, der im Container ausgeführt wird. wget -qO- ruft die Seite ohne zusätzliche Ausgaben ab und schreibt sie auf die Standardausgabe. Die Pipe | leitet diese Ausgabe an head weiter, das nur den Anfang anzeigt:
kubectl exec "$WEB_POD" -- wget -qO- http://127.0.0.1 | head
Das HTML beginnt mit <!DOCTYPE html>. Damit ist bewiesen, dass NGINX lokal auf Port 80 geantwortet hat.
Lesen Sie nun die aktuellen Logs. --tail=10 begrenzt die Ausgabe auf die zehn neuesten Zeilen, damit Startmeldungen den relevanten Anfrageeintrag nicht überlagern:
kubectl logs "$WEB_POD" --tail=10
Suchen Sie nach einer HTTP-Anfrage mit GET / HTTP/1.1 und dem Antwortcode 200. Logs sind besonders nützlich, wenn ein Container läuft, sich die Anwendung aber fehlerhaft verhält. Bei einem Fehler beim Abrufen des Images helfen sie normalerweise nicht weiter, weil der Container gar nicht gestartet wurde.
Den Container von innen untersuchen
In diesem Schritt untersuchen Sie die wiederhergestellte Anwendung aus ihrem Container heraus. kubectl exec führt einen Befehl in einem bereits laufenden Container aus und kann dessen Dateisystem, Prozesse, Umgebung, DNS-Sicht oder lokales Netzwerkverhalten überprüfen.
Verwenden Sie erneut den Namen des laufenden Pods:
WEB_POD=$(kubectl get pods -l app=broken-web \
--field-selector=status.phase=Running \
-o jsonpath='{.items[0].metadata.name}')
Fragen Sie den Container nach seinem Hostnamen:
kubectl exec "$WEB_POD" -- hostname
Die Ausgabe entspricht dem Pod-Namen, weil Kubernetes den Hostnamen des Pods standardmäßig entsprechend setzt.
Überprüfen Sie die Syntax der NGINX-Konfiguration innerhalb des Containers:
kubectl exec "$WEB_POD" -- nginx -t
Die Meldungen syntax is ok und test is successful zeigen, dass die Anwendungskonfiguration intern gültig ist.
Führen Sie abschließend eine kompakte Gesundheitsprüfung von innen nach außen durch. >/dev/null verwirft das heruntergeladene HTML, und && führt echo nur aus, wenn wget erfolgreich war. Die Erfolgsmeldung erscheint daher erst, nachdem eine HTTP-Antwort empfangen wurde:
kubectl exec "$WEB_POD" -- wget -qO- http://127.0.0.1 >/dev/null && echo "NGINX responded inside the Pod"
Verwenden Sie exec mit Bedacht. Es setzt einen laufenden Container voraus und hätte den früheren Fehler beim Abrufen des Images daher nicht diagnostizieren können. Ihre Beweiskette für diesen Vorfall lautete:
get -> describe -> events -> repair manifest -> rollout status -> logs -> exec
Je nach Fehler kann die Analyse auf einer anderen Stufe enden. Wenn Sie sich jedoch von kostengünstigen Übersichten zu einer immer tieferen Untersuchung vorarbeiten, bleibt die Fehleranalyse zielgerichtet.
Zusammenfassung
Sie haben einen vollständigen, einsteigerfreundlichen Ablauf zur Fehleranalyse in Kubernetes v1.35 praktiziert. Sie verglichen fehlerfreie und fehlerhafte Arbeitslasten, grenzten das Problem mithilfe von Labels und präzisen Feldern ein, identifizierten mit describe und Events ein ungültiges Image-Tag, reparierten die deklarative Quelle der Wahrheit und überprüften die Wiederherstellung mit Rollout-Status, Logs und Befehlen innerhalb des Containers.
Die zentrale Erkenntnis lautet: Wählen Sie die Belege passend zur aktuellen Phase des Lebenszyklus der Arbeitslast. Wenn ein Container noch nicht gestartet ist, untersuchen Sie Zustand und Events. Sobald er läuft, können Logs und exec Hinweise auf das Verhalten der Anwendungsebene liefern. In der nächsten Herausforderung wenden Sie diesen Ablauf selbstständig an.


