Prometheus — мониторинг и алерты
Prometheus — система мониторинга с открытым кодом. Она собирает метрики с серверов и приложений по расписанию, хранит их и позволяет строить по ним запросы, правила алертов и графики. Вместе с Grafana это стандарт де-факто мониторинга в мире DevOps.
1. Как это работает
- Pull-модель — Prometheus сам обращается к целевой службе за метриками;
- Экспортеры — небольшие агенты, которые отдают метрики в формате Prometheus;
- Метрики — числа с метками (labels) и временем сбора;
- PromQL — язык запросов для анализа и правил.
2. Установка
wget https://github.com/prometheus/prometheus/releases/download/v3.14.0/prometheus-3.14.0.linux-amd64.tar.gz
tar xzf prometheus-3.14.0.linux-amd64.tar.gz
cd prometheus-3.14.0.linux-amd64
./prometheus --config.file=prometheus.ymlUI доступен на http://localhost:9090.
docker run -p 9090:9090 prom/prometheus.3. Структура метрик
Метрика — это имя + метки + значение + временная метка:
node_cpu_seconds_total{mode="user", instance="server1:9100"} 12345.7Типы метрик
| Тип | Описание | Пример |
|---|---|---|
| Counter | только растёт (счётчик событий) | requests_total |
| Gauge | может падать и расти (значение) | temperature_celsius |
| Histogram | распределение значений по корзинам | request_duration_seconds |
| Summary | квантили на стороне приложения | latency_summary |
4. targets и scrape_configs
Список «целей» для сбора задаётся в prometheus.yml:
scrape_configs:
- job_name: node
metrics_path: /metrics
static_configs:
- targets: ["server1:9100", "server2:9100"]
- job_name: app
metrics_path: /actuator/prometheus
static_configs:
- targets: ["app-host:8080"]5. Экспортеры
# node_exporter — метрики ОС
wget https://github.com/prometheus/node_exporter/releases/download/v1.12.1/node_exporter-1.12.1.linux-amd64.tar.gz
tar xzf node_exporter-1.12.1.linux-amd64.tar.gz
./node_exporter # порт 9100
# blackbox_exporter — проверка доступности HTTP/TCP/ICMPГотовые экспортеры
| Экспортер | Что мониторит |
|---|---|
| node_exporter | CPU, память, диск, сеть ОС |
| mysqld_exporter | MySQL |
| postgres_exporter | PostgreSQL |
| redis_exporter | Redis |
| blackbox_exporter | доступность сервисов |
6. PromQL — язык запросов
PromQL позволяет выбирать и агрегировать метрики:
up // по всем целям
node_memory_MemAvailable_bytes // конкретная метрика
rate(http_requests_total[5m]) // скорость за последние 5 минут
sum(rate(http_requests_total[5m])) by (job) // сумма по jobЧастые операторы и функции
| Выражение | Смысл |
|---|---|
| rate(m[5m]) | скорость роста counter за окно |
| increase(m[1h]) | прирост за час |
| avg / sum / max / min | агрегация |
| by (label) / without (label) | группировка |
| {instance="x"} | фильтр по метке |
7. Правила и алерты
Правило — запрос, который проверяется по расписанию. Файл rules.yml подключается в конфиг:
rule_files:
- rules.ymlgroups:
- name: node
rules:
- record: instance:node_cpu_usage
expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
- alert: NodeDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Нода {{ $labels.instance }} недоступна"8. Alertmanager
Alertmanager принимает алерты и рассылает уведомления (email, Telegram, Slack):
route:
receiver: team
receivers:
- name: team
email_configs:
- to: ops@example.com./alertmanager --config.file=alertmanager.yml9. Хранение данных
По умолчанию данные сохраняются локально в ./data:
./prometheus \
--config.file=prometheus.yml \
--storage.tsdb.retention.time=30d \
--storage.tsdb.retention.size=50GB10. Интеграция с Kubernetes
Prometheus понимает service discovery: цели находятся не вручную, а из API кластера Kubernetes:
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: "true"11. Визуализация
Графики удобнее строить в Grafana, которая подключается к Prometheus как датасорс. Типовой стек мониторинга:
node_exporter + Prometheus + Grafana + Alertmanager12. Экспорт метрик из своего приложения
Библиотеки клиентов для Python, Go, Java и др. отдают метрики по адресу /metrics:
# Python, библиотека prometheus_client
from prometheus_client import Counter, start_http_server
REQUESTS = Counter("http_requests_total", "Всего запросов")
def handler():
REQUESTS.inc()
start_http_server(8000) # /metrics на 8000Названия метрик пиши по конвенции: суффикс _total для counter, _seconds для времени, юниты в имени.
http_requests_total{method="get", status="200"} 42
process_cpu_seconds_total 123.713. Долгосрочное хранение: remote write
Локальный TSDB рассчитан на недели-месяцы. Для года данных используют remote-write в векторные хранилища:
remote_write:
- url: http://thanos-receiver:19291/api/v1/receive
queue_config:
max_samples_per_send: 10000- Thanos — сжатие и запрос по нескольким Prometheus;
- VictoriaMetrics — высокая плотность и простой деплой;
- Cortex / Mimir — мультитенантность для команд;
- хранение в S3-совместимом объектном хранилище — стандарт.
14. SLO и burn rate алерты
Вместо точечных границ по одной метрике считай SLO — целевую доступность сервиса за окно времени:
error_ratio = sum(rate(http_requests_total{status=~"5.."}[30m]))
/ sum(rate(http_requests_total[30m]))Burn rate алерт: если ошибки за короткое окно превышают бюджет «сжигания» — это деградация, а не единичный блип.
- держи несколько окон: 5m, 60m и 30d;
- длинное окно срабатывает только при устойчивом нарушении;
- разделяй техно-метрики (CPU) и пользовательские (ошибки API).
15. Чек-лист продакшена
- все цели доступны:
up == 1без пропусков scrape; - есть алерты на NodeDown, HighCPU, Diskspace, 5xx;
- Alertmanager настроен на два канала (чат и почту) с эскалацией;
- заданы retention, remote write и бэкапы конфигов;
- документированы новые метрики приложения;
- дашборды покрывают ключевые пользовательские сценарии.
Начни с малого: node_exporter + базовые алерты, затем экспорт приложения, потом Thanos, если объёмы растут. Мониторинг строится итеративно.
16. Продвинутый PromQL: гистограммы и сравнение векторов
Настоящая ценность PromQL раскрывается при работе с гистограммами и бинарными операторами:
// 95-й перцентиль задержки из Histogram
histogram_quantile(0.95,
sum by (le) (rate(http_request_duration_seconds_bucket[5m])))
// отклонение от среднего по всем сервисам
node_cpu_usage - avg(node_cpu_usage)
// топ-3 по ошибкам
topk(3, sum(rate(http_errors_total[5m])) by (job))offset 1hсдвигает запрос в прошлое — для «сравни с прошлым часом»;- бинарные операторы по вектору требуют одинаковых меток — исправляй через
on()/ignoring(); - гистограмма складывается через
sum by (le), иначе кумулятивность ломается.
17. Kubernetes: kube-prometheus и kube-state-metrics
Поверх service discovery из курса Kubernetes ставят готовый стек kube-prometheus: Operator, правила, dashboards и ServiceMonitors:
// ServiceMonitor может «прицелиться» на конкретный deployment
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata: { name: api-sm, namespace: production }
spec:
selector:
matchLabels: { app: api }
endpoints:
- port: metrics
interval: 30s- kube-state-metrics отдаёт «желаемое» состояние: реплики, деплойменты, поды;
- kubelet/cAdvisor даёт метрики контейнеров: cpu, memory, network;
- правила kube-prometheus уже дают NodeDown, CrashLoopBackOff и другие базовые алерты;
- Prometheus Operator управляет конфигом декларативно — без правки yaml руками.
18. Pushgateway и метрики batch-задач
Pull-модель не подходит для короткоживущих задач (cron, пайплайны): процесс закончился раньше, чем Prometheus успел его опросить. Для них — Pushgateway:
# после успешного прогона батча
cat batch_result.prom | curl --data-binary @- \
http://pushgateway:9091/metrics/job/batch/stage/sync# статус в PromQL
batch_last_success_time{job="cron_sync"} > time() - 3600 # алерт, если давно не было- метрики «последнего прогона» — время, статус, число обработанных;
- никогда не используй Pushgateway вместо pull для сервисов;
- перед новым прогоном удаляй старые метрики через DELETE по группе, иначе группировка плывёт.
19. Отказоустойчивость и HA-стек
Один Prometheus — точка отказа. Классический HA-расклад — два независимых экземпляра + Thanos для чтения слитно:
Prometheus A ┐
├─> Thanos Query ─> Grafana
Prometheus B ┘
└─> Thanos Store ─> S3 (долгий retention)- identical выкатка: оба Prometheus с одинаковым конфигом и правилами;
--query.partition-query-by-tenantи дедупликация в Thanos Query;- правила алертов — не на каждом экземпляре одинаково, а через Grafana или центральный Router;
- проверяй «выживание»: выключи один Prometheus и убедись, что алерты живут.
20. Self-мониторинг: метрики самого Prometheus
Prometheus собирает данные о себе на /metrics — добавь их в собственный dash-борд. Параметры, за которыми стоит следить:
# базовые метрики self-monitoring
prometheus_tsdb_head_series # активные серии в TSDB
prometheus_tsdb_head_samples_appended_total # скорость приёма samples
prometheus_remote_storage_pending_samples # очередь remote write- рост head_series — сигнал о высокой кардинальности или «утечке» серий;
- pending samples в remote write — промет сервер не успевает выгружать данные;
- Prometheus тоже нужно измерять: добавь себя в scrape_configs как обычный target;
- веди «alert-требование»: если мониторинг постоял — первым делом чини его, а не данные.
21. Relabeling: управление метками перед записью
Метки определяют кардинальность и удобство запросов. Два уровня перезаписи: target relabel (до сбора) и metric relabel (после сбора):
scrape_configs:
- job_name: app
relabel_configs: # до scrape
- source_labels: [__scheme__, __address__]
target_label: endpoint
metric_relabel_configs: # после scrape
- source_labels: [status]
regex: 'ok|success'
action: drop- relabel_configs правит адрес и метки таргета (например, добавляет environment);
- metric_relabel_configs чистит ненужные метки и «редуцирует» метрики;
- осторожно с drop: потерянная метка может «съесть» нужные данные навсегда;
- у метрик, требующих уникальности, держи стабильные label_name — иначе бьются на суммы и проценты.
22. Alertmanager: группировка, ингибирование, тишины
Без группировки массовое падение отправляет десятки одинаковых уведомлений. Alertmanager объединяет алерты по правилам:
route:
group_by: ['alertname', 'job']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
inhibit_rules:
- source_matchers: ['severity=critical']
target_matchers: ['severity=warning']
equal: ['job']- group_by — как связанные алерты складываются в одно уведомление;
- inhibit_rules — критичный алерт гасит warning на той же сущности (job/service);
- silences — запланированные тишины: «проводим деплой в 22:00», «плановая ночь без алертов»;
- не злоупотребляй silences: «навсегда» — это способ забыть о проблеме.
23. Кардинальность меток и оптимизация PromQL
Каждая комбинация значений меток — отдельная серия. Две метки по 100 значений — это 10 000 серий на одну метрику. Кардинальность — главный враг и TSDB, и скорости запросов:
| Приём | Эффект |
|---|---|
| не выносить в метки request_id, pod | серии не раздуваются на миллионы |
| rate() + окна вместо total на большой глубине | меньше работы при чтении |
| recording rules для тяжёлых запросов | расчёт один раз, чтение — мгновенно |
| срез ненужных меток через metric_relabel_configs | меньше серий в хранилище |
| агрегация только там, где нужна | без лишних операций в каждом запросе |
# пример: считаем запросы только по нужным меткам
rate(api_requests_total{status=~"2[0-9][0-9]"}[5m])Что дальше
Подключи Prometheus к Grafana для красивых дашбордов, а логи собирай в ELK. Полный список курсов — на главной странице.