Veröffentlicht am

Kubernetes Incident Management: Runbooks erstellen

Teilen:
Authors

TL;DR

Kubernetes-Runbooks dokumentieren für jedes Incident-Szenario die exakten Debugging-Schritte und Lösungswege. Ein gutes Runbook enthält Symptom-Erkennung, Diagnose-Befehle und Eskalationspfade. Die häufigsten Szenarien (CrashLoopBackOff, OOMKilled, Node NotReady) lassen sich mit standardisierten Runbooks in unter 10 Minuten lösen.

Warum Runbooks?

Ohne Runbooks hängt die Incident-Reaktion vom Wissen einzelner Personen ab. Nachts um 3 Uhr erinnert sich niemand an den richtigen kubectl-Befehl. Runbooks lösen dieses Problem:

# Typische Situation ohne Runbook:
# Alert: "Pod CrashLoopBackOff in production"
# On-Call: "Was war nochmal der Befehl...?"

# Mit Runbook - sofort handlungsfähig:
kubectl get pods -n production | grep CrashLoop
kubectl logs <pod-name> -n production --previous
kubectl describe pod <pod-name> -n production | grep -A5 "Last State"

Runbooks reduzieren die Mean Time to Resolution (MTTR) drastisch. Teams mit dokumentierten Runbooks lösen Incidents im Schnitt 60% schneller.

Runbook-Template

Jedes Runbook folgt der gleichen Struktur. Hier das Basis-Template:

# runbook-template.yaml
name: "<Incident-Titel>"
severity: "P1|P2|P3|P4"
alert_source: "Prometheus Rule / PagerDuty Service"
symptoms:
  - "Beschreibung der sichtbaren Symptome"
  - "Relevante Metriken oder Logs"

diagnosis:
  steps:
    - command: "kubectl get pods -n <namespace>"
      expect: "Pods im Fehlerzustand identifizieren"
    - command: "kubectl describe pod <pod> -n <namespace>"
      expect: "Events und Conditions prüfen"
    - command: "kubectl logs <pod> -n <namespace> --previous"
      expect: "Fehlerursache in Logs finden"

resolution:
  automatic:
    - "Beschreibung automatischer Fixes"
  manual:
    - "Schritt-für-Schritt Anleitung"

escalation:
  timeout: "15 Minuten ohne Fortschritt"
  contact: "Platform Team Lead / Slack #k8s-incidents"

CrashLoopBackOff Runbook

Das häufigste Incident in Kubernetes-Clustern. Der Pod startet, crasht und wird endlos neu gestartet.

Diagnose:

# 1. Betroffene Pods identifizieren
kubectl get pods -A --field-selector status.phase!=Running | grep CrashLoop

# 2. Restart-Count und Exit-Code prüfen
kubectl get pod <pod> -n <ns> -o jsonpath='{.status.containerStatuses[0].lastState.terminated}'

# 3. Logs des letzten Laufs anzeigen
kubectl logs <pod> -n <ns> --previous --tail=50

# 4. Events prüfen (Image Pull Fehler, Resource Limits)
kubectl describe pod <pod> -n <ns> | tail -20
Exit-CodeBedeutungTypische Ursache
1Application ErrorFehlende Config, DB nicht erreichbar
137SIGKILL (OOMKilled)Memory Limit zu niedrig
139SIGSEGVSegfault in der Anwendung
143SIGTERMGraceful Shutdown fehlgeschlagen

Lösung: Bei Exit-Code 1 die Anwendungs-Logs prüfen. Bei 137 die Memory Limits erhöhen. Bei 139 ein Ticket für das Entwicklerteam erstellen.

OOMKilled Runbook

Der Container überschreitet sein Memory Limit und wird vom Kernel gekillt.

# 1. OOMKilled Pods finden
kubectl get pods -A -o json | jq -r '
  .items[] | select(.status.containerStatuses[]?.lastState.terminated.reason == "OOMKilled") |
  "\(.metadata.namespace)/\(.metadata.name)"'

# 2. Aktuellen Memory-Verbrauch prüfen
kubectl top pod <pod> -n <ns>

# 3. Memory Limits anzeigen
kubectl get pod <pod> -n <ns> -o jsonpath='{.spec.containers[0].resources}'

# 4. Fix: Limits anpassen (Deployment patchen)
kubectl patch deployment <deploy> -n <ns> --type=json \
  -p='[{"op":"replace","path":"/spec/template/spec/containers/0/resources/limits/memory","value":"512Mi"}]'

