lenec ru

← все посты

Runbook vs playbook: что писать для on-call инженера

12K

«Сервис недоступен», «база переключилась на реплику», «алерт HighDiskUsage сработал». Что делать в три ночи on-call инженеру? Если ответа нет — он будит других, разбирается на лету, и инцидент длится дольше. Если есть пошаговый сценарий — действует за 5 минут, и вопрос закрыт.

Документация для on-call — это не «справочник на всякий случай». Это инструмент работы дежурного, и от его качества зависит время на инцидент, частота эскалаций и количество выгораний. Слова «runbook» и «playbook» в индустрии используют как синонимы или с разными значениями в разных компаниях. Разберу, чем они отличаются по моему опыту, какой минимум документации нужен on-call, и как это поддерживать.

Runbook vs playbook

Чёткой стандартизации нет, но обычно различают так:

Runbook — пошаговое руководство для конкретного сценария. «Что делать, если сработал алерт X». Структурный документ, минимум прозы, максимум команд для копирования. Цель — действовать без раздумий.

Playbook — описание процесса с вариантами и решениями. «Как обрабатывать инциденты priority-1». Включает roles, communication, escalation, decision points. Цель — координация людей и принятие решений.

Простая аналогия: runbook — это рецепт пирога, playbook — это план мероприятия с гостями. Первый говорит «положи муку», второй — «как реагировать, если кончилась мука».

Что нужно on-call в первую очередь

На практике дежурный сталкивается с двумя сценариями:

  1. Известный алерт. Включается типичный паттерн «сработало X — делай Y» — нужен runbook.
  2. Неизвестная ситуация. Что-то ломается, никто не знает, что — нужен playbook по incident management.

Команды без документации обходятся «на чате»: что-то падает, дежурный пишет в общий канал, кто-то из старших разработчиков отвечает. Это работает, пока команда маленькая. С ростом — становится узким местом.

Структура runbook-а

Шаблон, который у меня работает на разных проектах:

# Runbook: HighDatabaseLatency

## Symptoms

- p99 query latency > 1s for > 5 minutes
- Alert: `HighDatabaseLatency` in Grafana
- Users may report slow page loads

## Most likely causes (in order)

1. Long-running query blocking others
2. Connection pool exhaustion
3. Disk IO saturation
4. Application bug causing query storm

## Diagnostic commands

Check active long queries:
<pre><code class="language-sql">SELECT pid, now() - query_start AS duration, state, query
FROM pg_stat_activity
WHERE state = 'active' AND query_start < now() - interval '30 seconds'
ORDER BY duration DESC;</code></pre>

Check connection pool:
`kubectl exec -it pgbouncer-0 -- psql -U pgbouncer -p 6432 -c 'SHOW POOLS;'`

Check disk IO:
`Grafana dashboard → Database → Disk IO panel`

## Mitigation

If long query found:
- Confirm with team owner of the service.
- Kill query: `SELECT pg_cancel_backend(pid);` (graceful)
- If persists: `SELECT pg_terminate_backend(pid);` (forceful)

If connection pool exhausted:
- Check if app deploy preceded the alert.
- Bounce affected app pods: `kubectl rollout restart deployment/<app>`
- If pool size is wrong: see runbook `IncreaseConnectionPool`.

## Escalation

If unresolved in 15 minutes — page database team:
- PagerDuty: `database-team`
- Slack: `#db-help`

## Related

- [Postmortem 2026-02-14: Long query during deploy](/postmortems/2026-02-14)
- [Runbook: IncreaseConnectionPool](/runbooks/conn-pool)

Семь секций: симптомы, наиболее вероятные причины, диагностика, mitigation, эскалация, связанные документы. Без воды.

Что критично в runbook-е

Команды для копирования. Не «проверьте состояние пула», а конкретный kubectl exec ... SHOW POOLS. В три ночи никто не вспомнит синтаксис.

Конкретные пороги. Не «если высокая нагрузка», а «если CPU > 80% дольше 5 минут».

Decision tree. «Если X — делайте A. Если Y — делайте B». Чтобы дежурный не гадал.

Эскалация с конкретными контактами. Не «обратитесь к команде базы данных», а «PagerDuty: database-team, Slack: #db-help».

Тайминг. «Если за 15 минут не решено — эскалируйте». Без таймера дежурный сам не знает, когда уже звать на помощь.

Чего не нужно в runbook-е

Объяснений «как работает компонент». Если нужны — отдельная страница explanation, на которую runbook ссылается. В runbook — действия, не теория.

Истории про то, как мы пришли к такой архитектуре. Дежурному не нужно знать, что в 2023 году мы перешли с MongoDB.

Слишком общих фраз. «Проверьте логи на наличие ошибок» — бесполезно. «Откройте Loki, фильтр service=notifications level=error за последние 30 минут» — полезно.

Множественных опций. «Можно использовать инструмент A, B или C». Дежурный не знает, какой выбрать. Один способ.

Структура playbook-а по incident management

Playbook — это координационный документ. Структура другая.

# Playbook: Production Incident Response

## Severity levels

- **P0** — total service outage, data loss risk. 24/7 immediate response.
- **P1** — partial outage, major degradation. Response within 1 hour, business hours 24/7.
- **P2** — minor degradation, no user impact. Response next business day.

## Roles during incident

- **Incident Commander (IC)** — coordinates response, makes decisions.
- **Tech Lead (TL)** — investigates, applies fixes.
- **Communications Lead (CL)** — updates stakeholders, status page.
- **Scribe** — records timeline, decisions.

