Runbooks
«Алерт без runbook — фоновый шум» — это фраза, которую я повторяю чаще всего на ревью алертов. Сам runbook — не идея «давайте напишем инструкции», а конкретный документ с конкретными командами, ожидаемыми выводами и точками, где дежурный принимает решение. В три ночи приходит pager, человек открывает ссылку и за десять секунд понимает, что перед ним: команда, которую можно скопировать, или эссе про архитектуру сервиса. Лист про эту разницу.
Что должен уметь
Заголовок раздела «Что должен уметь»Главный навык на уровне L4 — писать runbook так, чтобы по нему мог пройти новый дежурный без контекста. Если на каждом шаге приходится вспоминать архитектуру сервиса, догадываться, что имел в виду автор, и выбирать, какой dashboard открыть, — runbook сломан. Хороший runbook — это серия конкретных команд и явных решений «если видишь X, переходи к шагу N; если Y — к шагу M».
L3
- Использует существующие runbook’и команды для реагирования на инциденты; следует шагам, не выходит за их пределы без эскалации.
- Сообщает владельцу runbook о найденной неточности или устаревшем шаге сразу после использования (не «потом, на ревью»).
L4
- Пишет runbook для известного типа инцидента: симптом → шаги диагностики → шаги mitigation → как откатить → escalation. Обновляет runbook после новых инцидентов.
- Пишет по шаблону команды и проверяет каждый шаг на исполнимость: конкретная команда или явное решение, не «понять и подумать».
L5
- Строит культуру, в которой алерт без runbook в команде просто не принимается. Проводит аудит runbook’ов на актуальность по расписанию.
- Тестирует runbook’и в game day / wheel of misfortune; не доверяет ни одному runbook, которым никто не проходил по факту.
- Встраивает ссылку на runbook прямо в алерт (например, через
runbook_urlannotation в Prometheus AlertRule или полеrunbookв Alertmanager).
L6+
- Внедряет систему работы с runbook: платформа, шаблоны, метрики использования, автоматическая связь с системой алертинга.
- Держит SLO для самого репозитория с runbook’ами (например, «≥ 95% алертов имеют ссылку на актуальный runbook»); отслеживает деградацию покрытия.
Материалы
Заголовок раздела «Материалы»- Betsy Beyer et al. — Site Reliability Engineering (O’Reilly, 2016), глава 11 «Being On-Call». Раздел «Documenting» — фундамент всей культуры работы с runbook.
- Betsy Beyer et al. — The Site Reliability Workbook (O’Reilly, 2018), глава 8 «On-Call». Продолжение: playbook содержит severity, impact, debugging suggestions, mitigation. Утверждение «каждый алерт получает playbook» как норма.
Статьи и доклады
Заголовок раздела «Статьи и доклады»- PagerDuty — Incident Response Documentation. Публичный guide по incident response; даёт референс формата runbook («Being On-Call → Before / During / After»). По моим наблюдениям, многие команды берут именно его как стартовый шаблон.
Инструменты
Заголовок раздела «Инструменты»- Markdown в репозитории команды — самый простой и работающий формат. Один runbook = один файл, ревью через pull request, история в git. Я вижу, что большинство зрелых команд так и живёт, а отдельную платформу заводят единицы.
- Rundeck — open-source платформа для исполняемых runbook’ов (job runner + access control + audit). Имеет смысл, когда часть шагов автоматизируется и нужно фиксировать исполнение.
- StackStorm — event-driven automation platform; runbook как сценарий, запускаемый по триггеру. Альтернатива Rundeck для команд, у которых уже есть шина событий.
- Prometheus AlertRule
runbook_urlannotation — стандартный паттерн: каждому алерту вprometheus.ymlпрописывается ссылка на runbook. Alertmanager пробрасывает её в нотификацию (Slack/Pager).
Best practices
Заголовок раздела «Best practices»Я регулярно встречаю команды, у которых 200+ active алертов в Prometheus, а 70–80% из них либо без runbook, либо с мёртвым: ссылки на несуществующие сервисы, deprecated команды, dashboard URL, отдающий 404. Смена превращается в «разбуди и пусть гадает». Инженер ack’ает, копает 10–30 минут, чаще всего упирается в шум, а runbook откладывается «до следующего раза» — которого не бывает. MTTR на алерт на такой смене — десятки минут. После систематической чистки по правилу «или runbook, или удаляем алерт» цифра падает в несколько раз, но именно после работы, а не после решения «найти на это время».
Короткие правила:
- Runbook = детальные шаги, не нарратив. Если для исполнения шага надо «знать архитектуру» или «вспомнить контекст», runbook сломан: on-call в три ночи не думает, он следует.
- Каждый шаг исполним и заканчивается критерием проверки. Шаг «проверить логи» без указания где, какие и что искать — бесполезен. Правильно: «выполни
kubectl logs -n prod app-foo --tail=200 | grep ERROR; если видишьconnection refused— переходи к шагу 3, иначе к шагу 5».
Шаг «как откатить безопасно» я считаю обязательным, и его пропускают чаще всего. Каждое изменяющее действие в runbook идёт в паре с откатным шагом и критерием, по которому дежурный решает откатывать. Без этой пары runbook ведёт mitigation только вперёд. А ситуация, когда mitigation сделал хуже, встречается регулярно, и разбираться в ней приходится тому же человеку в те же три ночи.
Подробнее:
Привязка к симптому, а не к причине. Дежурный не видит «база упала». Он видит «p99 latency > 500ms» или «5xx rate > 1%». Runbook с названием «падение базы» для него не существует: связь между тем, что на экране, и тем, что в wiki, придётся достраивать самому, и это те самые пятнадцать минут, за которые инцидент успевает вырасти. Поэтому runbook называется по симптому — по имени алерта. Симптомов мало, причин много, и от симптома документ уже ведёт к диагностике причин.
Регулярный аудит и владелец. Устаревший runbook хуже отсутствующего: он даёт ложную уверенность и ведёт не туда. Я встречаю это часто. Ссылка на dashboard, который год назад переехал в другой namespace; на скрипт, который удалили из репозитория; на ротацию команды, которая расформировалась. Лечится скучно: явная периодичность пересмотра (квартал или полугодие), явный владелец, отвечающий за актуальность, и обязательное обновление того runbook, который использовали в последнем инциденте.
Тестирование в game day. Runbook, написанный год назад и положенный в wiki, в момент инцидента запросто окажется неработоспособным — команда не работает, шаги ведут не туда, dashboard давно другой. Game day (wheel of misfortune, прогон сценария из прошлого постмортема) находит эту гниль без боевой обстановки. Непротестированный runbook — обещание, а не инструмент.
Связанные листья
Заголовок раздела «Связанные листья»- SLI-based Alerting — обязательная пара: каждый SLO-алерт ведёт к runbook; алерт без runbook удаляется как фоновый шум.
- Incident Response — runbook — главный инструмент в моменте инцидента; качество runbook прямо определяет MTTR.
- Postmortem Culture — каждый постмортем порождает обновление runbook (новый или правки существующего); без обновления lesson learned не закреплён.
- Dev Team Partnership — co-ownership: runbook’и пишутся совместно с продуктовой командой; иначе SRE дежурит вслепую по чужому сервису.
- Toil Automation — шаги, которые дежурный выполняет одинаково каждый раз, переезжают в код: «runbook говорит сделать X — пусть делает скрипт».
- Playbooks — runbook отвечает «как делать», playbook — «что решать и кого звать». Runbook’и встраиваются в playbook’и как ссылки на конкретные шаги; разделение явное.
Открытые вопросы
Заголовок раздела «Открытые вопросы»- Я не знаю хорошего ответа на «когда runbook превращается в automated remediation». В тривиальных случаях — alert + 3-step runbook → Lambda или k8s operator. В нетривиальных — runbook содержит ветвление по контексту, и автоматизация рискует выстрелить в ногу при первом edge-case. Граница «можно автоматизировать» / «надо оставить человеческое решение» в публичной литературе чёткой не вижу. Если есть опыт — расскажите PR’ом.