Как автоматизировать мониторинг production-системы с помощью Prometheus и Grafana: пошаговое руководство

Разбудили среди ночи? Пора строить observability

Представьте: 3 часа ночи, вы спите, а ваш телефон разрывается от алертов. Микросервис упал, пользователи жалуются, а вы не знаете, с чего начать расследование. Знакомо? Если ваша production-система работает без автоматизированного мониторинга, вы не просто теряете деньги — вы рискуете репутацией.

Но есть и хорошая новость: за последние годы стек Prometheus + Grafana стал золотым стандартом наблюдаемости. Он open source, масштабируется до тысяч сервисов и позволяет настраивать алерты так, что вы будете просыпаться только по делу.

В этой статье мы разберём реальный кейс: как за один день автоматизировать мониторинг микросервисного приложения — от сбора метрик до дашбордов и оповещений. Вы получите готовые конфиги и поймёте, как не просто «поставить Prometheus», а сделать систему, которая реально помогает дежурить.

Проблема: микросервисы растут, а мониторинг — нет

Допустим, у вас есть типичное приложение: фронтенд на React, бэкенд на Go (три микросервиса — auth, order, payment), PostgreSQL, Redis и несколько воркеров для фоновых задач. Всё это крутится в Kubernetes.

Проблемы, с которыми сталкивается команда:
- Нет единой панели: кто-то смотрит логи в Kibana, кто-то — метрики в облачной консоли.
- Алерты приходят пачками: «CPU 90%», но непонятно, какой сервис виноват.
- Инциденты расследуются часами: нужно вручную собирать данные из пяти источников.

Цель: за 24 часа настроить стек, который даст ответы на три вопроса:
1. Что сейчас с системой?
2. Что пошло не так?
3. Кто должен это чинить?

Решение: архитектура на Prometheus и Grafana

Мы построим минимальную, но production-ready архитектуру:

Компонент Роль Инструмент
Сборщик метрик Pull-модель, сбор с endpoints Prometheus Server
Экспортёры Метрики из инфраструктуры node_exporter, kube-state-metrics
Клиентские библиотеки Метрики из кода приложений Prometheus client_golang
Хранилище Долгосрочное хранение (по желанию) Thanos или VictoriaMetrics
Визуализация Дашборды и графики Grafana
Алертинг Оповещения в мессенджеры Alertmanager + Telegram

Важно: мы не ставим всё «из коробки». Мы делаем упор на автоматизацию — чтобы конфиги версионировались в Git, а дашборды импортировались одной командой.

Шаг 1. Установка Prometheus Operator в Kubernetes

Самый быстрый способ — использовать Prometheus Operator. Он управляет жизненным циклом инстансов Prometheus, правилами алертов и ServiceMonitor.

Установка через Helm:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack --namespace monitoring --create-namespace

Это одной командой развернёт:
- Prometheus (с настройками retention 15 дней)
- Grafana (с предустановленными дашбордами Kubernetes)
- Alertmanager
- node_exporter и kube-state-metrics

Через 5 минут проверяем, что всё работает:

kubectl get pods -n monitoring

Должны увидеть все поды в статусе Running.

Шаг 2. Добавляем метрики из кода приложения

Prometheus собирает метрики по HTTP-эндпоинту /metrics. Чтобы ваши микросервисы отдавали метрики, нужно добавить клиентскую библиотеку.

Пример для Go (микросервис order):

package main

import (
    "net/http"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
    httpRequestsTotal = prometheus.NewCounterVec(
        prometheus.CounterOpts{
            Name: "http_requests_total",
            Help: "Total number of HTTP requests",
        },
        []string{"method", "endpoint", "status"},
    )
    requestDuration = prometheus.NewHistogramVec(
        prometheus.HistogramOpts{
            Name:    "http_request_duration_seconds",
            Help:    "Duration of HTTP requests",
            Buckets: prometheus.DefBuckets,
        },
        []string{"method", "endpoint"},
    )
)

func init() {
    prometheus.MustRegister(httpRequestsTotal)
    prometheus.MustRegister(requestDuration)
}

func main() {
    http.Handle("/metrics", promhttp.Handler())
    // ... остальной код
}

После деплоя приложения создаём ServiceMonitor — он скажет Prometheus, откуда забирать метрики:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: order-service-monitor
  namespace: monitoring
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app: order-service
  endpoints:
  - port: http
    path: /metrics
    interval: 15s

Prometheus Operator автоматически подхватит этот ресурс и начнёт сбор.

Шаг 3. Создаём дашборд в Grafana

