Warum Incident Management zählt
Jedes produktive System wird irgendwann ausfallen. Der Unterschied zwischen High-Performing-Organisationen und dem Rest besteht nicht darin, ob Incidents passieren – sondern darin, wie sie reagieren, wenn sie auftreten.
Google's Site-Reliability-Engineering-Praktiken sind zum Industriestandard für das Management von Zuverlässigkeit im großen Maßstab geworden. Aber Sie brauchen keine Google-Infrastruktur, um von SRE-Prinzipien zu profitieren. Auch kleine Teams können ihre Incident Response dramatisch verbessern, indem sie strukturierte Praktiken rund um Alerting, Eskalation, Kommunikation und das Lernen aus Fehlern einführen.
Schritt 1: SLOs definieren, bevor Sie Alerts definieren
Der größte Fehler, den Teams machen, ist, auf Metriken zu alarmieren, ohne sie mit Nutzerauswirkungen zu verknüpfen. Ihr Monitoring sollte durch Service Level Objectives (SLOs) getrieben sein, nicht durch willkürliche Schwellwerte.
Beginnen Sie damit zu definieren, was Ihren Nutzern wichtig ist:
# slo-definition.yaml
service: checkout-api
slos:
- name: availability
description: "Checkout API returns successful responses"
target: 99.95%
window: 30d
sli:
type: ratio
good: 'http_requests_total{status=~"2..|3.."}'
total: 'http_requests_total'
- name: latency
description: "Checkout completes within acceptable time"
target: 99.0%
window: 30d
sli:
type: ratio
good: 'http_request_duration_seconds_bucket{le="0.5"}'
total: 'http_request_duration_seconds_count'
Mit definierten SLOs können Sie Ihr Error Budget berechnen – das Maß an Unzuverlässigkeit, das Sie tolerieren können. Ein Verfügbarkeits-Target von 99,95 % gibt Ihnen etwa 21,6 Minuten Downtime pro Monat. Wenn Ihr Error Budget schneller verbrannt wird als erwartet, ist das der Zeitpunkt, zu dem Sie alarmieren.
Error-Budget-Alerts mit Prometheus umsetzen
Verwenden Sie Multi-Window-/Multi-Burn-Rate-Alerting, wie es im Google-SRE-Buch empfohlen wird:
# prometheus-rules.yaml
groups:
- name: slo-alerts
rules:
# Fast burn: 14.4x burn rate over 1 hour (fires within 1h)
- alert: CheckoutHighErrorBudgetBurn
expr: |
(
sum(rate(http_requests_total{service="checkout",status=~"5.."}[1h]))
/
sum(rate(http_requests_total{service="checkout"}[1h]))
) > (14.4 * 0.0005)
and
(
sum(rate(http_requests_total{service="checkout",status=~"5.."}[5m]))
/
sum(rate(http_requests_total{service="checkout"}[5m]))
) > (14.4 * 0.0005)
for: 2m
labels:
severity: critical
team: checkout
annotations:
summary: "Checkout API burning error budget 14.4x faster than normal"
runbook: "https://wiki.internal/runbooks/checkout-high-error-rate"
dashboard: "https://grafana.internal/d/checkout-slo"
# Slow burn: 3x burn rate over 3 days (catches gradual degradation)
- alert: CheckoutSlowErrorBudgetBurn
expr: |
(
sum(rate(http_requests_total{service="checkout",status=~"5.."}[3d]))
/
sum(rate(http_requests_total{service="checkout"}[3d]))
) > (3 * 0.0005)
for: 1h
labels:
severity: warning
team: checkout
annotations:
summary: "Checkout API slowly burning through error budget"
Dieser Ansatz eliminiert laute Alerts, die keine tatsächlichen Nutzerauswirkungen widerspiegeln. Sie pagen Menschen nur, wenn der Service sein Versprechen gegenüber den Nutzern verletzt.
Schritt 2: Eine On-Call-Rotation aufbauen, die niemanden ausbrennt
On-Call sollte nachhaltig sein. Teams, die ihre On-Call-Engineers ausbrennen, ernten hohe Fluktuation, niedrige Moral und – ironischerweise – schlechtere Zuverlässigkeit. Befolgen Sie diese Prinzipien:
- Mindestens zwei Personen pro Rotation – Primary und Secondary, damit niemand die Last allein trägt
- Regelmäßige Rotations-Kadenz – Wöchentliche Rotationen sind Standard; mehr als zwei Wochen führen zu Erschöpfung
- On-Call-Zeit vergüten – Durch Zusatzlohn, Freizeit oder beides
- Maximale Interrupt-Frequenz – Wird ein Team mehr als zweimal pro On-Call-Schicht gepaged, investieren Sie in Reliability-Verbesserungen, bevor Sie weitere Features hinzufügen
Hier ein PagerDuty-Schedule, konfiguriert über Terraform:
# pagerduty.tf
resource "pagerduty_schedule" "checkout_oncall" {
name = "Checkout Team On-Call"
time_zone = "America/New_York"
layer {
name = "Primary"
start = "2025-01-01T00:00:00-05:00"
rotation_virtual_start = "2025-01-01T00:00:00-05:00"
rotation_turn_length_seconds = 604800 # 1 week
users = [
pagerduty_user.alice.id,
pagerduty_user.bob.id,
pagerduty_user.carol.id,
pagerduty_user.dave.id,
]
}
layer {
name = "Secondary"
start = "2025-01-01T00:00:00-05:00"
rotation_virtual_start = "2025-01-08T00:00:00-05:00"
rotation_turn_length_seconds = 604800
users = [
pagerduty_user.alice.id,
pagerduty_user.bob.id,
pagerduty_user.carol.id,
pagerduty_user.dave.id,
]
}
}
resource "pagerduty_escalation_policy" "checkout" {
name = "Checkout Escalation"
num_loops = 2
rule {
escalation_delay_in_minutes = 10
target {
type = "schedule_reference"
id = pagerduty_schedule.checkout_oncall.id
}
}
rule {
escalation_delay_in_minutes = 15
target {
type = "user_reference"
id = pagerduty_user.engineering_manager.id
}
}
}
Schritt 3: Ein Incident-Response-Framework etablieren
Wenn ein Incident auftritt, ist Chaos der Feind. Definieren Sie klare Rollen und einen strukturierten Prozess, bevor Sie ihn brauchen.
Incident-Schweregrade
| Severity | Definition | Reaktionszeit | Kommunikation |
|---|---|---|---|
| SEV-1 | Service vollständig down, alle Nutzer betroffen | 5 Minuten | War Room, Status Page, Exec-Benachrichtigung |
| SEV-2 | Wichtiges Feature degradiert, signifikante Nutzerauswirkung | 15 Minuten | War Room, Status Page |
| SEV-3 | Leichte Degradation, begrenzte Nutzerauswirkung | 30 Minuten | Benachrichtigung im Team-Channel |
| SEV-4 | Keine Nutzerauswirkung, potenzielles zukünftiges Problem | Nächster Arbeitstag | Ticket erstellt |
Incident-Rollen
Jeder SEV-1- oder SEV-2-Incident sollte diese Rollen explizit zugewiesen bekommen:
- Incident Commander (IC) – Koordiniert die Response, trifft Entscheidungen, treibt die Lösung voran
- Technical Lead – Diagnostiziert die Root Cause, setzt Fixes um
- Communications Lead – Informiert Stakeholder, Status Page und Kunden
- Scribe – Dokumentiert Timeline, Maßnahmen und wichtige Entscheidungen
Automatisierte Incident-Erstellung mit Slack und PagerDuty
Verwenden Sie einen Bot, um die Incident-Erstellung zu standardisieren. Hier ein vereinfachter Incident-Bot in Python:
# incident_bot.py
import slack_sdk
import requests
from datetime import datetime
class IncidentManager:
def __init__(self, slack_token, pagerduty_token):
self.slack = slack_sdk.WebClient(token=slack_token)
self.pd_token = pagerduty_token
def declare_incident(self, severity, title, reporter):
# Create dedicated incident channel
timestamp = datetime.now().strftime("%Y%m%d-%H%M")
channel_name = f"inc-{timestamp}-{severity}"
channel = self.slack.conversations_create(
name=channel_name,
is_private=False
)
channel_id = channel["channel"]["id"]
# Post incident template
self.slack.chat_postMessage(
channel=channel_id,
blocks=[
{
"type": "header",
"text": {"type": "plain_text", "text": f"🚨 {severity.upper()}: {title}"}
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": f"*Reporter:* {reporter}"},
{"type": "mrkdwn", "text": f"*Status:* Investigating"},
{"type": "mrkdwn", "text": f"*IC:* Unassigned"},
{"type": "mrkdwn", "text": f"*Started:* {datetime.now().isoformat()}"},
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": (
"*Checklist:*\n"
"☐ Assign Incident Commander\n"
"☐ Assess user impact\n"
"☐ Update status page\n"
"☐ Identify mitigation steps\n"
"☐ Implement fix or rollback\n"
"☐ Verify resolution\n"
"☐ Schedule postmortem"
)
}
}
]
)
# Trigger PagerDuty if SEV-1 or SEV-2
if severity in ("sev-1", "sev-2"):
self._trigger_pagerduty(title, severity, channel_name)
return channel_id
def _trigger_pagerduty(self, title, severity, channel):
requests.post(
"https://events.pagerduty.com/v2/enqueue",
json={
"routing_key": "YOUR_INTEGRATION_KEY",
"event_action": "trigger",
"payload": {
"summary": f"[{severity.upper()}] {title}",
"severity": "critical" if severity == "sev-1" else "error",
"source": f"slack/{channel}",
}
}
)
Schritt 4: Blameless Postmortems verfassen
Im Postmortem findet organisatorisches Lernen statt. Ohne ihn sind Sie dazu verdammt, dieselben Fehler zu wiederholen. Das Schlüsselwort lautet blameless – konzentrieren Sie sich auf Systeme und Prozesse, nicht auf Einzelpersonen.
Jedes Postmortem sollte Folgendes abdecken:
Postmortem-Template
## Incident Summary
- **Date:** 2025-12-15
- **Duration:** 47 minutes
- **Severity:** SEV-2
- **Impact:** 12% of checkout requests failed for users in EU region
## Timeline (UTC)
- 14:23 — Monitoring detects elevated 5xx rate on checkout-api-eu
- 14:25 — PagerDuty pages on-call engineer (Alice)
- 14:28 — Alice joins incident channel, assumes IC role
- 14:35 — Root cause identified: database connection pool exhausted
- 14:42 — Mitigation applied: increased pool size via config change
- 14:50 — Error rates return to normal
- 15:10 — Incident resolved, monitoring confirmed stable
## Root Cause
A background migration job was opened without connection limits,
consuming all available database connections in the EU region pool.
## Contributing Factors
1. Migration jobs share the same connection pool as production traffic
2. No connection limit enforced on batch operations
3. Connection pool exhaustion alert had a 15-minute delay
## Action Items
| Action | Owner | Priority | Due Date |
|--------|-------|----------|----------|
| Separate connection pool for batch jobs | Bob | P1 | 2025-12-22 |
| Add connection pool utilization alert | Carol | P1 | 2025-12-20 |
| Document migration runbook | Alice | P2 | 2026-01-05 |
| Load test batch operations | Dave | P2 | 2026-01-10 |
## Lessons Learned
- **What went well:** Fast detection (2 min), clear escalation, mitigation applied quickly
- **What could improve:** Batch jobs need resource isolation, need better pre-migration checklist
Planen Sie das Postmortem-Review innerhalb von 48 Stunden nach dem Incident, solange die Details noch frisch sind. Machen Sie die Teilnahme für das Team verpflichtend und für den Rest der Organisation optional. Veröffentlichen Sie das Postmortem breit – Transparenz schafft Vertrauen und verhindert Wiederholungsfehler.
Schritt 5: Messen und über Zeit verbessern
Tracken Sie diese Incident-Management-Metriken monatlich:
- MTTD (Mean Time to Detect) – Wie schnell Sie Probleme bemerken
- MTTA (Mean Time to Acknowledge) – Wie schnell jemand auf einen Page reagiert
- MTTR (Mean Time to Resolve) – Gesamtzeit von der Erkennung bis zur Lösung
- Incident-Häufigkeit nach Severity – Tendenz nach oben oder unten?
- Abschlussrate von Postmortem-Action-Items – Lernen Sie wirklich?
- Alert-Noise-Ratio – Anteil der Alerts, die keine menschliche Aktion erforderten
Bauen Sie ein Grafana-Dashboard, das diese Metriken über die Zeit verfolgt. Wenn sich MTTR nicht quartalsweise verbessert, verdient Ihr Postmortem-Prozess Aufmerksamkeit.
Tools, die wir empfehlen
- Alerting und On-Call: PagerDuty, Opsgenie oder Grafana OnCall
- Incident-Koordination: Slack mit Rootly, incident.io oder FireHydrant
- Status Pages: Atlassian Statuspage, Instatus oder Cachet
- SLO-Tracking: Sloth, Pyrra oder Nobl9
- Postmortem-Management: Jeli, Blameless oder ein einfaches Shared-Doc-Template
Fazit
Effektives Incident Management bedeutet nicht, jeden Ausfall zu verhindern – es bedeutet, Systeme und Prozesse aufzubauen, die die Auswirkungen minimieren und das Lernen maximieren. Die Organisationen, die Incidents gut meistern, sind jene, die üben, bevor sie es müssen, in Werkzeuge investieren und jedes Postmortem als Geschenk betrachten.
Bei DevOpsVibe helfen wir Teams, erstklassige Incident-Management-Prozesse von Grund auf aufzubauen. Vom Design SLO-getriebener Alerts über die Implementierung automatisierter Incident-Workflows bis hin zum Training Ihres Teams in Postmortem-Moderation bringen wir praxiserprobte SRE-Erfahrung in Ihre Organisation. Lassen Sie uns helfen, dass Sie im On-Call besser schlafen.