В 2026 году мониторинг сервисов и приложений в Kubernetes строится на связке Prometheus v3, Prometheus Operator, Grafana и Alertmanager. Этот стек закрывает три задачи: сбор метрик с сервисов и подов, автоматическое обнаружение новых целей, алертинг по SLO. Ниже разобраны рабочие ServiceMonitor, PodMonitor, правила бюджета ошибок и чек-лист для продакшена.
Главный принцип: Prometheus работает в pull-режиме и забирает метрики из эндпоинтов /metrics. Оператор управляет целями через CRD, поэтому менять prometheus.yml вручную не нужно. При добавлении сервиса с нужными labels оператор создает scrape-конфиг и Prometheus начинает собирать метрики без перезагрузки.
Материал рассчитан на DevOps-инженеров и администраторов кластеров Kubernetes 1.30+. Все примеры проверены на Prometheus Operator и kube-prometheus-stack.
Архитектура мониторинга Kubernetes-кластера в 2026
Стек выглядит так: Prometheus v3 хранит метрики и выполняет PromQL, Prometheus Operator преобразует ServiceMonitor/PodMonitor в scrape-конфиг, Alertmanager маршрутизирует уведомления, Grafana отображает дашборды. К этому добавляются kube-state-metrics и node-exporter.
Компоненты стека: Prometheus, Operator, Grafana, Alertmanager
Prometheus собирает и хранит временные ряды, не зависит от внешней БД. Operator следит за объектами Kubernetes и генерирует конфигурацию сбора. Grafana подключается к Prometheus как к источнику данных. Alertmanager принимает алерты, группирует, дедуплицирует и отправляет в Slack, Telegram, почту.
kube-state-metrics отдает состояние объектов: реплики Deployment, статусы Pod, ресурсы Job. node-exporter собирает CPU, память, диск и сеть с каждого узла. Эти два компонента закрывают уровень инфраструктуры, а ServiceMonitor/PodMonitor закрывают уровень сервисов и приложений. Настройка kube-state-metrics и node-exporter с готовыми PromQL-запросами разобрана в статье про сбор метрик CPU, памяти, диска и сети.
Почему ServiceMonitor и PodMonitor заменили статичный prometheus.yml
В статичном prometheus.yml цель описывалась вручную: адрес, порт, путь, интервал. При каждом изменении Service или Pod требовалась правка файла и reload Prometheus. В динамичной среде Kubernetes это не работает. ServiceMonitor и PodMonitor объявляют цели через Kubernetes API. Operator смотрит на labels и namespace, автоматически генерирует scrape-конфиг и перезапускает Prometheus при изменениях.
Результат: новый Deployment с label app: api и Service с нужным портом попадает в мониторинг без ручных действий. Это ключевое отличие от Prometheus вне Kubernetes.
Установка и подготовка Prometheus Operator
Установка kube-prometheus-stack в кластер
Рекомендуемый способ - Helm. Создайте namespace monitoring и установите chart:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
kubectl create namespace monitoring
helm install monitoring prometheus-community/kube-prometheus-stack -n monitoring --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false --set prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValues=false
Эти параметры включают подхват ServiceMonitor/PodMonitor во всех namespace. CRD ставятся вместе с chart, но при обновлении chart'а CRD лучше обновлять отдельно. Полная пошаговая установка с Grafana и Alertmanager описана в отдельном руководстве.
Если под рукой нет кластера, для проверки конфигураций подойдет managed Kubernetes в Timeweb Cloud. Для продакшена выделите отдельный namespace monitoring и ограничьте доступ.
Проверка CRD и доступности Prometheus
Проверьте, что CRD установлены:
kubectl get crd | grep monitoring.coreos.com
kubectl get pods -n monitoring
kubectl get servicemonitors,podmonitors -A
Откройте Prometheus UI через port-forward:
kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090
В браузере http://localhost:9090 откройте Status > Targets, чтобы видеть цели. Если CRD не появились, проверьте версию chart'а и наличие прав на создание CRD в кластере.
Мониторинг Kubernetes-сервисов через ServiceMonitor
Создание ServiceMonitor для HTTP-сервиса
ServiceMonitor привязывается к Service по labels, а не к Pod напрямую. Для Service с меткой app: api и портом http манифест выглядит так:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: api
namespace: backend
spec:
selector:
matchLabels:
app: api
endpoints:
- port: http
interval: 30s
path: /metrics
scheme: http
Порт http должен совпадать с именем порта в Service. Не указывайте номер порта как число, поскольку Operator сопоставляет endpoint по имени порта. ServiceMonitor должен находиться в namespace, который разрешен в serviceMonitorNamespaceSelector объекта Prometheus.
Привязка ServiceMonitor к Prometheus: serviceMonitorSelector и namespaceSelector
ServiceMonitor не подхватывается автоматически. Prometheus CR указывает, какие ServiceMonitor и из каких namespace брать:
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: k8s
namespace: monitoring
spec:
serviceAccountName: prometheus-k8s
serviceMonitorSelector:
matchLabels:
team: backend
serviceMonitorNamespaceSelector:
matchNames:
- backend
Если нужно собирать все ServiceMonitor во всех namespace, установите пустые селекторы: serviceMonitorSelector: {} и serviceMonitorNamespaceSelector: {}. Это удобно на старте, но в большом кластере приводит к массовому сбору нецелевых метрик. Лучше сразу использовать matchLabels.
В kube-prometheus-stack эти параметры можно задать через values.
Настройка TLS, аутентификации и базового relabeling
Для HTTPS-эндпоинта с клиентским сертификатом, токеном или basic auth используйте блок tlsConfig, bearerTokenSecret или basicAuth:
endpoints:
- port: https
interval: 30s
scheme: https
tlsConfig:
ca:
secret:
name: api-ca
key: ca.crt
insecureSkipVerify: false
bearerTokenSecret:
name: api-token
key: token
relabelings:
- sourceLabels: [__meta_kubernetes_namespace]
targetLabel: namespace
- sourceLabels: [__meta_kubernetes_service_name]
targetLabel: service
insecureSkipVerify: false оставляйте в продакшене. Секреты должны лежать в namespace ServiceMonitor'а. relabelings добавляют постоянные метки namespace и service, чтобы не полагаться на служебные __meta_*.
Типовые ошибки при настройке ServiceMonitor
- Label Service не совпадает с
selector.matchLabels. Проверьтеkubectl get svc -n backend --show-labels. - В
portуказан номер порта вместо имени. Используйте имя порта из Service. - ServiceMonitor создан в namespace, который не разрешен. Проверьте
serviceMonitorNamespaceSelector. - Нет прав RBAC у Prometheus на чтение Service/Pod. Смотрите логи operator'а и события.
- Target down из-за TLS: сертификат не подписан вашим CA или CN не совпадает.
Быстрый признак: в Prometheus UI цель находится в состоянии DOWN с ошибкой скрейпинга. Текст ошибки указывает на причину.
PodMonitor: сбор метрик с подов напрямую
Когда PodMonitor предпочтительнее ServiceMonitor
ServiceMonitor балансирует запросы через Service и зависит от эндпоинтов. PodMonitor скрейпит каждый Pod напрямую по IP. Выбирайте PodMonitor, если Service не создан, метрики отдают отдельные pod'ы stateful-нагрузок, или в поде несколько контейнеров и метрики лежат в sidecar. При наличии стабильного Service чаще используют ServiceMonitor.
Пример PodMonitor для приложения с sidecar-метриками
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: worker-sidecar
namespace: backend
spec:
selector:
matchLabels:
app: worker
namespaceSelector:
matchNames: [backend]
podMetricsEndpoints:
- port: metrics
interval: 15s
path: /metrics
relabelings:
- sourceLabels: [__meta_kubernetes_pod_name]
targetLabel: pod
- sourceLabels: [__meta_kubernetes_namespace]
targetLabel: namespace
Prometheus скрейпит каждый под с label app: worker и портом metrics. Если порт открыт только в sidecar-контейнере, Operator все равно найдет endpoint по имени порта. Один PodMonitor может собирать метрики со всех подов приложения, а relabeling добавляет имена pod и namespace.
Автоматическое обнаружение сервисов и подов в Kubernetes
Селекторы и namespaceSelector: управление автодобавлением целей
Оператор через Kubernetes API находит объекты, которые подходят под selectors. Для автоматического включения только нужных сервисов используйте matchLabels или matchExpressions. Пример для Prometheus CR, который берет только namespace production и сервисы с меткой monitoring: enabled:
serviceMonitorSelector:
matchLabels:
monitoring: enabled
serviceMonitorNamespaceSelector:
matchNames:
- production
Исключить системные namespace можно с помощью matchExpressions с operator NotIn. При таком подходе новый сервис попадает в Prometheus после установки двух меток: monitoring: enabled на ServiceMonitor и namespace production.
Совместимость с аннотациями prometheus.io/scrape
Prometheus Operator поддерживает legacy-аннотации на Service и Pod: prometheus.io/scrape: 'true', prometheus.io/port: '8080', prometheus.io/path: '/metrics'. Он конвертирует их в ServiceMonitor/PodMonitor. Это удобно при миграции с обычного Prometheus, но CRD дает больше контроля: TLS, интервалы, relabeling, отдельные namespace. Для новых проектов используйте CRD.
Relabeling: из метаданных Kubernetes в метки Prometheus
Prometheus при обнаружении целей получает служебные метки __meta_kubernetes_*. Их нужно превращать в постоянные метки или удалять. Основные действия: keep, drop, replace, labelmap, labeldrop.
relabelings:
- action: keep
sourceLabels: [__meta_kubernetes_service_label_monitoring]
regex: enabled
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- sourceLabels: [__meta_kubernetes_namespace]
targetLabel: namespace
action: replace
- regex: __meta_kubernetes_pod_label_pod_template_hash
action: labeldrop
Правило keep оставляет только сервисы с меткой monitoring=enabled. labelmap переносит все service labels в обычные метки. labeldrop убирает ненужные служебные метки, чтобы не раздувать кардинальность.
Метрики приложений в Kubernetes: что собирать и как отдавать
Эндпоинт /metrics и клиентские библиотеки
Приложение должно открыть HTTP-эндпоинт /metrics и отдавать метрики в текстовом формате Prometheus. Пример строки:
request_duration_seconds_bucket{le='0.1'} 42
requests_total{code='200',method='get'} 1280
Для инструментирования используйте официальные клиентские библиотеки: client_golang для Go, prom-client для Node.js, Micrometer для Java, prometheus_client для Python. Счетчики (counter) подходят для числа запросов и ошибок, гистограммы - для длительности. Отделяйте gauge для текущей очереди, активных соединений, размера пула.
Метрики RED отвечают на вопросы: rate запросов, ошибки, длительность. Метрики USE показывают утилизацию, насыщение и ошибки ресурсов. Для HTTP-сервиса начинайте с RED.
Экспортеры для баз данных, очередей и внешних систем
PostgreSQL, Redis, Kafka не отдают метрики в формате Prometheus нативно. Запускайте экспортеры sidecar-контейнером или отдельным Deployment с Service. Популярные: postgres_exporter, redis_exporter, kafka_exporter. После запуска создайте ServiceMonitor для Service экспортера.
Для ресурсов узлов и состояния объектов уже используются node-exporter и kube-state-metrics. Настройка этих компонентов и готовые PromQL-запросы описаны в статье про сбор метрик CPU, памяти и диска.
OpenTelemetry и Prometheus: что выбрать
OpenTelemetry может передавать метрики в Prometheus через OTLP HTTP или через Prometheus exporter. Если кластер уже работает на Prometheus, используйте инструментирование, совместимое с /metrics, а OpenTelemetry вводите постепенно для трассировок. Резкий переход на OTLP без необходимости увеличивает число движущихся частей. Ценность OpenTelemetry заметна в распределенной трассировке, а для метрик Prometheus v3 остается основным хранилищем.
Алертинг на основе SLO: от метрик к надёжности сервисов
SLI и SLO: как выбрать показатели для сервиса
SLI - факт: процент успешных запросов за период, задержка 95-го перцентиля. SLO - цель: 99.9% доступности за 30 дней, 95% запросов быстрее 300 мс. SLA добавляет договор и штрафы. Для HTTP-сервиса базовые SLI: доступность (все запросы, кроме 5xx, от всех запросов), латентность (p95/p99), насыщение очереди.
Формулируйте SLO конкретно. Не используйте 100%, потому что каждая ошибка станет критичной. Начните с 99.9% для внешних API.
PromQL для бюджета ошибок и burn rate
Бюджет ошибок - допустимая доля неудачных запросов: 1 - SLO. Для SLO 99.9% бюджет равен 0.001. Burn rate показывает, как быстро расходуется этот бюджет. Формула для отношения ошибок за 5 минут:
sum(rate(requests_total{code=~'5..'}[5m]))
/
sum(rate(requests_total[5m]))
Чтобы получить burn rate, разделите ошибки на бюджет ошибок:
sum(rate(requests_total{code=~'5..'}[5m]))
/
sum(rate(requests_total[5m]))
/
0.001
Burn rate 1 означает, что бюджет расходуется ровно с допустимой скоростью. Burn rate 14.4 за час показывает, что за 1 час вы сожжете бюджет за 30 дней. Используйте rate() вместо increase() для корректной экстраполяции на коротких окнах.
Создание алерт-правил и связь с Alertmanager
Задайте PrometheusRule с критическим и предупреждающим уровнями:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: api-slo
namespace: backend
spec:
groups:
- name: api-slo
rules:
- alert: APIBurnRateCritical
expr: sum(rate(requests_total{code=~'5..'}[5m])) / sum(rate(requests_total[5m])) / 0.001 > 14.4
for: 5m
labels:
severity: critical
annotations:
summary: 'API burn rate критический'
description: 'Бюджет ошибок расходуется слишком быстро: burn rate > 14.4 за 5 минут.'
- alert: APIBurnRateWarning
expr: sum(rate(requests_total{code=~'5..'}[5m])) / sum(rate(requests_total[5m])) / 0.001 > 3
for: 10m
labels:
severity: warning
annotations:
summary: 'API burn rate повышен'
Alertmanager маршрутизирует их по severity: critical в Slack, warning в почту. Подробный разбор контроля SLA распределенных систем есть в руководстве по Prometheus и Grafana для контроля SLA.
Алерты используют метки, добавленные при сборе через relabeling. Если в PromQL нет метки service, группировка по сервису невозможна.
Лучшие практики 2026: производительность, безопасность и масштабирование
Контроль кардинальности и именование меток
Кардинальность - число уникальных временных рядов. Высокая кардинальность замедляет PromQL и увеличивает потребление памяти. Не добавляйте в метки userId, requestId, sessionId. Используйте exemplars для привязки трассировки к конкретному запросу. Договоритесь о метках namespace, service, pod. Кардинальность выше 1 млн рядов требует шардирования.
Recording rules и оптимизация запросов
Тяжелые запросы с агрегацией выполняйте заранее через recording rules:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: api-record
namespace: backend
spec:
groups:
- name: api-rates
rules:
- record: job:requests:rate5m
expr: sum(rate(requests_total[5m])) by (service)
Дашборды Grafana читают готовый ряд job:requests:rate5m, а не пересчитывают rate каждый раз. Это снижает нагрузку на Prometheus и ускоряет графики.
Безопасность сбора метрик: RBAC, TLS, NetworkPolicy
Ограничьте RBAC для Prometheus service account. Ему нужны права на чтение pods, services, endpoints, nodes. Не выдавайте cluster-admin. Для скрейпинга используйте tlsConfig в ServiceMonitor. Сетевую политику настройте так, чтобы только Prometheus подключался к портам метрик:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-prometheus-metrics
namespace: backend
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- port: http
Замените port: http на порт метрик. NetworkPolicy добавляет второй рубеж после TLS.
Масштабирование: remote_write, Thanos, VictoriaMetrics
Для кластеров до 100 узлов одного Prometheus достаточно. При росте используйте remote_write для долгого хранения, федерацию для разделения нагрузки, Thanos для HA и объектного хранилища, VictoriaMetrics как совместимую альтернативу. Сначала контролируйте кардинальность и запросы, потом масштабируйте хранилище. Готовые дашборды и связку мониторинга с GitLab для SRE можно посмотреть в практике по наблюдаемости высоконагруженных систем.
Отладка и проверка мониторинга Kubernetes: чек-лист
Как проверить target в Prometheus
Откройте Prometheus UI: Status > Targets. Каждая цель имеет state UP/DOWN, endpoint и ошибку. Если target DOWN, читайте ошибку скрейпинга. Проверьте, что job соответствует ServiceMonitor/PodMonitor. Для поиска конкретного сервиса используйте фильтр по label service.
Диагностика ServiceMonitor и PodMonitor через логи Operator
kubectl describe servicemonitor api -n backend
kubectl get events -n monitoring --sort-by=.lastTimestamp
kubectl logs -n monitoring deploy/kube-prometheus-stack-operator
Частые причины отсутствия цели: label не совпал, endpoint port не существует в Service, у Prometheus нет прав, ServiceMonitor в неймспейсе вне selector'а. Оператор пишет в логи ошибки reconciliation.
Production-чек-лист внедрения
- CRD мониторинга установлены и версия совместима с Operator.
- Включены алерты критического уровня и проверена доставка в Alertmanager.
- Для скрейпинга включен TLS,
insecureSkipVerify: false. - Ограничены
serviceMonitorSelectorиnamespaceSelector. - Настроен remote_write или локальное хранилище с retention.
- Метрики приложений отдают
/metrics, документация для команды есть. - Проверены цели в Prometheus UI после каждого деплоя.
Мониторинг живет рядом с приложением. Если ServiceMonitor лежит в другом namespace или использует жесткие label, он ломается при рефакторинге. Разбирайте ошибки через диагностику Pods и узлов по метрикам, если деградация сервиса уже произошла.