Grafana уже идёт в комплекте с kube-prometheus-stack. Открываем её:

kubectl port-forward svc/prometheus-grafana 3000:80 -n monitoring

Логин: admin, пароль: prom-operator (по умолчанию).

Теперь создаём дашборд для нашего order-сервиса. Импортируем готовый JSON (ID 11074 из Grafana Labs) или пишем свой.

Пример простого дашборда (импортируйте через API):

{
  "title": "Order Service Dashboard",
  "panels": [
    {
      "title": "HTTP Requests Rate",
      "type": "graph",
      "targets": [
        {
          "expr": "rate(http_requests_total{endpoint=\"/api/orders\"}[5m])",
          "legendFormat": "{{status}}"
        }
      ]
    },
    {
      "title": "P99 Latency",
      "type": "graph",
      "targets": [
        {
          "expr": "histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))",
          "legendFormat": "p99"
        }
      ]
    }
  ]
}

Важный совет: используйте переменные дашборда (например, $service), чтобы переключаться между микросервисами без дублирования панелей.

Шаг 4. Настраиваем алерты в Alertmanager

Алерты — сердце автоматизации. Мы хотим получать уведомления только тогда, когда что-то действительно требует внимания.

Создаём правило алерта в PrometheusRule:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: order-service-alerts
  namespace: monitoring
  labels:
    release: prometheus
spec:
  groups:
  - name: order-service
    rules:
    - alert: HighErrorRate
      expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.05
      for: 2m
      labels:
        severity: critical
      annotations:
        summary: "High error rate on order service"
        description: "Error rate is {{ $value | humanizePercentage }} for the last 5 minutes"
    - alert: HighLatency
      expr: histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) > 2
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "P99 latency is high"
        description: "P99 latency is {{ $value }}s"

Настраиваем Alertmanager на отправку в Telegram:

apiVersion: v1
kind: Secret
metadata:
  name: alertmanager-config
  namespace: monitoring
data:
  alertmanager.yaml: |
    global:
      resolve_timeout: 5m
    route:
      receiver: 'telegram'
      group_wait: 10s
      group_interval: 5m
      repeat_interval: 4h
    receivers:
    - name: 'telegram'
      telegram_configs:
      - bot_token: '<YOUR_BOT_TOKEN>'
        chat_id: <YOUR_CHAT_ID>
        parse_mode: 'HTML'

Примените конфиг, и вы будете получать алерты прямо в Telegram. Теперь ночные звонки будут только по делу.

Шаг 5. Автоматизируем развёртывание (IaC)

Чтобы не настраивать всё руками каждый раз, используем GitOps с ArgoCD или Flux. Весь конфиг храним в Git:

├── helm/
│   └── kube-prometheus-stack/
│       └── values.yaml
├── servicemonitors/
│   ├── order-service.yaml
│   └── auth-service.yaml
├── prometheusrules/
│   └── alerts.yaml
└── grafana/
    └── dashboards/
        └── order-service.json

При изменении кода или конфигов — CI/CD пайплайн автоматически обновляет мониторинг. Это исключает человеческий фактор и экономит часы.

Результаты: что изменилось за день

После внедрения стека команда получила:
- Единую панель — Grafana показывает состояние всех микросервисов.
- Сокращение времени расследования с 2 часов до 15 минут: дашборды показывают, какой endpoint тормозит.
- Алерты без шума — только критические ошибки и высокая задержка.
- Автоматическое развёртывание — новый микросервис добавляется простым PR в Git.

Конкретные цифры (из нашего опыта):
- Время обнаружения инцидента снизилось с 10 минут до 30 секунд.
- Количество ложных алертов уменьшилось на 70% за счёт группировки и for-условий.
- Деплой нового сервиса с мониторингом теперь занимает 5 минут вместо часа.

Вывод: наблюдаемость — это не опция, а необходимость

Prometheus и Grafana — мощный дуэт, но без правильной архитектуры они превращаются в «ещё один инструмент». Ключ к успеху — автоматизация: ServiceMonitor, PrometheusRule и GitOps.

Если вы хотите глубже разобраться в построении production-системы наблюдаемости — от SLI/SLO до on-call и postmortem, обратите внимание на курс по Observability на asibiont.com. Там вы научитесь не только ставить Prometheus, но и проектировать алерты, интегрировать distributed tracing и работать с Loki. Это практический опыт, который сэкономит вам недели экспериментов.

А пока — возьмите конфиги из этой статьи и попробуйте развернуть стек уже сегодня. Production скажет вам спасибо.

← Все статьи

Комментарии

Читайте также