Das ist die Checkliste, die ich im Kopf hervorhole, wenn etwas kaputtgeht. Sie ist keine Garantie. Sie ist eine Reihenfolge, die mich davon abhält, den Ausfall schlimmer zu machen, während ich herausfinde, was wirklich los ist.

Foto von Luis Gomes auf Pexels
Die eigene Umgebung braucht andere Befehle und andere Dashboards. Diese Liste ist ein Ausgangspunkt, den man für die eigenen Cluster, Namespaces und den eigenen Bereitschaftsdienst anpasst.
Bevor etwas bricht: Rollback ermöglichen
Vorfälle sind leichter zu handhaben, wenn man an einem ruhigen Dienstag vorbereitet hat.
- Wissen, wie man den letzten Deploy rückgängig macht (
kubectl rollout undo, Argo-CD-Revert, Helm-Rollback). - Vorherige Image-Tags und Chart-Versionen erreichbar halten.
- Ein Dashboard pro kritischem Service, das im Bereitschaftsdienst wirklich geöffnet wird.
- Drei Runbooks für die drei häufigsten Fehlermodi schreiben — nicht fünfzig.
Wenn man nicht zurückrollen kann, schrumpfen die Optionen im Vorfall auf „unter Druck nach vorn reparieren“. Das kann funktionieren. So will ich um zwei Uhr nachts aber nicht dastehen.
Die ersten Minuten — zuerst Ruhe schaffen
- Symptom bestätigen — wer ist betroffen, seit wann, vollständig oder teilweise?
- Riskante Änderungen pausieren — Deploys einfrieren, GitOps-Auto-Sync anhalten, unnötige Pipeline-Läufe stoppen, wenn möglich.
- Rollen benennen — Incident Lead, Protokoll, Kommunikation. In kleinen Teams kann eine Person zwei Rollen übernehmen, aber man sollte sie laut benennen.
- Letzte Änderung klären — was ging in der letzten Stunde live? Was am letzten Tag? Korrelation ist nicht Kausalität, aber ein guter erster Verdacht.
- Control Plane prüfen — antwortet die API? Sind viele Nodes
NotReady? Ist etcd gesund, falls man es selbst betreibt?
Die Startzeit im Incident-Channel notieren. Das zukünftige Ich wird sie brauchen.
Stabilisieren — Zeit gewinnen ohne wahlloses Löschen
Ziel: nichts verschlimmern, den Service sicher wiederherstellen, wenn das möglich ist, und Hinweise erhalten.
# Cluster / node health
kubectl get nodes -o wide
kubectl get componentstatuses 2>/dev/null || true
# Pods not in Running phase (!= is valid for field selectors; quote for the shell)
kubectl get pods -A --field-selector='status.phase!=Running'
# Note: includes Pending, Failed, Succeeded, Unknown — filter out completed Jobs if noisy
# Recent events — often the fastest clue
kubectl get events -A --sort-by='.lastTimestamp' | tail -30
# If one namespace is in scope
kubectl get deploy,sts,ds -n <namespace>
kubectl rollout history deployment/<name> -n <namespace>
Dann einen Weg zur Eindämmung wählen und im Channel ankündigen, bevor man ihn ausführt:
- Last — horizontal skalieren, wenn die Anwendung gesund, aber gesättigt ist; zuerst HPA-Grenzen und Node-Kapazität prüfen.
- Schlechte Revision — Traffic weglenken oder
kubectl rollout undo, wenn die Zeitachse passt. - Abhängigkeit ausgefallen — Circuit Breaker, Feature Flag, Wartungsseite; was die Anwendung eben unterstützt.
- Unbekannt — Auswirkungsbereich verkleinern, etwa nur bei einem unkritischen Service auf null skalieren und nur, wenn die Beteiligten zustimmen.
Notieren, was zurückgerollt wurde — Deployment-Revision, Image-Tag, Git-Commit, Helm-Release-Version. Nach dreißig Minuten wird die Erinnerung unscharf.
Was ich beim Stabilisieren zu vermeiden versuche
- Namespaces löschen, um Dinge zu „reparieren“.
- etcd oder Control-Plane-Komponenten neu starten, weil jemand es auf Slack vorgeschlagen hat.
- Fünf zusammenhanglose YAML-Dateien anwenden, weil eine davon vielleicht hilft.
Langsam diagnostizieren — eine Hypothese nach der anderen
Stabilisieren heißt nicht, dass man die Ursache verstanden hat. Nach der Eindämmung: Tempo herausnehmen.
| Wenn ich sehe … | schaue ich meist auf … | Befehle / Hinweise |
|---|---|---|
| CrashLoopBackOff | Exit-Grund, Probes, Limits, Image Pull, Konfiguration | kubectl logs --previous, describe pod, letzter Deploy |
| Pending | Scheduling, Quotas, Affinity, PVC-Binding, Kapazität | describe pod Events-Abschnitt; get pvc; Node-Ressourcen |
| Running, aber Fehler | Anwendungslogs, Ingress/Route, Timeouts bei Abhängigkeiten | Fehlerrate mit Deploy-Zeit vergleichen; eine fehlschlagende Anfrage nachverfolgen |
| Latenzspitze | Letzte Änderung, DB, DNS, CNI, Sättigung | CPU und Speicher von Node und Pod; Dashboards der Abhängigkeiten |
| Intermittierend | Ein einzelner schlechter Pod, Node, eine Zone oder ein Client-Pfad | Verteilung der Replicas über Nodes; Korrelation mit einer AZ |
# CrashLoop — why did the last container exit?
kubectl logs <pod> -n <ns> --previous
kubectl describe pod <pod> -n <ns> | sed -n '/Events:/,$p'
# Pending — why not scheduled?
kubectl describe pod <pod> -n <ns> | grep -A2 "Conditions:"
# Service / ingress path (vanilla k8s)
kubectl get svc,ingress -n <ns>
kubectl get endpoints -n <ns>
Eine Regel, die ich aus der Luftfahrt übernommen habe: eine Variable ändern, beobachten, dann entscheiden. Wer in denselben fünf Minuten neu startet, skaliert und deployt, weiß danach nicht, welche Aktion geholfen hat.
Beobachtbarkeit — dem Dashboard trauen, aber prüfen
Das Dashboard öffnen, auf das sich das Team geeinigt hat. Nicht zwölf Tabs.
- Fehlerrate und Latenz im Vergleich zu einem Ausgangswert, dem man vertraut.
- Sättigung (CPU, Speicher, Verbindungen, Thread Pools).
- Marker für den letzten Deploy auf derselben Zeitachse.
- Bei Canary oder progressivem Rollout: Metriken nach Versions-Label trennen, wenn vorhanden.
Wenn Metriken gut aussehen, Nutzer aber wütend sind: den Nutzern glauben und Sampling, Auth-Pfade oder eine einzelne Region prüfen.
OpenShift-Details, die ich mit reinen Kubernetes-Gewohnheiten vergesse
Wenn das Symptom auf OpenShift vage ist:
oc get clusteroperators— sind Plattform-Operatoren degraded?- Routes vs. Ingress — TLS am Edge, falscher Zielport?
- Image-Pull-Secrets und Erreichbarkeit der internen Registry.
- SCC-Verweigerungen — manchmal spät in Events sichtbar.
Die Denkweise ist dieselbe wie bei Kubernetes. Die Objekte sind andere.
Kommunikation — langweilige Updates sind besser als Stille
Alle zwanzig bis dreißig Minuten, bis der Vorfall gelöst ist:
- Auswirkung (wer ist betroffen, welcher Workaround existiert).
- Aktuelle Theorie (ein Satz).
- Nächster Schritt und Zeitpunkt des nächsten Updates.
„Wir untersuchen noch“ ist einmal in Ordnung. Wiederholt ohne neue Fakten untergräbt es Vertrauen.
Wenn es wieder grün ist — den Kreis schließen
Kurze Nachbesprechung innerhalb weniger Tage, solange die Erinnerung frisch ist:
- Zeitachse mit Befehlen und Entscheidungen aus den Protokollnotizen.
- Ursache oder „unbekannt, aber eingedämmt“.
- Eine Folgeaufgabe mit verantwortlicher Person und Datum: Runbook aktualisieren, Alarm verbessern, Deploy-Absicherung ergänzen.
Das Runbook aktualisieren, solange die Details noch frisch sind. Ein Runbook, das nur im Kopf existiert, ist ein Single Point of Failure.
Was diese Checkliste nicht löst
Sie repariert keine kaputte Architektur, keine fehlende Kapazitätsplanung und keine Alarme, die bei allem feuern. Sie ersetzt kein Team, das Rollback nie geübt hat.
Sie gibt mir einen Startpunkt, wenn das Adrenalin hoch ist — aus demselben Grund, aus dem Piloten Checklisten nutzen, bei gutem Wetter und bei schlechtem.
Wer das für die eigene Organisation anpasst, sollte die Abschnitte behalten, die zur tatsächlichen Arbeitsweise passen, und den Rest streichen. Eine kürzere Checkliste, die man nutzt, ist besser als eine lange, die man überspringt.