Управление надежностью как код: почему SLO должны быть ресурсами Kubernetes, а не дашбордами
В современной SRE-практике определение целей надежности (SLO) играет ключевую роль. Но на деле они часто фрагментированы: требования живут в Confluence, формулы индикаторов (SLI) — в файлах Prometheus, графики — в Grafana, а алерты — в Alertmanager. Такая архитектура ведет к рассинхронизации при изменениях бизнес-требований, заставляя инженеров вручную обновлять данные. Ошибка или забытая строчка приводят к ложным ночным звонкам дежурным. Надежным решением является переход к концепции «SLO как код» (SLO-as-Code) через Custom Resource Definitions (CRD) в Kubernetes.
Описывая цели надежности в виде YAML-манифестов, мы создаем единый источник истины. Специальный оператор берет на себя рутину по генерации правил Prometheus и панелей Grafana. Любые изменения проходят проверку через GitOps (Pull Requests) и применяются к кластеру автоматически, исключая человеческий фактор.
Ниже приведено руководство по переходу к декларативному управлению SLO с помощью Kubernetes-оператора.
Инструкция по настройке декларативного управления SLO (SLO-as-Code)
1. Подготовка окружения (Prerequisites)
Убедитесь, что в вашем кластере настроены следующие компоненты:
- Установлен оператор Prometheus (Prometheus Operator), поддерживающий работу с кастомными ресурсами
PrometheusRule. Документацию можно изучить по ссылке: Prometheus Operator API. - Настроена система автоматического импорта дашбордов в Grafana из конфигурационных карт Kubernetes (ConfigMap sidecar provisioning).
- Сбор метрик вашего приложения в Prometheus работает стабильно, а метрики содержат чёткие лейблы (labels) для фильтрации по именам сервисов и кодам ответов.
2. Разработка схемы и установка CRD (Custom Resource Definition)
Чтобы API-сервер Kubernetes научился распознавать новый тип объектов, необходимо зарегистрировать схему данных. Создайте файл serviceslo-crd.yaml, описывающий структуру ресурса ServiceSLO. Схема должна содержать описание полей для спецификации: целевой показатель (objective), скользящее окно мониторинга (window), описание индикатора качества (indicator) и параметры отправки алертов (alerting).
Установите CRD в кластер с помощью команды в терминале:
kubectl apply -f serviceslo-crd.yaml
Подробное руководство доступно в официальной документации: Kubernetes CRD Guide.
3. Создание манифеста цели надежности (ServiceSLO)
Создайте файл конфигурации для конкретного микросервиса. Ниже представлен пример манифеста для API оформления заказов (checkout-api) с целевым показателем доступности 99.95% за последние 30 дней:
apiVersion: slo.kubeslo.dev/v1
kind: ServiceSLO
metadata:
name: checkout-availability
namespace: e-commerce
spec:
service: checkout-api
objective: 99.95
window: 30d
indicator:
type: availability
metric: http_requests_total
errorFilter: code=~"5.."
alerting:
burnRates:
- name: critical
shortWindow: 5m
longWindow: 1h
factor: 14.4
4. Разработка управляющего контроллера (Operator Reconciler)
Используя фреймворк kubebuilder или библиотеку controller-runtime на Go, реализуйте цикл синхронизации (reconcile loop) оператора. Логика работы контроллера должна состоять из следующих шагов:
- Получить объект
ServiceSLOпо его имени и пространству имен. - Рассчитать допустимый бюджет ошибок на основе целевого показателя:
errorBudget = 1 - objective / 100. - Сгенерировать ресурс
PrometheusRule, содержащий предварительно рассчитываемые метрики (recording rules) для ускорения запросов. - Сгенерировать второй ресурс
PrometheusRuleс правилами отправки оповещений, используя метод Multi-Burn-Rate. Этот метод требует одновременного превышения порога расхода бюджета как на коротком (5 минут), так и на длинном (1 час) интервале, что позволяет отсечь кратковременные всплески и не спамить дежурных инженеров. - Сформировать ConfigMap с JSON-описанием дашборда для Grafana. Примените к ConfigMap лейблы, которые отслеживает sidecar-контейнер Grafana для автоматического импорта.
5. Настройка связей и автоматической очистки (OwnerReferences)
!IMPORTANT При создании дочерних ресурсов (PrometheusRule и ConfigMap) внутри кода оператора обязательно вызывайте метод
controllerutil.SetControllerReference(). Это устанавливает полеOwnerReferencesв метаданных дочерних объектов, связывая их с родительским ресурсомServiceSLO. Благодаря этому встроенный сборщик мусора Kubernetes (Garbage Collector) автоматически удалит все сгенерированные правила мониторинга и дашборды при удалении исходного манифестаServiceSLO.
6. Периодическая проверка и защита от ручных правок
Контроллер должен не только реагировать на изменения YAML-файлов в Git, но и защищать систему от несанкционированных изменений в обход GitOps. Настройте периодический запуск reconciler (например, каждые 5 минут) с помощью параметра RequeueAfter в возвращаемом значении функции синхронизации. Если дежурный инженер вручную удалит сгенерированное правило в Prometheus или отредактирует дашборд в интерфейсе Grafana, оператор автоматически обнаружит расхождение и перезапишет ресурс дочернего объекта в соответствии с конфигурацией из Git.
Как проверить корректность работы (Verification Actions)
- Примените манифест
ServiceSLOв кластер. Убедитесь, что статус ресурса изменился наReconciled. - Выполните команду
kubectl get prometheusrule -n e-commerceи проверьте, что в пространстве имен появились новые правила с именами видаcheckout-availability-recordingиcheckout-availability-burnrate. - Откройте интерфейс Grafana и найдите автоматически импортированный дашборд с графиком расхода бюджета ошибок для
checkout-api. - Удалите сгенерированный ConfigMap вручную через
kubectl delete configmap. Убедитесь, что в течение 5 минут оператор воссоздал его с исходными настройками.

