Заметка

Инцидент, закрытый дважды: severity, роли ICS и три гейта перед recovered

Почему «восстановлено» — самое дорогое слово в инциденте и какие три проверки обязаны пройти до него.

Самое дорогое слово в инциденте — «восстановлено». В одном реальном инциденте — потеря сетевых алиасов в Docker Swarm — recovery анонсировали дважды: после первого анонса регресс пришёл через час, после второго тихие повреждения копились ещё четыре дня, потому что control plane уверенно рапортовал «everything is up». Преждевременный анонс стоит дороже самого даунтайма: он снимает команду с боевого режима и сжигает доверие к каждому следующему «всё работает».

Каркас, который удерживает инцидент от хаоса, состоит из трёх частей: классификация severity, роли Incident Command System и формальный definition of recovered.

Severity назначают за минуту — и она решает всё

SEV1 — полный outage прода, потеря данных или security breach: page в течение пяти минут, all-hands, status page, руководство в курсе. SEV2 — серьёзная деградация ключевой функции: page за 15 минут, on-call плюс менеджер. SEV3 — деградация с workaround: тикет в течение часа, канал команды. SEV4 — косметика, next business day, бэклог.

Смысл этой таблицы не в самой классификации, а в том, что она снимает первое решение с уставшего человека в три ночи: severity определяет, кого будят, какой канал открывают и какое время отведено на реакцию. Спор «а это точно SEV1?» откладывается на постмортем — даунгрейдить инцидент задним числом дёшево, проспать эскалацию дорого.

ICS: командир не трогает клавиатуру

При SEV1/SEV2 включается Incident Command System — набор ролей, пришедший из мира пожарных служб. Incident Commander принимает решения и координирует — и не делает hands-on. Operations Lead ведёт техническую диагностику и mitigation. Communications Lead обновляет status page и держит в курсе клиентов и руководство. Scribe ведёт хронологию в канале #incident-NNN. SME подтягиваются по доменам — база, сеть, конкретный сервис.

Главное правило одно: IC не может одновременно копать и координировать. Перегруженный командир теряет картину целиком, команда теряет синхронизацию — и через час выясняется, что два инженера параллельно катили несовместимые mitigation.

Mitigate ≠ Fix

Жизненный цикл инцидента: Detect → Triage → Mitigate → Resolve → Learn. Mitigate — остановить кровотечение: rollback, scale up, выключенный feature flag. Fix — устранение root cause в спокойной обстановке, после. Классическая ошибка — дебажить корневую причину в пике инцидента, когда откат вернул бы сервис за две минуты: 90% инцидентов связаны с недавним изменением, поэтому «что катили за последние два часа» проверяется раньше, чем первый stack trace.

Три гейта перед словом «recovered»

Этот урок формализуется в три проверки, без которых инцидент не закрывается.

Первый гейт — stable-for-N-minutes под боевым трафиком. N масштабируется с severity: SEV1 — от 30 минут, SEV2 — от 15. Одна зелёная точка на графике — не тренд.

Второй — downstream-artefact verification. Для каждого критичного выхода затронутых сервисов — sitemap, RSS, public API, выгрузки по расписанию — проверяется свежесть и корректность, а не только health самого сервиса. Комбинация «сервис up, артефакт stale» — классический удар по доверию.

Третий — post-recovery discovery audit, и он заслуживает отдельного раздела.

Пока все три гейта не пройдены, статус инцидента — «stabilised, verification ongoing». Не «closed».

Control plane врёт: declared vs actual

Самый коварный failure mode общий для любого оркестратора с internal DNS: control plane рапортует «everything is up», а фактические регистрации частично отсутствуют или устарели. В Kubernetes под может быть Running, но не попасть в Endpoints — readiness, taint ноды. В Docker Swarm overlay-алиасы теряются, и переподключение сети in-place не восстанавливает bookkeeping. В Consul — split-brain агента или истёкший TTL регистрации. Downstream-потребители при этом молча получают 504 или NXDOMAIN.

Ответ — recurring audit «declared vs actual»: то, что объявлено (selector сервиса, алиасы из compose-стека, service definition), сравнивается с тем, что фактически зарегистрировано (EndpointSlice, overlay DNS, consul catalog). Результат пушится во внешний receiver — Uptime Kuma push monitor или healthchecks.io: упавший кластер ломает и собственный alerting, поэтому локальный cron с алертом здесь не годится.

Оттуда же — практическое наблюдение про reset: для оркестратора с непрозрачным внутренним состоянием scale до нуля и обратно сильнее, чем рестарт in-place, потому что освобождает bookkeeping шедулера. Если «рестартни под» не помогло — состояние повреждено глубже, чем кажется с поверхности.

«Recovered» — это контракт

Definition of recovered — контракт команды с пользователями: не «метрика позеленела», а «стабильно N минут под трафиком, downstream-артефакты свежие, declared совпадает с actual». Формализовать его — полчаса на runbook. Не иметь — четыре дня тихих повреждений после второго преждевременного анонса.

© 2026 axyi.ru · CC BY 4.0