Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Prometheus Operator и ServiceMonitor на практике

Prometheus Operator: ServiceMonitor, релизы и мониторинг Kubernetes

Как Prometheus Operator управляет мониторингом в k8s: ServiceMonitor и PodMonitor, настройка релиза, ресурсы Prometheus-пода и миграция со статического конфига.

Прямой ответ

Проблема без оператора: Prometheus в k8s — статический prometheus.yml в ConfigMap (конфигурация — «новый сервис — правка конфига+reload — кто-то забыл — сервис без мониторинга» — drift); Prometheus Operator — декларативное управление через CRD: Prometheus (спецификация самого сервера — реплики/ресурсы/retention/storage — ресурсы-контекст), ServiceMonitor (что скрейпить: «сервисы с лейблом app и портом metrics, путь /metrics, интервал 30s» — оператор транслирует в скрейп-конфиг — сервис регистрирует мониторинг сам — лейблом на своём Service — микросервисы — «новый сервис — добавил лейбл — метрики подхватились» — drift исключён), PodMonitor (скрейп подов напрямую — без Service — джобы/sidecar'и — k8s-сети), PrometheusRule (алерт/recording-правила как CRD — правила — алерты), Alertmanager (CRD-спецификация AM-кластера — Alertmanager), Probe (внешние blackbox-чеки — healthcheck); установка — kube-prometheus-stack (helm-чарт: Operator + Prometheus + Grafana + Alertmanager + node-exporter + дашборды (Grafana) — «мониторинг k8s за одну команду» — helm-практика — values-файл в git — IaC — helmfile/argocd — деплой-стратегии); ServiceMonitor-анатомия (минимум): selector.matchLabels (какие Service — лейбл-контракт — команда договаривается: «порт называется metrics» — метрики-инструментация), endpoints (port: metrics, interval: 30s, path: /metrics — scrapeTimeout < interval — таймауты), namespaceSelector (свои/выбранные/все namespace — RBAC оператора — доступы); типичные поломки (первый день): метрики не появились — чек-лист: лейбл Service не совпал с selector (90% случаев — kubectl get servicemonitor -o yaml против лейблов сервиса), порт назван иначе (endpoints.port — имя порта Service, не число — сервисы-механика), RBAC оператора не видит namespace (namespaceSelector + права — networkpolicy-не-мешает — скрейп-трафик разрешить — netpol), target down в Prometheus UI (Service Discovery → targets — ошибка видна — «connection refused» — приложение не слушает/путь неверный — метрики-эндпоинт); ресурсы Prometheus-пода (главная прод-забота): retention+ряды → диск/RAM (ёмкость-методика — storageSpec volumeClaimTemplate (PVC — хранение — не emptyDir — «Prometheus пересоздался — история пропала»), resources.requests по замерам (кардинальность — 1M рядов — 2–4 ГБ RAM ориентир — свои замеры — метрики); когда Operator избыточен: один Prometheus вне k8s (статический конфиг проще — мониторинг-стек), vmagent-путь (VictoriaMetrics — VM-operator или vmagent+ServiceMonitor-совместимость — выбор — VM).

Практика: шардирование, HA и большие кластеры

Рост нагрузки (500+ таргетов): один Prometheus упирается (скрейпы+хранение — ёмкость); решения: shards в CRD Prometheus (shards: 3 — оператор разнесёт таргеты по хешу — три Prometheus-пода — запросы через Thanos query/Mimir/прокси — Mimir-контекст); HA-пары (replicas: 2 — две идентичные копии (external-label replica — дедупликация на чтении — Thanos/Mimir/VM (dedup — «Prometheus умер — метрики пишутся» — failover-аналогия); remote write (Mimir/VM — локальный retention короткий (48ч — буфер/алерты), глобальное хранение — внешнее — Mimir/VM — паттерн «локально свежее, глобально всё» — метрики-архитектура); алерты — локальный evaluation (правила в PrometheusRule — данные свежее remote-write-пути — алерт-латентность — Alertmanager-кластер (CRD — 3 реплики — gossip-дедуп — Alertmanager); миграция со статического конфига: параллельно (Operator-стек поднимается рядом, статический продолжает — миграция-осторожность), таргеты → ServiceMonitor'ы (скрейп-джобы → CRD — по сервису — сверка targets — сверка-культура), правила → PrometheusRule (файлы → CRD — правила — тесты promtool переносятся), Grafana-datasource свитч (Grafana), отключение старого; апгрейды стека: helm-чарт версии (kube-prometheus-stack мажоры — breaking CRD-изменения — changelog — зависимости — стейдж сначала — флаги-постепенность — «обновили оператор в проде» — CRD-конфликт — ревью); self-monitoring оператора (метрики оператора/Prometheus-цели — «мониторинг не мониторится» — мета-алерты (healthcheck — dead man's switch — алерт-дизайн).

Практический сценарий: 30 сервисов без мониторинга → полный охват за неделю

Контекст: k8s-кластер, 30 микросервисов, Prometheus — статический (12 джоб в ConfigMap — добавлялись «когда вспомнят» — 18 сервисов без метрик — техдолг), инцидент-триггер: «сервис лежал 3 часа — метрик нет — увидели по жалобам» (incident); план (неделя): (1) kube-prometheus-stack (helm — values в git (IaC — Grafana/Alertmanager из чарта — дашборды k8s из коробки (Grafana); (2) контракт инструментации (командное решение — ADR: Service каждого приложения — лейбл monitoring: enabled + порт с именем metrics (метрики-эндпоинт — FastAPI/gunicorn — /metrics); (3) универсальный ServiceMonitor (один на кластер — selector по лейблу контракта — все namespace — «сервис соблюдает контракт — мониторится автоматически» — не 30 ServiceMonitor'ов — один паттерн — шаблонизация); (4) прополка 18 отстающих (инструментация /metrics (метрики — библиотека+3 строки) + лейблы — по сервису за PR — CI — покрытие — дашборд «сервисы с/без метрик» (Grafana — прогресс виден — техдолг-волна); (5) правила (PrometheusRule: базовые (pod down/restart-loop/OOM — ресурсы — cgroups-контекст), SLO-шаблон (SLO — по сервисам — burn rate — алерты); (6) проверка боем (chaos: убили pod сервиса — алерт за 90 секунд (chaos — против 3 часов тишины — цель достигнута — incident-метрики); (7) попутно: Kyverno-политика «новый Deployment без metrics-порта — warn» (Kyverno — контракт enforced — «забыли инструментировать» — подсказка на деплое — политики); итоги: охват 40% → 100% за неделю, MTTD 3 ч → 2 мин, новый сервис онбордится в мониторинг лейблом (0 минут ручной настройки — платформа-мышление); вывод: ценность оператора — не «удобные YAML», а контракт (сервис сам declares мониторинг — оператор гарантирует подхват — drift невозможен — IaC-культура — «мониторинг как код сервиса» — структура).

FAQ

ServiceMonitor не подхватывается — где искать? Чек-лист (по частоте): (1) selector-лейблы (matchLabels ServiceMonitor против фактических лейблов Service — kubectl get svc --show-labels — совпадение полное — регистр/опечатки — 90% случаев); (2) имя порта (endpoints[].port — имя порта из Service.spec.ports (не 8080, а "metrics" — безымянный порт — не сматчится — сервисы); (3) namespaces (namespaceSelector: any против конкретного — оператор с RBAC только в своих — доступы — kubectl auth can-i — RBAC-проверка); (4) Prometheus-спецификация (serviceMonitorSelector/serviceMonitorNamespaceSelector в CRD Prometheus — «ServiceMonitor создан, но Prometheus его не выбирает» — двойная селекция — частая неочевидность); (5) targets в UI (Prometheus → Status → Targets — ошибка scrape видна (метрики-отладка — connection refused — приложение/путь; timeout — scrapeTimeout — таймауты); (6) NetworkPolicy (netpol — скрейп-трафик от Prometheus-пода разрешён — default-deny — «метрики блокированы политикой» — Hubble/Cilium покажет дроп — eBPF); отладка-команда: kubectl get --raw "/apis/monitoring.coreos.com/v1/servicemonitors" + логи оператора — логи-практика.

Prometheus Operator или vmagent/свой скрейпер? Operator: полный стек CRD (Prometheus/AM/правила — «всё декларативно» — зрелость/сообщество — kube-prometheus-stack — сценарий выше); vmagent: легче (10–30 МБ — скрейпы+remote write — ServiceMonitor-совместимость через VM-operator (VM — «Operator-UX, VM-эффективность» — VM-operator CRD — VMAgent/VMAlert/VMRule); критерии: полный Prometheus-стек нужен (локальное хранение+запросы+алерты) — Operator, сбор в центральное хранилище (Mimir/VM — архитектура — edge-скрейпер — vmagent/Alloy (Alloy — «собираем и шлём»); гибрид-норма: Operator управляет Prometheus (алерты локально), remote write в VM/Mimir (история) — метрики-паттерн; «свой скрейпер» — почти никогда (Service Discovery k8s — сложность — операторы решают — выбор — не изобретать — техдолг).

Как хранить данные Prometheus в k8s правильно? storageSpec в CRD (volumeClaimTemplate — PVC — тома — StorageClass с быстрым диском — ёмкость-диск — WAL+TSDB — IO-чувствительны — диск-диагностика); размер: retention × скорость роста (ряды × retention — кардинальность — эмпирика: 1M рядов/15 дней ≈ 30–60 ГБ — свои замеры — метрики — запас ×1.5 — расширение PVC — k8s-resize); «emptyDir» — антипаттерн (pod-пересоздание — история+WAL мертвы — «метрики пропали» — failover-контекст); retention-стратегия: локально — короткое (48ч–7д — буфер+алерты+расследования «сейчас»), долго — remote (Mimir/VM — «локальный Prometheus — не архив» — метрики-архитектура); бэкап TSDB: снапшоты-обязательны? обычно нет (метрики — не платежи (идемпотентность) — потеря часов — приемлема — SLO-контекст; SLO-история — из remote-хранилища с его бэкапами (3-2-1 — Mimir); антипаттерн: NFS для TSDB (блокировки/латентность — WAL-коррупция — «дешёвый NFS» — дорога к потерянным данным — диск-практика).

Что с RBAC и безопасностью оператора? Принцип: оператору — минимум (Service/Pod/Endpoint-чтение в наблюдаемых namespace — namespaceSelector ограничивает (доступы — ClusterRole «всё везде» — удобно и опасно — OWASP-k8s); ServiceMonitor как вектор (кто может создать ServiceMonitor — может скрейпить любой pod namespace'а (secret-эндпоинты — «/metrics админ-панели с чувствительными метриками» — RBAC на создание SM — ограничение namespace — политики); секреты в скрейпах (bearer_token_file/basic_auth — Secret-ссылки в endpoints — секреты — не инлайн — vault-культура); метрики как канал утечки (labels с чувствительными значениями (кардинальность-контекст — email/user_id в лейблах — и метрика, и PII-дыра — OWASP — ревью инструментации — ревью); Prometheus UI (не наружу без auth — ingress+basic/oauth (ingress — «Prometheus наружу» — данные/конфиги видны — харднинг); аудит: оператор-обновления (CVE — Trivy-скан — чарт-версии — Dependabot — инфраструктура-зависимости тоже — supply chain).

Источники: документация Prometheus Operator, kube-prometheus-stack chart — ссылки в шапке.