Kurs › Folge 13
Wenn es nicht läuft: vier Fehlerbilder, die du sofort erkennst
ImagePullBackOff, CrashLoopBackOff, Pending, leere Endpoints — und der Ablauf, der dich in Minuten zur Ursache bringt.
Das Video zu dieser Folge ist noch nicht veröffentlicht. Die Notizen stehen trotzdem schon hier.
Was du danach kannst
- die vier haeufigsten Fehlerbilder am Statuswort erkennen
- den immer gleichen Ablauf anwenden - get, describe, logs, exec
- die Logs eines bereits gestorbenen Containers lesen
- einen Fehler zwischen Service und Pods finden, obwohl beide "laufen"
Warum diese Folge so früh kommt
Die meisten Kurse behandeln Fehlersuche am Ende. Das ist verkehrt herum: Den
ersten ImagePullBackOff siehst du am ersten Tag, nicht in Woche vier.
Und im Beruf ist es die eigentliche Fähigkeit. Etwas zu bauen, das läuft, kann man nachschlagen. Herauszufinden, warum etwas nicht läuft, kann man nur üben.
Der Ablauf — immer derselbe
Vier Schritte, in dieser Reihenfolge. Nie eine Suchmaschine vor Schritt zwei.
kubectl get pods -o wide # 1. Welches Statuswort? Welcher Knoten?
kubectl describe pod <name> # 2. Die Events am Ende lesen
kubectl logs <name> # 3. Was sagt die Anwendung selbst?
kubectl exec -it <name> -- sh # 4. Nachsehen, wenn er wenigstens läuft
Der wichtigste Teil ist Schritt 2, und dort ausschließlich die Events-Liste ganz unten. Dort steht in fast allen Fällen die Antwort im Klartext — nur liest sie kaum jemand, weil vorher zwei Bildschirmseiten Objektbeschreibung stehen.
Fall 1: ImagePullBackOff
kubectl run kaputt1 --image=nginxx
kubectl describe pod kaputt1
Failed to pull image "nginxx": ... repository does not exist
or may require authentication
Bedeutung: Das Image lässt sich nicht holen. Drei Ursachen, in dieser Häufigkeit: Tippfehler im Namen, kein Netz zur Registry, fehlende Zugangsdaten für eine private Registry.
Zwischenstufe: Kurz vorher steht ErrImagePull. BackOff heißt, dass
Kubernetes es bereits mehrfach vergeblich versucht hat und die Abstände
verlängert.
Fall 2: CrashLoopBackOff
kubectl run kaputt2 --image=busybox -- /bin/false
kubectl get pods -w
Der Zähler RESTARTS steigt, und die Pausen zwischen den Versuchen werden
länger — 10 s, 20 s, 40 s, bis maximal 5 Minuten.
Bedeutung: Der Container startet erfolgreich und beendet sich dann. Das ist ein Anwendungsfehler, kein Kubernetes-Fehler. Typisch: fehlende Umgebungsvariable, Datenbank nicht erreichbar, Konfigurationsdatei nicht gefunden — oder schlicht ein Programm, das nach getaner Arbeit endet und deshalb gar kein Pod sein sollte, sondern ein Job.
Der entscheidende Befehl:
kubectl logs kaputt2 --previous
--previous zeigt die Ausgabe des bereits gestorbenen Durchlaufs. Ohne
diesen Schalter siehst du die Logs des gerade startenden Containers — meist
leer. Das ist der Grund, warum Leute stundenlang „keine Logs" melden,
obwohl die Ursache dort steht.
Fall 3: Pending
Ein Deployment mit einer Anforderung, die kein Knoten erfüllen kann:
resources:
requests:
memory: "64Gi"
kubectl describe pod <name>
0/2 nodes are available: 2 Insufficient memory.
Bedeutung: Der Scheduler hat keinen passenden Knoten gefunden — und er sagt in den Events präzise, woran es lag. Andere häufige Begründungen:
node(s) had untolerated taint→ Control Plane, siehe Folge 21node(s) didn't match Pod's node affinity/selector→ Label fehltpod has unbound immediate PersistentVolumeClaims→ Speicher fehlt
Pending ist deshalb kein Fehler, sondern eine Auskunft. Man muss sie
nur lesen.
Fall 4: Der gemeinste — Service ohne Endpoints
kubectl expose deployment web --port=80 --name=falsch --selector=app=gibtsnicht
kubectl get endpoints falsch
NAME ENDPOINTS
falsch <none>
Hier ist nichts kaputt. Die Pods laufen, der Service existiert, kein Pod meldet einen Fehler, in keinem Log steht etwas. Trotzdem antwortet niemand.
Der Selektor des Service passt auf kein einziges Pod-Label — und ein Service ohne passende Pods ist eine Adresse ins Leere.
Die zwei Befehle, die es aufklären:
kubectl get endpoints <service> # leer?
kubectl get pods --show-labels # welche Labels haben die Pods wirklich?
Zweite Variante desselben Falls: Die Labels passen, aber die Pods sind nicht
Ready — dann fallen sie ebenfalls aus der Liste. Siehe Folge 19 über Probes.
Die Reihenfolge, die Zeit spart
| Statuswort | Zuerst ansehen |
|---|---|
ImagePullBackOff |
Imagename buchstabieren, dann Registry-Zugang |
CrashLoopBackOff |
kubectl logs --previous |
Pending |
Events in describe — der Scheduler begründet sich |
Running, aber keine Antwort |
kubectl get endpoints, dann Labels |
ContainerCreating hängt |
Events — meist Netzwerk, Speicher oder Registry |
Aus dem eigenen Aufbau
Beim Einrichten dieses Labors hingen alle Pods auf ContainerCreating:
plugin type="cilium-cni" failed (add): failed to find plugin
"cilium-cni" in path [/usr/lib/cni]
Beide Knoten meldeten dabei fröhlich Ready — denn dafür genügt dem kubelet
eine CNI-Konfigurationsdatei, es prüft nicht, ob die Programme dazu
auffindbar sind. Die Wahrheit stand ausschließlich in den Events des Pods.
Merksatz: Ready heißt nicht funktioniert.
Zum Nachlesen
Eine geordnete Übersicht über die offizielle Dokumentation steht unter Nachlesen.
Befehle aus dieser Folge
kubectl get pods -o widekubectl describe pod <name>kubectl logs <name> --previouskubectl get events -A --sort-by=.lastTimestampkubectl get endpoints <service>kubectl exec -it <name> -- sh
Begriffe
- ImagePullBackOff
- das Image laesst sich nicht holen - Name, Netz oder Zugangsdaten
- CrashLoopBackOff
- der Container startet, stirbt, startet - mit wachsender Pause dazwischen
- Pending
- der Scheduler hat keinen passenden Knoten gefunden und sagt in den Events warum
- Events
- die Chronik am Ende von describe - dort steht fast immer die Antwort
- --previous
- zeigt die Logs des vorherigen, bereits gestorbenen Containers
Übung — mach es selbst
Bau alle vier Fehler selbst — absichtlich.
kubectl run kaputt1 --image=nginxx
kubectl run kaputt2 --image=busybox -- /bin/false
kubectl expose deployment web --port=80 --name=falsch --selector=app=gibtsnicht
Für den dritten Fall (Pending) ein Deployment mit einer Anforderung, die kein Knoten erfüllen kann — etwa 64 GB Speicher.
Zu jedem Fall beantworten, ohne im Internet zu suchen:
- Welches Statuswort steht bei
kubectl get pods? - Welche Zeile in den Events nennt die Ursache?
- Mit welchem einzigen Befehl haettest du es am schnellsten gefunden?
Danach alles wieder loeschen und die Zeit stoppen: Wie lange brauchst du beim zweiten Durchgang? Wer unter zwei Minuten je Fall kommt, hat den Ablauf verinnerlicht — und genau das ist im Beruf die Faehigkeit, die zaehlt.