Skip to content
PПромтбук
RUEN
04Документация

Runbook для инцидента: шаблон

Симптомы → first response → escalation → проверки → восстановление → пост-мортем. Живой документ, не отчёт.

Напиши runbook для {{service}} на тип инцидента: {{incident_type}}.

Базовая аксиома: runbook читается в 3 часа ночи человеком в панике после звонка PagerDuty. У него нет времени думать, нет контекста, не знает кода. Каждое предложение должно быть командой. Без воды, без объяснений «почему». Объяснения идут в постмортем, не в runbook.

Шаблон

# Runbook: [{{service}}] {{incident_type}}

**Severity:** SEV-1 / SEV-2 / SEV-3
**Owner:** team-name (slack channel)
**On-call:** PagerDuty schedule name
**Last updated:** YYYY-MM-DD by @author
**Last verified:** YYYY-MM-DD (game day / real incident)

---

## 1. Это оно? (симптомы)

Проверь ВСЕ три условия. Если совпадает — продолжай. Если нет — ищи другой runbook.

- [ ] **Алерт:** `HighLatencyAlert` / `5xxBurst` / `QueueLagCritical` — точное имя
- [ ] **Метрика:** `http_request_duration_seconds{service="X"} p99 > 2s` за последние 5 минут
- [ ] **Симптом у пользователя:** [конкретное наблюдение — медленный checkout / ошибки в логине]

**Похожие но НЕ это:**
- Если только увеличена latency, но 2xx-ответы — см. `high-latency.md`
- Если 5xx, но только из одного региона — см. `regional-outage.md`
- Если только background jobs тормозят — см. `worker-lag.md`

---

## 2. First response (первые 5 минут)

**Дашборд:** [ссылка на grafana / datadog с заранее настроенным view]

**Скажи в #incidents:**

INCIDENT: {{service}} {{incident_type}} Severity: SEV-? IC: @me Status page: yes/no


**Сделай СРАЗУ (не думая):**
1. Открой дашборд (выше)
2. Открой логи: `kubectl logs -n {{service}} --tail=200 | grep ERROR`
3. Открой traces: [ссылка на jaeger/honeycomb с фильтром на error]
4. Сделай screenshot текущего состояния (для постмортема)

**НЕ делай в первые 5 минут:**
- НЕ деплой
- НЕ перезагружай поды массово
- НЕ меняй конфиг
- НЕ паникуй в публичных каналах

---

## 3. Escalation (когда звать помощь)

| Условие | Кого | Канал |
|---|---|---|
| SEV-1 (revenue impact) | Incident Commander | PagerDuty escalation |
| Не понял что происходит за 15 мин | Senior on-call | @senior-oncall in #incidents |
| Нужен доступ которого нет | Tech lead | @tech-lead-{{service}} |
| Возможна потеря данных | Database team + CTO | DM + #db-emergency |
| Влияет на другой сервис | Owner того сервиса | их PagerDuty |

**Когда поднимать статус-страницу:** > 1% пользователей затронуто на > 5 минут.

---

## 4. Что в логах и метриках

