SLO как код

SLO-as-сode это не просто модный термин, а эволюция подхода SRE, где надежность становится декларативной, версионируемой, тестируемой и неотъемлемой частью процесса разработки.

Вот как я бы выстроил эту систему, исходя из лучших практик и горького опыта.

Цель SLO-as-сode в устранении разрыва между декларативными намерениями по надежности и их реализацией. Это возможность перейти от дохлых и необновляемых страничек в Confluence, которые никто не читает, и помойке из разовых дашбордов в Grafana к управляемой кодовой базе, которая:

  • Единственный источник истины: SLO определены в одном месте, в машиночитаемом формате.
  • Автоматизирована: создание мониторинга, алертинга, отчетов происходит автоматически.
  • Интегрирована в CI/CD: изменения в SLO проходят ревью, тесты, могут блокировать деплой ("можем ли мы позволить себе деплой? Проверяем текущий бюджет ошибок сервиса. Если бюджет исчерпан (или почти), деплой может быть остановлен (с пометкой "override" для экстренных фиксов)).
  • Измерима и тестируема: мы можем проводить тесты для SLO на основе синтетических данных.

Я бы выбрал декларативный YAML/JSON формат, а не код (типа Python). Это делает определения проще для чтения и написания инженерами, не обязательно SRE. Есть и готовые инструменты, например, Sloth.

Пример конфига SLO для HTTP-сервиса

version: "prometheus/v1"
service: "my-http-service"
slos:
  - name: "request-availability"
    objective: 99.9  # 99.9% доступности
    description: "Общая доступность HTTP-запросов"
    sli:
      events:
        error_query: sum(rate(http_requests_total{status=~"5.."}[5m]))
        total_query: sum(rate(http_requests_total[5m]))
    alerting:
      name: "HighErrorRate"
      labels:
        severity: "critical"
      annotations:
        summary: "SLO 'request-availability' нарушен ({{ $labels.slo }} > {{ $value }}%)"

На чем реализовывать:

  • Формат/стандарт: OpenSLO - отлично для начала, но придется допиливать под свои нужды.
  • Хранилище: Git (GitLab, GitHub и т.п.). Каждый сервис хранит свои SLO-файлы в своем репозитории, рядом с кодом, либо в общем репозитории.
  • Обработчик (CLI/Operator): кастомный инструмент, который:
  • Валидирует синтаксис и семантику SLO-файлов (линтер).
  • Генерирует конфигурации для систем мониторинга и алертинга.
  • Вычисляет текущий статус Error Budget.
  • Мониторинг: Prometheus/VictoriaMetrics для метрик. Обработчик генерирует правила записи (recording rules) для SLI и SLO.
  • Визуализация: Grafana. Обработчик генерирует дашборды (через Jsonnet или Terraform) с графиками доступности и сожженного бюджета ошибок.
  • Алертинг: Alertmanager. Обработчик генерирует конфигурации алертов на основе budgetBurnRate.
  • Orchestration: можно использовать заготовки Terraform или Helm-чарты для развертывания всей цепочки мониторинга.

Важно:

Alerting на основе Budget Burn Rate: мы не алертим на нарушение SLO (это уже поздно). Мы алертим на аномальную скорость сжигания бюджета ошибок. Правила fast-burn (пожар) и slow-burn (тление) это золотой стандарт. Обработчик превратит их в Prometheus правила и конфигурацию Alertmanager.

Подробнее в главе "Что делать при нарушении SLO?"

Еще хорошая мысль - программный доступ к Error Budget: делаем Error Budget как метрику (например, slo_error_budget_remaining_ratio) и получаем возможности, например: - интегрировать с системами управления функциями (Feature Flags), то есть, отключать рисковые фичи при низком бюджете ошибок; - строить, например, автоскейлинг на основе не только нагрузки, но и качества обслуживания.

Организационные аспекты

Команда-владелец сервиса пишет и поддерживает свои SLO. SRE - не писатели за них, это консультанты, предоставляющие инструменты и экспертизу.

Нужны воркшопы и другие формы обучения по написанию качественных SLO. Плохой SLO хуже, чем его отсутствие.

Процесс: SLO-as-code должен быть частью Definition of Done для любой новой функциональности.

Как это реализовать

Ничего сложного, главное - захотеть :)

Примерный roadmap:

  • Выбрать 1-2 критичных сервиса. Вручную прописать для них идеальные SLO-файлы.
  • Создать минимальный CLI, который сможет прочитать эти файлы и вывести текущий статус.
  • Интеграция с мониторингом: научить CLI генерировать дашборд в Grafana.
  • Реализовать генерацию алертов по burn rate для одного сервиса.
  • Интегрировать проверку SLO в пайплайн выбранной команды.
  • Масштабирование: упаковать инструмент в Docker, написать документацию, провести "демо надежности" для других команд.

Когда все научатся простому, можно добавить поддержку многокомпонентных SLO, экспериментов (Chaos Engineering), которые автоматически проверяют устойчивость SLO и многое другое.

Никогда не устану повторять, что внедрение SLO кардинально меняет диалог между разработкой/продуктом и SRE: переходим от "почему все упало?" к "хватит ли у нас бюджета ошибок, чтобы выпустить эту фичу на следующей неделе?".

Это делает надежность измеримой, автоматизированной и, что самое важное, с разделенной ответственностью, равной для всех.