For P2 — IC and TL can be same person.
For P0 — must have all four roles, no exceptions.

## Initial response (first 15 minutes)

1. On-call confirms alert is real (not noise).
2. Declares incident, posts in #incidents channel.
3. Assigns IC role (initially — themselves).
4. Pages additional people based on severity.
5. Opens incident channel in Slack: `#inc-YYYY-MM-DD-short-description`.

## During the incident

- IC keeps focus on resolution, defers post-analysis.
- Updates every 30 minutes in incident channel.
- TL investigates, doesn't implement fix without IC approval (for P0).
- Communications go through CL only.

## Resolution

- Verify metrics back to baseline for > 30 minutes.
- IC declares incident closed in channel.
- Schedule postmortem within 5 business days.

## After the incident

- Postmortem author assigned (usually IC or TL).
- Postmortem reviewed by team within 2 weeks.
- Action items tracked in main project board.

Этот документ нужен команде, в которой инциденты случаются регулярно и требуют координации нескольких людей. Маленьким командам (1-2 разработчика на сервис) playbook избыточен — там всё в одной голове.

Severity matrix

На что чаще всего ругаются on-call: «было ли это P0 или P1»? Без матрицы — спор на ровном месте.

| Severity | User impact                    | Response   | Examples                          |
|----------|--------------------------------|------------|-----------------------------------|
| P0       | Total outage, data loss risk   | 24/7 ASAP  | Login broken, payments down       |
| P1       | Major degradation              | 1h, 24/7   | Slow API, partial feature broken  |
| P2       | Minor issue, no user impact    | Next day   | Internal tool slow, dashboard 404 |
| P3       | Cosmetic                       | Next sprint| Minor UI glitch                   |

Конкретные примеры важны, чтобы не было спора «это P1 или P2». Когда не знаешь — округляй вверх. Лишний раз объявить P1 и закрыть проще, чем недореагировать на P0.

Где это всё хранить

Опции:

  • Markdown в репозитории сервиса. Хорошо для runbook-ов, привязанных к конкретному сервису. Плохо для playbook-ов, общих для всей организации.
  • Отдельный репозиторий runbook-ов. Хорошо для центрального доступа. Все runbook-и команды в одном месте.
  • Backstage TechDocs. Если есть — интегрируется с каталогом сервисов.
  • Confluence. Удобно для playbook-ов уровня организации, но устаревает быстрее, чем хотелось бы.

Лично я делаю гибрид: runbook-и — в репозитории сервиса, в папке docs/runbooks/; playbook incident management — в общем репозитории платформенной команды.

Связь алертов и runbook-ов

Самое полезное — ссылка на runbook прямо в алерте.

- alert: HighDatabaseLatency
  expr: histogram_quantile(0.99, rate(db_query_duration_bucket[5m])) > 1
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "Database latency is high"
    runbook_url: "https://docs.internal/runbooks/HighDatabaseLatency"

Когда алерт срабатывает, в нотификации (PagerDuty, Slack) — кликабельная ссылка на runbook. Дежурный открывает за один клик. Без неё — сначала нужно понять, какой runbook относится к этому алерту, потом найти его в репозитории.

Поддержание актуальности

Runbook быстро устаревает: сервис мигрировал, имена изменились, команды переименовались. Нужен процесс.

  • После каждого инцидента — апдейт связанного runbook-а. «Что было непонятно дежурному, добавляем в runbook». Это action item на постмортем.
  • Раз в квартал — review runbook-ов на предмет устаревания. Команда быстро проходит по списку, помечает «устарело», переписывает.
  • Game days. Имитация инцидента, дежурный использует runbook. Если что-то непонятно — runbook не работает, поправляем.

Без процесса — runbook через год становится «общим описанием с устаревшими командами», и дежурные перестают на него полагаться.

Что делать новой команде с нулём документов

Если команда только начинает обкладываться runbook-ами:

  1. Список топ-5 алертов по частоте за последний месяц.
  2. На каждый — runbook по шаблону. 30-60 минут на каждый.
  3. Простой playbook incident response: severity matrix + основные роли.
  4. Связь алертов с runbook-ами (поле runbook_url).
  5. В каждом постмортеме — апдейт связанного runbook-а как action item.

За месяц у команды есть базовый набор. Дальше расширяется по запросу: новый алерт без runbook-а — добавляем, и так до покрытия 80% инцидентов.

Чек-лист зрелости документации on-call

  • Есть runbook на каждый алерт, который может разбудить дежурного ночью.
  • Алерты содержат ссылку на runbook.
  • Runbook-и в репозитории, в Markdown.
  • В каждом — секция эскалации с конкретными каналами и таймером.
  • Severity matrix существует и согласована командой.
  • Playbook incident response описывает роли, начальные действия, коммуникации.
  • После каждого инцидента связанный runbook обновляется.
  • Runbook-и проходят game day-ревью раз в квартал.
  • Новые члены команды могут разобрать инцидент по runbook-ам без помощи старших.

Документация для on-call — это не дополнительная нагрузка, это инструмент работы. Команда без runbook-ов проигрывает в скорости реакции и держит знание в головах нескольких ключевых людей. Как только эти люди уходят или выгорают — команда оказывается беспомощной. Runbook и playbook не делают команду суперэффективной, но защищают от провалов в самые неудобные моменты.

Комментарии 0

  • Будьте первым, кто оставит комментарий.

Войдите, чтобы оставить комментарий.