Faustregel: Das Memory Limit sollte 20-30% über dem normalen Verbrauch liegen. Prometheus-Query für den tatsächlichen Verbrauch: container_memory_working_set_bytes{pod="<pod>"}.

Node NotReady Runbook

Ein Node meldet sich nicht mehr beim API-Server. Alle Pods auf diesem Node sind betroffen.

Diagnose:

# 1. NotReady Nodes finden
kubectl get nodes | grep NotReady

# 2. Node-Conditions prüfen
kubectl describe node <node> | grep -A10 "Conditions"

# 3. Kubelet-Status auf dem Node prüfen (SSH nötig)
ssh <node> "sudo systemctl status kubelet"
ssh <node> "sudo journalctl -u kubelet --since '10 minutes ago' | tail -30"

# 4. Disk Pressure / Memory Pressure prüfen
kubectl describe node <node> | grep -E "DiskPressure|MemoryPressure|PIDPressure"

Häufigste Ursachen: volle Disk (Container-Images, Logs), kubelet-Crash, oder Netzwerkprobleme zum API-Server. Bei Disk Pressure helfen docker system prune bzw. crictl rmi --prune für ungenutzte Images.

Zertifikats-Ablauf Runbook

Kubernetes-Zertifikate laufen nach einem Jahr ab. Ohne Erneuerung fällt der gesamte Cluster aus.

# Ablaufdaten aller Zertifikate prüfen
sudo kubeadm certs check-expiration

# Alle Zertifikate erneuern
sudo kubeadm certs renew all

# kubelet neu starten
sudo systemctl restart kubelet

Best Practice: Ein CronJob oder Monitoring-Alert warnt 30 Tage vor Ablauf.

Alerting-Integration

Runbooks sind nur nützlich, wenn Alerts direkt auf sie verlinken. In PagerDuty oder OpsGenie kann jeder Alert-Service eine Runbook-URL enthalten:

ToolRunbook-FeldFormat
PagerDutyService > Integrations > Runbook URLHTTPS Link
OpsGenieAlert Policy > Details > RunbookHTTPS Link
Prometheusannotations.runbook_urlIn AlertRule

In Prometheus-Alerting-Rules sieht das so aus:

groups:
  - name: kubernetes-pods
    rules:
      - alert: PodCrashLooping
        expr: rate(kube_pod_container_status_restarts_total[15m]) > 0
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Pod {{ $labels.pod }} crasht wiederholt"
          runbook_url: "https://wiki.intern/runbooks/crashloopbackoff"

FAQ

Wo sollten Runbooks gespeichert werden?

Im gleichen Git-Repository wie die Infrastruktur-Definitionen. So werden Runbooks bei Infrastruktur-Änderungen mitaktualisiert. Markdown-Dateien in einem /runbooks-Verzeichnis funktionieren gut.

Wie detailliert sollten Runbooks sein?

So detailliert, dass ein Junior-Engineer nachts um 3 Uhr ohne Hilfe das Incident lösen kann. Jeder Schritt braucht einen konkreten Befehl, keine vagen Beschreibungen wie "prüfe die Logs".

Wer schreibt und pflegt die Runbooks?

Das Team, das On-Call-Dienst hat. Nach jedem Incident ohne passendes Runbook wird ein neues erstellt. Nach jedem Incident mit veraltetem Runbook wird es aktualisiert. Das gehört zur Incident-Retrospektive.

Wie teste ich ob Runbooks funktionieren?

Game Days: geplante Ausfälle in Staging-Umgebungen simulieren. Das Team arbeitet ausschließlich mit Runbooks. Lücken und veraltete Befehle werden sofort sichtbar.

Sollten Runbooks automatisiert werden?

Ja, schrittweise. Häufige Incidents wie OOMKilled können mit Kubernetes Operators oder Scripts teilautomatisiert werden. Aber: die manuelle Version muss als Fallback immer dokumentiert bleiben.

Kubernetes ohne DevOps-Overhead?

Wir betreiben Ihre Kubernetes-Cluster 24/7 – Sie fokussieren auf Ihr Kerngeschäft. Ab 4.000€/Monat, DSGVO-konform, mit deutschem Support.

24/7 SupportDeutsche RechenzentrenDSGVO-konform

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen