← 23: etcd
SLA, SLO, RPO, RTO — ограничения, которые определяют архитектурные решения: сколько реплик нужно приложению, какой cadence у backup'ов, нужен ли multi-zone etcd. Каждое число требует доказательства — измеренного, а не предполагаемого. sre.google/sre-book/service-level-objectives/
SLA — внешнее обязательство
Service Level Agreement — контрактное обещание бизнесу или пользователям. Пример: «Платформа доступна 99.9% времени в месяц». Нарушение SLA влечёт последствия — финансовые штрафы, отток пользователей, потерю доверия.
SLA — это потолок, ниже которого нельзя опускаться. Но инженерный таргет должен быть строже, иначе при первом же инциденте контракт нарушен.
SLO — внутренний инженерный таргет
Service Level Objective — внутренняя цель, которая строже SLA. Если SLA = 99.9%, то SLO должен быть 99.95% или выше. Зазор между SLO и SLA — это буфер: он позволяет обнаружить деградацию до того, как она становится нарушением контракта.
SLO 99.95% ←── инженерный таргет (строже)
↕ буфер
SLA 99.9% ←── контрактное обязательство
SLO без SLI — декорация. Число бессмысленно, если нет способа его измерить.
SLI — доказательство соответствия
Service Level Indicator — конкретная метрика, которая доказывает выполнение SLO. Без SLI невозможно определить, соблюдается SLO или нет.
Примеры SLI для Kubernetes-платформы:
- Доля успешных API-запросов (
apiserver_request_totalс HTTP 2xx / total) за скользящее 30-дневное окно - P99 latency API server (
apiserver_request_duration_seconds{quantile="0.99"}) < 1 секунды now() - backup_last_success_timestamp< RPO — свежесть последнего backup'а
SLI — мост между обещанием (SLO) и реальностью. Если метрики нет — SLO существует только на бумаге.
SLI для доступности API server (PromQL)
Запрос для расчёта error rate за 30-дневное окно:
# Доля успешных запросов (success rate)
sum(rate(apiserver_request_total{code=~"2.."}[30d]))
/
sum(rate(apiserver_request_total[30d]))
Важный нюанс: из denominater нужно исключать запросы типа WATCH — они долгоживущие и искажают latency SLI. Фильтр по verb!="WATCH" типичен для latency SLI, но не для availability SLI.
# P99 latency (исключая WATCH)
histogram_quantile(0.99,
sum(rate(apiserver_request_duration_seconds_bucket{verb!="WATCH"}[5m]))
by (le, resource, verb)
)
Связка SLI → SLO → алерт
Практический подход: для каждого SLO определяется SLI-запрос, пороговое значение, и alerting rule. Пример структуры:
# В terms Prometheus recording rule
- record: sli:apiserver_availability:ratio_rate30d
expr: |
sum(rate(apiserver_request_total{code=~"2.."}[30d]))
/
sum(rate(apiserver_request_total[30d]))
# Алерт: SLO нарушен (success rate < 99.95%)
- alert: APIServerSLOViolation
expr: sli:apiserver_availability:ratio_rate30d < 0.9995
for: 5m
labels:
severity: critical
annotations:
summary: "API server availability SLO нарушен"
kubernetes.io/docs/reference/instrumentation/metrics/
RPO и RTO — параметры восстановления
RPO — Recovery Point Objective
Максимально допустимая потеря данных. RPO = 15 минут означает: при аварии допустимо потерять не более 15 минут данных. RPO напрямую определяет cadence backup'ов. Если RPO = 15 минут, а backup снимается раз в час — RPO нарушен by design, ещё до любой аварии.
RTO — Recovery Time Objective
Максимальное время восстановления до рабочего состояния. RTO = 30 минут означает: от момента аварии до работающего кластера — не более 30 минут.
RTO без измеренного restore — пустое число. Если полный цикл восстановления никогда не тестировался, заявленный RTO — это желание, а не гарантия.
Авария Восстановление
│ │
├──── RPO ────┤ │
│ (допустимая потеря данных) │
│ │
├─────────── RTO ────────────┤
│ (время от аварии до рабочего состояния)
Связь с backup: для подтверждения RTO нужно регулярно запускать тестовый restore и замерять его длительность. kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/
Error Budgets
Error budget переводит SLO из абстрактного числа в операционный инструмент.
Расчёт бюджета
Формула: бюджет = (1 - SLO) × период
Пример: SLO 99.95% за месяц (43 200 мин) → бюджет = 0.0005 × 43 200 ≈ 21.6 мин.
Как error budget управляет решениями
Error budget — это переключатель между режимами работы команды:
Error budget полный Error budget исчерпан
───────────────────────── ─────────────────────────
Можно деплоить фичи Стоп фичам
Можно экспериментировать Фокус на стабильность
Плановые обновления ОК Только критические патчи
Risky rollout — допустим Risky rollout — запрещён
Без error budget SLO — пожелание. С error budget — операционный сигнал, который диктует приоритеты.
Один неудачный restore длительностью 45 минут при SLO 99.95% съедает бюджет двух месяцев целиком. Это делает тестирование restore экономически обоснованным требованием.
Burn rate алерты
Классический алерт «error rate > порога» реагирует слишком медленно или слишком шумно. Burn rate — скорость, с которой расходуется error budget. Если burn rate = 1, бюджет расходуется ровно в темпе SLO. Burn rate = 10 означает, что бюджет закончится в 10 раз быстрее, чем ожидалось.
# Burn rate за 1 час (быстрый алерт, высокий порог)
(
1 - sum(rate(apiserver_request_total{code=~"2.."}[1h]))
/ sum(rate(apiserver_request_total[1h]))
)
/ (1 - 0.9995) # (1 - SLO)
Если это значение > 14.4 (канонический Google SRE порог: 2% бюджета за час) — бюджет месяца будет исчерпан за 2 дня. Это критичный алерт. Двухуровневая схема алертинга (fast + slow burn rate) снижает количество ложных срабатываний при сохранении чувствительности к реальным проблемам.
Baseline-таблица для Kubernetes-платформы
Пояснения:
- Tier-1 user path — критичные пользовательские сценарии. SLA фиксируется в контракте с бизнесом.
- Control plane — без внешнего SLA, но SLO обязателен: без control plane невозможно управлять кластером.
- Observability stack — менее строгий SLO допустим, но без observability нельзя доказать соблюдение остальных SLO. Это единственный компонент, деградация которого делает все остальные числа недоказуемыми.
Когда использовать
SLO и error budget нужны сразу — с первого дня production-эксплуатации кластера:
- Есть внешние пользователи или SLA — SLI/SLO обязательны, иначе нельзя доказать соблюдение контракта.
- Плановые обновления и дренаж нод — error budget подсказывает, безопасно ли сейчас рисковать disruption.
- Решение об архитектуре — нужен ли multi-zone, сколько реплик control plane, какой cadence у backup'ов. Без SLO/RPO/RTO эти решения принимаются интуитивно, а не по данным.
- Postmortem — фиксация фактического impact в единицах error budget. Конкретное число («потрачено 18 мин из 22-минутного бюджета») сильнее, чем «был небольшой инцидент».
Для внутренних dev-кластеров без внешних пользователей — достаточно RPO/RTO, SLI/SLO опциональны.
Практический минимум для старта: выбрать один SLI (success rate API server), задать SLO (99.95%), настроить recording rule в Prometheus, добавить алерт на burn rate. Следующий шаг — добавить latency SLI и RPO-алерт на свежесть backup'а. Постепенное расширение SLI-покрытия предпочтительнее попытки настроить всё сразу: каждый новый SLI требует калибровки порогов на реальном трафике.
Типичные ошибки
1. SLO = SLA Инженерный таргет совпадает с контрактным обязательством. Любой инцидент — сразу нарушение SLA. Нет буфера для обнаружения деградации. Правило: SLO должен быть строже SLA минимум на 0.05–0.1 процентных пункта.
2. RTO без тестового restore
Цифра «RTO = 30 мин» написана в документе, но полный цикл восстановления никогда не запускался. При реальной аварии обнаруживается, что restore занимает 2 часа. Правило: RTO действителен только если подтверждён измеренным restore_check_duration_seconds.
3. RPO ≠ cadence backup'ов RPO = 15 минут, backup — раз в час. RPO нарушён by design. Правило: cadence backup ≤ RPO. kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/#backing-up-an-etcd-cluster
4. SLO без SLI «Доступность 99.95%» есть в roadmap, но нет метрики, которая это измеряет. Число не подтверждается и не фальсифицируется. Правило: каждому SLO — минимум один SLI с конкретным запросом к Prometheus.
5. Error budget как информация, а не как механизм Бюджет отображается на дашборде, но не влияет на решения о деплоях. Правило: исчерпание error budget должно автоматически (или по процессу) блокировать risky deployments.
6. Игнорирование observability stack в SLO SLO есть для приложений и control plane, но сам мониторинг не мониторится. Если Prometheus падает — нарушения SLO незаметны. Правило: observability stack — отдельный SLO с heartbeat-алертом.
Альтернативы
DORA Metrics (Deployment Frequency, Lead Time, MTTR, Change Failure Rate) Ориентированы на delivery process, а не на runtime reliability. Дополняют SLO/SLI, не заменяют. Хороши для оценки engineering velocity рядом с reliability-метриками.
Uptime monitoring (Pingdom, UptimeRobot, Blackbox Exporter) Проверяют доступность endpoint'а снаружи. Проще в настройке, но не дают detalization: непонятно, почему сервис недоступен, и не покрывают latency SLO. Подходят как дополнение к SLI, не как замена.
Synthetic monitoring (k6, Playwright в CI) Синтетические транзакции, которые эмулируют пользовательский путь. Отличный источник SLI для Tier-1 user path — реальнее, чем метрики с API server. Требуют поддержки тестов.
Chaos Engineering (LitmusChaos, Chaos Mesh) Намеренное внесение сбоев для проверки, что SLO выдерживается при реальных failure modes. Не альтернатива SLO, а способ их верифицировать. kubernetes.io/docs/concepts/workloads/pods/disruptions/
Vendor SLA (managed Kubernetes: EKS, GKE, AKS) Cloud-провайдеры дают SLA на control plane (обычно 99.95–99.99%). Снимает ответственность за availability control plane, но не снимает обязанность определять RPO/RTO для данных приложений и SLO для user-facing сервисов.