Fehlerbehebung bei Kubernetes-Pod-Ausfällen: Ein umfassender Leitfaden
Navigieren Sie durch die Komplexität von Kubernetes-Pod-Ausfällen mit diesem umfassenden Leitfaden. Lernen Sie den strukturierten Prozess zur Diagnose häufiger Probleme wie CrashLoopBackOff, ImagePullBackOff und Ressourcenerschöpfung. Wir erläutern, wie Sie wichtige Tools wie `kubectl describe` und `kubectl logs --previous` nutzen, um die Ursache zu identifizieren, Container-Exit-Status zu interpretieren und praktische Lösungen zu implementieren, um eine zuverlässige Anwendungsverfügbarkeit und -stabilität zu gewährleisten.
Fehlerbehebung bei Kubernetes-Pod-Ausfällen: Ein umfassender Leitfaden
Die Fehlerbehebung bei Kubernetes-Pod-Ausfällen erfordert weniger das Auswendiglernen jedes Status, sondern vielmehr das Wissen, wo Kubernetes Hinweise hinterlässt. Ein Pod fällt fast nie „still" aus. Der Scheduler, die Kubelet, die Container-Laufzeitumgebung, die Image-Registry, das Volume-Plugin und Ihre Anwendung hinterlassen alle Spuren an verschiedenen Stellen. Der Trick besteht darin, sie in der richtigen Reihenfolge zu überprüfen, damit Sie nicht zwanzig Minuten damit verbringen, Anwendungslogs für einen Pod zu lesen, der sein Image nie gezogen hat.
Normalerweise beginne ich mit einer Frage: Ist der Pod fehlgeschlagen, bevor der Container gestartet wurde, während des Container-Starts oder nachdem die Anwendung zu laufen begann? Diese einzelne Unterscheidung hält die Untersuchung auf dem Boden. Pending deutet normalerweise auf Probleme bei der Planung, dem Speicher oder der Image-Einrichtung hin. ImagePullBackOff deutet auf den Registry-Pfad, das Tag, die Anmeldeinformationen oder den Node-Egress hin. CrashLoopBackOff bedeutet normalerweise, dass der Prozess startet und dann beendet wird, obwohl der Grund eine Konfiguration, eine fehlende Datei, ein fehlerhafter Befehl, eine fehlgeschlagene Abhängigkeit oder Speicherdruck sein kann.
Die drei Säulen der Pod-Diagnose
Die Fehlerbehebung beginnt mit der Verwendung von drei primären kubectl-Befehlen, um alle verfügbaren Informationen über den fehlgeschlagenen Pod zu sammeln.
1. Erste Statusprüfung (kubectl get pods)
Der erste Schritt besteht immer darin, den aktuellen Status des Pods und seiner Container zu ermitteln. Achten Sie besonders auf die Spalten STATUS und READY.
kubectl get pods -n my-namespace
Interpretation des Pod-Status
| Status | Bedeutung | Erste Maßnahme |
|---|---|---|
| Running | Mindestens ein Container läuft; dies bedeutet nicht immer, dass die App Traffic bedient. | Überprüfen Sie READY, Neustarts und Readiness-Ereignisse. |
| Pending | Pod wurde von Kubernetes akzeptiert, aber Container wurden noch nicht erstellt. | Überprüfen Sie Planungsereignisse oder den Image-Pull-Status. |
| CrashLoopBackOff | Container startet, stürzt ab und Kubelet versucht, ihn wiederholt neu zu starten. | Überprüfen Sie Anwendungslogs (kubectl logs --previous). |
| ImagePullBackOff | Kubelet kann das erforderliche Container-Image nicht ziehen. | Überprüfen Sie Image-Name, Tag und Registry-Anmeldeinformationen. |
| Error | Pod wurde aufgrund eines Laufzeitfehlers oder eines fehlgeschlagenen Startbefehls beendet. | Überprüfen Sie Logs und describe-Ereignisse. |
| Terminating/Unknown | Pod wird heruntergefahren oder der Kubelet-Host reagiert nicht. | Überprüfen Sie die Node-Gesundheit. |
2. Tiefgehende Inspektion (kubectl describe pod)
Wenn der Status etwas anderes als Running ist, liefert der describe-Befehl entscheidenden Kontext, der Planungsentscheidungen, Ressourcenzuweisungen und Container-Status detailliert beschreibt.
kubectl describe pod [POD_NAME] -n my-namespace
Konzentrieren Sie sich auf diese Abschnitte in der Ausgabe:
- Containers/Init Containers: Überprüfen Sie den
State(insbesondereWaitingoderTerminated) und denLast State(wo der Fehlergrund oft aufgezeichnet ist, z.B.Reason: OOMKilled). - Resource Limits: Stellen Sie sicher, dass
LimitsundRequestskorrekt gesetzt sind. - Events: Dies ist der kritischste Abschnitt. Ereignisse zeigen den Lebenszyklusverlauf, einschließlich Planungsfehlern, Volume-Mounting-Problemen und Image-Pull-Versuchen.
Tipp: Wenn der Abschnitt
Eventseine Meldung wie „0/N nodes available" anzeigt, kann der Pod wahrscheinlich aufgrund unzureichender Ressourcen (CPU, Speicher) oder nicht erfüllter Affinitätsregeln nicht geplant werden.
Lesen Sie Ereignisse von unten nach oben, wenn Sie den neuesten Hinweis möchten, aber ignorieren Sie ältere Ereignisse nicht. Ein Pod kann mehr als ein Problem haben. Beispielsweise kann ein Deployment mit FailedScheduling beginnen, weil der angeforderte Speicher zu hoch ist, und später nach dem Hinzufügen eines Nodes zu ImagePullBackOff wechseln. Wenn Sie nur den endgültigen Status betrachten, übersehen Sie möglicherweise die Änderung, die das Problem vorangebracht hat.
3. Überprüfung der Logs (kubectl logs)
Bei Laufzeitproblemen der Anwendung liefern Logs den Stacktrace oder Fehlermeldungen, die erklären, warum der Prozess beendet wurde.
# Aktuelle Container-Logs überprüfen
kubectl logs [POD_NAME] -n my-namespace
# Logs für einen bestimmten Container innerhalb des Pods überprüfen
kubectl logs [POD_NAME] -c [CONTAINER_NAME] -n my-namespace
# Entscheidend für CrashLoopBackOff: Logs des *vorherigen* fehlgeschlagenen Laufs überprüfen
kubectl logs [POD_NAME] --previous -n my-namespace
Wenn der Pod Sidecars hat, fügen Sie immer -c hinzu. Viele frustrierende Untersuchungen resultieren daraus, dass die Logs des gesunden Sidecars anstelle des fehlgeschlagenen Anwendungscontainers gelesen werden. Verwenden Sie bei Fehlern von Init-Containern ebenfalls den Init-Container-Namen mit -c:
kubectl logs [POD_NAME] -c [INIT_CONTAINER_NAME] -n my-namespace
Häufige Pod-Fehlerszenarien und Lösungen
Die meisten Pod-Fehler fallen in einige erkennbare Muster, die jeweils einen gezielten Diagnoseansatz erfordern.
Szenario 1: CrashLoopBackOff
Dies ist der häufigste Pod-Fehler. Er bedeutet, dass der Container erfolgreich startet, die Anwendung innerhalb des Containers jedoch sofort beendet wird (mit einem Exit-Code ungleich Null).
Diagnose:
- Verwenden Sie
kubectl logs --previous, um den Traceback oder den Exit-Grund anzuzeigen. - Verwenden Sie
kubectl describe, um denExit Codeim AbschnittLast Statezu überprüfen.
Häufige Ursachen und Lösungen:
- Exit-Code 1/2: Allgemeiner Anwendungsfehler, fehlende Konfigurationsdatei, Datenbankverbindungsfehler oder Anwendungsabsturz aufgrund fehlerhafter Eingabe.
- Lösung: Debuggen Sie den Anwendungscode oder überprüfen Sie die eingehängten ConfigMaps/Secrets.
- Fehlende Abhängigkeiten: Das Einstiegsskript benötigt Dateien oder Umgebungen, die nicht vorhanden sind.
- Lösung: Überprüfen Sie das Dockerfile und den Image-Build-Prozess.
- Falscher Befehl oder falsche Argumente: Das Container-Image ist gültig, aber der Befehl in der Pod-Spezifikation überschreibt den Image-Einstiegspunkt falsch.
- Lösung: Vergleichen Sie den Deployment-
commandund dieargsmit dem erwarteten Startbefehl des Images. Testen Sie dasselbe Image nach Möglichkeit lokal.
- Lösung: Vergleichen Sie den Deployment-
- Durch Probes ausgelöste Neustarts: Eine Liveness-Probe kann eine langsam startende App töten, bevor sie vollständig hochgefahren ist.
- Lösung: Erhöhen Sie
initialDelaySeconds, verwenden Sie einestartupProbeoder richten Sie die Probe auf einen günstigeren Health-Endpunkt.
- Lösung: Erhöhen Sie
Ein praktisches Muster besteht darin, eine temporäre Kopie mit demselben Image, aber einem harmlosen Befehl bereitzustellen und dann das Dateisystem und die Umgebung zu inspizieren:
kubectl run debug-image \
--image=registry.example.com/app:tag \
--restart=Never \
--command -- sleep 3600
kubectl exec -it debug-image -- /bin/sh
Dies ersetzt nicht die Behebung des Deployments, hilft aber, einfache Fragen schnell zu beantworten: Ist die Konfigurationsdatei tatsächlich im Image, existiert die Binärdatei, hat der Container die erwartete Shell und sind Umgebungsvariablen vorhanden?
Szenario 2: ImagePullBackOff / ErrImagePull
Dies tritt auf, wenn die Kubelet das in der Pod-Definition angegebene Container-Image nicht abrufen kann.
Diagnose:
- Überprüfen Sie den Abschnitt
Eventsvonkubectl describeauf die spezifische Fehlermeldung (z.B.404 Not Foundoderauthentication required).
Häufige Ursachen und Lösungen:
- Tippfehler oder falsches Tag: Der Image-Name oder das Tag ist falsch.
- Lösung: Korrigieren Sie den Image-Namen in der Deployment- oder Pod-Spezifikation.
- Zugriff auf private Registry: Der Cluster hat keine Anmeldeinformationen, um von einer privaten Registry (wie Docker Hub, GCR, ECR) zu ziehen.
- Lösung: Stellen Sie sicher, dass ein entsprechendes
imagePullSecretin der Pod-Spezifikation referenziert wird und dass das Secret im Namespace existiert.
- Lösung: Stellen Sie sicher, dass ein entsprechendes
# Beispiel-Pod-Spezifikationsausschnitt für die Verwendung eines Pull-Secrets
spec:
containers:
...
imagePullSecrets:
- name: my-registry-secret
Überprüfen Sie auch, wo das Pull-Secret lebt. Kubernetes-Secrets sind namespaced. Ein Secret namens regcred im default-Namespace hilft einem Pod im payments-Namespace nicht. Wenn dasselbe Image in einem Namespace funktioniert, in einem anderen jedoch fehlschlägt, vergleichen Sie Service Accounts und Image-Pull-Secrets, bevor Sie annehmen, dass die Registry defekt ist:
kubectl get serviceaccount default -n payments -o yaml
kubectl get secret regcred -n payments
Szenario 3: Pending-Status (Feststecken)
Ein Pod bleibt im Status Pending, was normalerweise darauf hindeutet, dass er nicht auf einen Node geplant werden kann oder auf Ressourcen (wie ein PersistentVolume) wartet.
Diagnose:
- Führen Sie
kubectl describeaus und sehen Sie sich den AbschnittEventsan.
Häufige Ursachen und Lösungen:
- Ressourcenerschöpfung: Dem Cluster fehlen Nodes mit ausreichend verfügbarer CPU oder Arbeitsspeicher, um die
requestsdes Pods zu erfüllen.- Lösung: Vergrößern Sie den Cluster oder reduzieren Sie die Pod-Ressourcenanforderungen (falls möglich).
- Beispiel für Ereignismeldung:
0/4 nodes are available: 4 Insufficient cpu.
- Volume-Bindungsprobleme: Der Pod benötigt einen
PersistentVolumeClaim(PVC), der nicht an ein zugrunde liegendesPersistentVolume(PV) gebunden werden kann.- Lösung: Überprüfen Sie den Status des PVC (
kubectl get pvc) und stellen Sie sicher, dass die StorageClass funktioniert.
- Lösung: Überprüfen Sie den Status des PVC (
- Selektor- oder Affinitätskonflikt: Der Pod fragt nach einem Node-Label, das nicht existiert, oder eine erforderliche Affinitätsregel schließt jeden Node aus.
- Lösung: Vergleichen Sie
nodeSelector,nodeAffinityund Node-Labels mitkubectl get nodes --show-labels.
- Lösung: Vergleichen Sie
- Taints nicht toleriert: Nodes sind verfügbar, aber sie stoßen diesen Pod ab, weil ihm eine passende Tolerierung fehlt.
- Lösung: Fügen Sie die beabsichtigte Tolerierung zum Pod hinzu oder entfernen Sie den Taint, wenn er keine echte Platzierungsregel mehr darstellt.
Szenario 4: OOMKilled (Wegen Speichermangels beendet)
Obwohl dies normalerweise zu einem CrashLoopBackOff-Status führt, ist die zugrunde liegende Ursache spezifisch: Der Container hat mehr Speicher verbraucht als das in seiner Spezifikation definierte Limit, was dazu führte, dass das Host-Betriebssystem (über die Kubelet) ihn zwangsweise beendet hat.
Diagnose:
- Überprüfen Sie
kubectl describe->Last State->Reason: OOMKilled.
Lösungen:
- Limits erhöhen: Erhöhen Sie das Speicher-
limitin der Pod-Spezifikation, um mehr Spielraum zu schaffen. - Anwendung optimieren: Profilieren Sie die Anwendung, um ihren Speicherverbrauch zu reduzieren.
- Requests setzen: Stellen Sie sicher, dass
requestsnahe am tatsächlichen stabilen Verbrauch liegen, um die Planungszuverlässigkeit zu verbessern.
resources:
limits:
memory: "512Mi" # Erhöhen Sie diesen Wert
requests:
memory: "256Mi"
Seien Sie vorsichtig mit Speicher-"Lösungen", die nur das Limit erhöhen. Wenn die Anwendung ein Leck hat, kann ein höheres Limit den nächsten Fehler nur verzögern und den Node einem größeren Risiko aussetzen. Betrachten Sie den Speicher im Laufe der Zeit in Ihrem Metriksystem. Ein Sägezahnmuster, das nach der Garbage Collection zur Baseline zurückkehrt, unterscheidet sich von einem stetigen Anstieg bis zum OOM.
Szenario 5: CreateContainerConfigError und CreateContainerError
Diese Status werden leicht übersehen, da sie nicht wie Anwendungsfehler klingen. Sie bedeuten normalerweise, dass die Kubelet die Container-Konfiguration nicht zusammenstellen konnte.
Häufige Ursachen sind:
- Ein referenzierter ConfigMap oder Secret existiert nicht im Namespace.
- Ein Schlüssel in einem ConfigMap oder Secret ist falsch geschrieben.
- Ein Volume-Mount-Pfad kollidiert mit einem anderen Mount.
- Der Container referenziert einen ungültigen Sicherheitskontext.
Der schnellste Check ist immer noch describe:
kubectl describe pod [POD_NAME] -n my-namespace
Achten Sie auf Ereignismeldungen wie secret "app-config" not found oder configmap "settings" not found. Überprüfen Sie dann das Objekt:
kubectl get secret app-config -n my-namespace
kubectl get configmap settings -n my-namespace -o yaml
Dies ist ein häufiger Fehler in Deployment-Pipelines. Das Anwendungsmanifest wird angewendet, aber der Schritt zur Secret-Erstellung ist fehlgeschlagen oder wurde gegen den falschen Namespace ausgeführt.
Szenario 6: Running but Not Ready
Ein Pod kann Running anzeigen, während er dennoch unbrauchbar ist. Die Spalte READY gibt an, wie viele Container gemäß ihrer Readiness-Probes bereit sind. Ein Pod mit 1/2 oder 0/1 kann zwar am Leben, aber von den Service-Endpunkten entfernt sein.
Überprüfen Sie Endpunkte, wenn Traffic ausfällt, aber Pods lebendig aussehen:
kubectl get endpoints [SERVICE_NAME] -n my-namespace
kubectl describe pod [POD_NAME] -n my-namespace
Wenn die Endpunktliste leer ist, liegt das Problem möglicherweise an einer Readiness-Probe, einem Service-Selektor-Konflikt oder daran, dass die Anwendung auf einem anderen Port lauscht, als der Service erwartet. In echten Vorfällen verlieren Leute hier Zeit: Sie starten Pods immer wieder neu, obwohl die Pods nicht der Grund für den fehlenden Traffic sind.
Vermeidung zukünftiger Fehler: Best Practices
Robuste Anwendungen erfordern eine sorgfältige Konfiguration, um häufige Deployment-Fallstricke zu vermeiden.
Verwenden Sie Liveness- und Readiness-Probes
Die ordnungsgemäße Implementierung von Probes ermöglicht es Kubernetes, die Container-Gesundheit intelligent zu verwalten:
- Liveness-Probes: Stellen fest, ob der Container gesund genug ist, um weiterzulaufen. Wenn die Liveness-Probe fehlschlägt, startet Kubelet den Container neu (Behebung von Softlocks).
- Readiness-Probes: Stellen fest, ob der Container bereit ist, Traffic zu bedienen. Wenn die Readiness-Probe fehlschlägt, wird der Pod aus den Service-Endpunkten entfernt, wodurch fehlgeschlagene Anfragen vermieden werden, während sich der Container erholt.
Richten Sie Liveness-Probes nicht auf tiefe Abhängigkeitsprüfungen, es sei denn, Sie möchten wirklich, dass Kubernetes den Container jedes Mal neu startet, wenn diese Abhängigkeit einen kurzen Ausfall hat. Eine Datenbank, die für dreißig Sekunden nicht verfügbar ist, ist normalerweise kein Beweis dafür, dass der Prozess tot ist. Readiness ist der bessere Ort, um zu sagen: „Senden Sie diesem Pod jetzt keinen Traffic."
Erzwingen Sie Ressourcenlimits und -anforderungen
Definieren Sie immer Ressourcenanforderungen für Container. Dies verhindert, dass Pods übermäßige Ressourcen verbrauchen (was zu Node-Instabilität führt) und stellt sicher, dass der Scheduler den Pod auf einem Node mit ausreichender Kapazität platzieren kann.
Verwenden Sie Init-Container für die Einrichtung
Wenn ein Pod eine Abhängigkeitsprüfung oder Dateneinrichtung benötigt, bevor die Hauptanwendung startet (z.B. Warten auf den Abschluss einer Datenbankmigration), verwenden Sie einen Init-Container. Wenn der Init-Container fehlschlägt, startet der Pod ihn wiederholt neu, wodurch Einrichtungsfehler sauber von Anwendungslaufzeitfehlern isoliert werden.
Ein praktischer Triage-Ablauf
Wenn Sie Bereitschaftsdienst haben, verwenden Sie einen wiederholbaren Pfad:
- Überprüfen Sie
kubectl get pods -n <namespace> -o wide, um Status, Neustarts, Alter und Node-Platzierung zu sehen. - Führen Sie
kubectl describe podaus und lesen Sie Events, State, Last State, Mounts und Ressourceneinstellungen. - Ziehen Sie Logs mit
kubectl logs, fügen Sie--previousfür neu gestartete Container und-cfür Multi-Container-Pods hinzu. - Wenn der Pod
Pendingist, inspizieren Sie Planung, Taints, Node-Labels und PVCs, bevor Sie App-Logs lesen. - Wenn der Pod
Runningist, aber keinen Traffic erhält, inspizieren Sie Readiness-Probes, Service-Selektoren und Endpunkte. - Wenn der Pod OOMKilled wurde, vergleichen Sie Limits mit tatsächlichen Speicherdiagrammen, bevor Sie die Zahl einfach erhöhen.
Diese Reihenfolge verhindert, dass Sie direkt zur Anwendung springen, wenn Kubernetes sie noch nicht einmal gestartet hat.
Abschließende Überprüfung
Die nützlichste Gewohnheit ist, Symptome von Ursachen zu trennen. CrashLoopBackOff ist ein Symptom. Die Ursache könnte ein fehlendes Secret, eine fehlerhafte Migration, eine Liveness-Probe oder ein Speicherlimit sein. Pending ist ein Symptom. Die Ursache könnte CPU-Anforderungen, ein PVC, ein Taint oder ein Node-Selektor sein. Lassen Sie sich vom Pod-Status sagen, wo Sie suchen sollen, und dann lassen Sie Ereignisse und Logs sagen, was sich geändert hat.