### Проверка 1: ошибки в логах
```bash
kubectl logs -n prod -l app={{service}} --since=10m | grep -E "ERROR|FATAL|panic"

Что искать: новый класс ошибок (не было 30 минут назад) — это коренная причина.

Проверка 2: метрики golden signals

  • Latency: p50, p99 за 1ч / 24ч — сравни
  • Traffic: RPS — упал или вырос?
  • Errors: rate(http_5xx[5m]) — взрыв?
  • Saturation: CPU / memory / connection pool / queue length

Проверка 3: недавние изменения

  • Деплои за 2 часа: [ссылка на CI/CD timeline]
  • Feature flags toggled: [ссылка на flag changelog]
  • Конфиг changes: git log --since="2 hours ago" -- config/
  • Инфра changes: Terraform applies, kubectl rollout

Эмпирика: 80% инцидентов — недавнее изменение. Если был deploy/flag/config за 2 часа — это первый подозреваемый, не «странный баг в проде».

Проверка 4: зависимости

  • БД: alive, latency, connections, slow queries
  • Redis / cache: alive, hit rate, eviction rate
  • External APIs: их status page, latency
  • Очередь: длина, age oldest message, consumer lag

5. Восстановление (mitigation)

Иерархия: сначала остановить кровь, потом разобраться. Восстановление != fix.

Опция A: rollback (≤ 5 минут)

kubectl rollout undo deployment/{{service}} -n prod
# или
helm rollback {{service}} <previous-revision>

Когда: проблема началась после deploy в последние 2 часа. Риск: низкий. Может потерять hotfix.

Опция B: feature flag off (≤ 2 минуты)

flagctl set {{service}}.new_feature off --reason "incident-NNNN"

Когда: проблема в фиче за флагом. Риск: функционал недоступен пользователям.

Опция C: scale up (≤ 5 минут)

kubectl scale deployment/{{service}} --replicas=20 -n prod

Когда: saturation (CPU/mem high, queue grows), не код-bug. Риск: маскирует реальную проблему. Не использовать как permanent fix.

Опция D: shed load (≤ 5 минут)

  • Включить rate limit на тяжёлом endpoint
  • Drop low-priority background jobs
  • Включить cached fallback

Когда: dependency сдох (БД, downstream), нужно снизить нагрузку.

Опция E: failover (≤ 15 минут)

# Переключение на standby DB
./scripts/failover.sh --to=replica-2 --confirm

Когда: primary мёртв, replica здорова. Риск: возможна потеря последних писем (RPO). Кто разрешает: Database team + IC.

Опция F: communication only

Иногда лучшее действие — обновить status page и подождать. Если dependency-провайдер (Stripe, AWS) лежит — ничего не сделать, кроме как сообщить.


6. Verification (как понять что отлегло)

  • Алерт прекратил срабатывать на 10 минут подряд
  • Метрики вернулись в норму (latency p99 < target)
  • Synthetic check проходит: curl https://{{service}}/health
  • Пользовательский сценарий работает: [конкретные шаги]
  • Логи: нет нового error class за 5 минут
  • Нагрузка вернулась к baseline (не маска от scale up)

Закрытие инцидента:

  1. Скажи в #incidents: RESOLVED at HH:MM. Owner: @me. Postmortem: <link>
  2. Сбрось status page
  3. Открой postmortem задачу
  4. Если SEV-1/2: уведомь stakeholders (email/slack)

7. Постмортем (в течение 48 часов)

Шаблон в [link]. Минимум:

  • TL;DR: одно предложение, что произошло
  • Impact: длительность, % пользователей, $ revenue если оценимо
  • Timeline: ключевые события с временем (UTC)
  • Root cause: 5 whys, дойти до корня не «human error»
  • Что сработало: хвалить
  • Что не сработало: без обвинений
  • Action items: owner + due date + JIRA ticket
  • Detection time: alert → human awareness — сколько минут
  • Mitigation time: awareness → impact stopped — сколько минут

Blameless: ищем процесс, не человека. «Почему было легко сделать ошибку» вместо «кто виноват».


8. История инцидентов с этим runbook

ДатаКтоСколько minutesЧто пошло не так в runbookAction
2026-03-15@alice23mОпция B не сработала, flag был уже offДобавлен check
2026-04-02@bob12mOK

9. Game day

  • Последний раз протестирован: YYYY-MM-DD
  • Следующий: YYYY-MM-DD (квартально)
  • Известные пробелы: ...

## Принципы хорошего runbook

1. **Команды, не описания.** Не «проверьте логи» — конкретный `kubectl logs ...`.
2. **Копипаст-готово.** Команды должны работать с заменой одной переменной.
3. **Иерархия по времени:** что сделать за 1 минуту, за 5, за 15.
4. **Конкретные пороги:** не «много ошибок», а «`rate(5xx) > 10/s`».
5. **Branching:** если симптом такой → этот runbook, иначе → другой runbook.
6. **Owner viable:** на runbook обязан быть owner который его поддерживает.
7. **Verified:** game day минимум раз в квартал. Не протестированный runbook не работает.
8. **Постмортем-driven updates:** каждый инцидент → пункт в runbook что было неочевидно.

## Anti-patterns

- ❌ Runbook на 50 страниц с теорией системы — никто не прочитает в 3 часа ночи
- ❌ Команды с placeholder'ами без примера (`kubectl logs <pod>`) — какой pod, формат?
- ❌ Ссылки на дашборды без сохранённых фильтров — оператор настраивает grafana вместо тушения
- ❌ «Если что — позвони Алисе» — Алиса в отпуске, нет escalation matrix
- ❌ Не указан severity и нет критериев — нет понимания эскалировать или нет
- ❌ Recovery options без trade-offs — оператор не знает что выбрать
- ❌ Не проверяется (не было game day) — половина команд устарела
- ❌ Не обновляется по постмортемам — те же грабли
- ❌ Описывает «как работает система» вместо «что нажать» — теория не нужна в инциденте
- ❌ Игнорирует communication — статус-страница, stakeholder updates
- ❌ Шаблон постмортема не привязан — постмортем не пишется или формально
- ❌ Нет verification checklist — закрытие инцидента «на ощупь», recurrence через час

## На выходе

- Заполненный runbook по шаблону для {{incident_type}}
- Список зависимостей runbook'а (дашборды, скрипты, доступы) — что нужно подготовить заранее
- Game day сценарий (как протестировать без реального инцидента)
- Owner и расписание review (квартал)
- Связанные runbook'и для соседних симптомов
К подразделу «Документация»
Похожие промты