Loading...
Усі статті
Monitoring · 6 min read

Побудова продакшн-стека спостережуваності з Prometheus і Grafana

Практичний посібник з розгортання повного стека спостережуваності з Prometheus, Grafana, Alertmanager і Loki для продакшн-середовищ Kubernetes.

За межами базового моніторингу

Існує суттєва різниця між моніторингом і спостережуваністю. Моніторинг каже вам, коли щось не так. Спостережуваність каже вам, чому. Стек спостережуваності продакшн-рівня поєднує метрики, логи й трейси в єдиному поданні, яке дозволяє вашій команді діагностувати проблеми за хвилини, а не години.

У цьому посібнику ми проходимо стек, який ми найчастіше розгортаємо в DevOpsVibe: Prometheus для метрик, Grafana для візуалізації, Alertmanager для сповіщень і Loki для агрегації логів. Усе працює на Kubernetes.

Огляд архітектури

Стек складається з чотирьох основних компонентів:

  • Prometheus -- скрейпить і зберігає time-series метрики з ваших сервісів та інфраструктури
  • Grafana -- надає дашборди, інструменти дослідження та єдиний інтерфейс запитів
  • Alertmanager -- обробляє маршрутизацію сповіщень, дедуплікацію, групування та silencing
  • Loki -- горизонтально масштабована система агрегації логів, спроєктована для роботи з Grafana

Разом ці інструменти дають вам три стовпи спостережуваності: метрики, логи і (з додаванням Tempo) трейси.

Розгортання стека за допомогою Helm

Найшвидший шлях до продакшну — Helm-чарт kube-prometheus-stack, що включає Prometheus, Grafana, Alertmanager і набір попередньо налаштованих recording rules та дашбордів:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm install monitoring prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace \
  --values custom-values.yaml

Кастомні значення

Ось налаштований під продакшн custom-values.yaml:

# custom-values.yaml
prometheus:
  prometheusSpec:
    retention: 30d
    retentionSize: "50GB"
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: gp3
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 100Gi
    resources:
      requests:
        memory: 4Gi
        cpu: "2"
      limits:
        memory: 8Gi
    scrapeInterval: 30s
    evaluationInterval: 30s

grafana:
  adminPassword: "${GRAFANA_ADMIN_PASSWORD}"
  persistence:
    enabled: true
    size: 10Gi
  dashboardProviders:
    dashboardproviders.yaml:
      apiVersion: 1
      providers:
        - name: custom
          orgId: 1
          folder: "Custom"
          type: file
          disableDeletion: false
          editable: true
          options:
            path: /var/lib/grafana/dashboards/custom

alertmanager:
  alertmanagerSpec:
    storage:
      volumeClaimTemplate:
        spec:
          storageClassName: gp3
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 5Gi

Налаштування service discovery

Prometheus автоматично виявляє цілі в Kubernetes за допомогою custom resources ServiceMonitor і PodMonitor. Щоб моніторити новий застосунок, створіть ServiceMonitor:

# servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-api
  namespace: monitoring
  labels:
    release: monitoring
spec:
  selector:
    matchLabels:
      app: my-api
  namespaceSelector:
    matchNames:
      - production
  endpoints:
    - port: metrics
      interval: 15s
      path: /metrics
      scrapeTimeout: 10s

Ключова деталь, яку багато команд пропускають: лейбл release: monitoring має збігатися з ім'ям Helm-релізу. Без нього Prometheus не підхопить ваш ServiceMonitor.

Побудова ефективних дашбордів

Поширена помилка — створення дашбордів з десятками панелей, на які ніхто не дивиться. Натомість дотримуйтесь методів RED і USE:

Метод RED (для сервісів)

  • Rate -- запитів за секунду
  • Errors -- рівень помилок у відсотках
  • Duration -- перцентилі затримки (p50, p95, p99)

Метод USE (для ресурсів)

  • Utilization -- відсоток використовуваної ємності ресурсу
  • Saturation -- кількість роботи в черзі
  • Errors -- кількість помилкових подій

Ось визначення панелі дашборду Grafana для затримки API за допомогою PromQL:

{
  "title": "API Latency (p99)",
  "type": "timeseries",
  "targets": [
    {
      "expr": "histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service=\"my-api\"}[5m])) by (le))",
      "legendFormat": "p99"
    },
    {
      "expr": "histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket{service=\"my-api\"}[5m])) by (le))",
      "legendFormat": "p95"
    },
    {
      "expr": "histogram_quantile(0.50, sum(rate(http_request_duration_seconds_bucket{service=\"my-api\"}[5m])) by (le))",
      "legendFormat": "p50"
    }
  ]
}

Сповіщення, що не викликають втоми

Втома від сповіщень — причина номер один, чому інвестиції в моніторинг провалюються. Інженери починають ігнорувати сповіщення, і потім справжній інцидент проходить непоміченим. Ось як ми налаштовуємо Alertmanager, щоб запобігти цьому:

# alertmanager-config.yaml
global:
  resolve_timeout: 5m
  slack_api_url: "${SLACK_WEBHOOK_URL}"

route:
  receiver: "default"
  group_by: ["alertname", "namespace", "service"]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    - match:
        severity: critical
      receiver: "pagerduty-critical"
      repeat_interval: 15m
    - match:
        severity: warning
      receiver: "slack-warnings"
      repeat_interval: 4h

receivers:
  - name: "default"
    slack_configs:
      - channel: "#alerts-default"
        title: '{{ .GroupLabels.alertname }}'
        text: '{{ range .Alerts }}{{ .Annotations.description }}{{ end }}'

  - name: "pagerduty-critical"
    pagerduty_configs:
      - service_key: "${PAGERDUTY_SERVICE_KEY}"
        severity: critical

  - name: "slack-warnings"
    slack_configs:
      - channel: "#alerts-warnings"

inhibit_rules:
  - source_match:
      severity: critical
    target_match:
      severity: warning
    equal: ["alertname", "namespace"]

Написання хороших правил сповіщень

Кожне сповіщення має бути actionable. Якщо інженер отримує сповіщення і не знає, що робити, такого сповіщення не повинно існувати.

# alert-rules.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: api-alerts
  namespace: monitoring
spec:
  groups:
    - name: api.rules
      rules:
        - alert: HighErrorRate
          expr: |
            sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
            /
            sum(rate(http_requests_total[5m])) by (service)
            > 0.05
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: "High error rate on {{ $labels.service }}"
            description: "{{ $labels.service }} is returning 5xx errors at {{ $value | humanizePercentage }} over the last 5 minutes."
            runbook: "https://wiki.example.com/runbooks/high-error-rate"

        - alert: HighLatency
          expr: |
            histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service))
            > 2.0
          for: 10m
          labels:
            severity: warning
          annotations:
            summary: "High p99 latency on {{ $labels.service }}"
            description: "p99 latency for {{ $labels.service }} is {{ $value }}s, exceeding 2s threshold."

Додавання агрегації логів за допомогою Loki

Розгорніть Loki разом зі стеком Prometheus, щоб об'єднати метрики й логи в Grafana:

helm install loki grafana/loki-stack \
  --namespace monitoring \
  --set promtail.enabled=true \
  --set loki.persistence.enabled=true \
  --set loki.persistence.size=50Gi \
  --set loki.persistence.storageClassName=gp3

Потім додайте Loki як data source у Grafana. Сила цього налаштування — у можливості перейти від сплеску метрики безпосередньо до відповідних логів за допомогою split view Grafana та label matching.

Типовий запит LogQL для пошуку помилок:

{namespace="production", app="my-api"} |= "error" | json | level="error" | line_format "{{.timestamp}} {{.message}}"

Моніторинг на основі SLO

Замість того щоб сповіщати на довільні пороги, визначте Service Level Objectives і сповіщайте на burn rates:

  • SLI: Співвідношення успішних запитів до загальних
  • SLO: 99.9% запитів повинні успішно завершуватися за 30-денним вікном
  • Error budget: 0.1% запитів можуть зазнати невдачі (приблизно 43 хвилини простою на місяць)

Сповіщайте, коли ваш error budget вигорає занадто швидко:

- alert: ErrorBudgetBurnRate
  expr: |
    (
      sum(rate(http_requests_total{status=~"5.."}[1h])) by (service)
      /
      sum(rate(http_requests_total[1h])) by (service)
    ) > (14.4 * 0.001)
  for: 5m
  labels:
    severity: critical
  annotations:
    summary: "Error budget burning fast for {{ $labels.service }}"

Операційні поради

  • Підбирайте retention правильно. 30 днів даних високої роздільної здатності з downsampled довготривалим зберіганням через Thanos або Cortex.
  • Використовуйте recording rules для попереднього обчислення дорогих запитів. Це драматично покращує час завантаження дашбордів.
  • Розділяйте Prometheus для сповіщень і Prometheus для дашбордів у великих середовищах, щоб уникнути впливу навантаження запитів на оцінку сповіщень.
  • Зберігайте дашборди як код у системі контролю версій за допомогою системи provisioning Grafana або інструментів на кшталт Grafonnet.
  • Тестуйте свої сповіщення. Використовуйте promtool для unit-тестування правил сповіщень перед їх розгортанням.

Висновок

Добре побудований стек спостережуваності — не розкіш, а фундамент, що робить можливим усе інше. Без нього реакція на інциденти — це гадання, планування ємності — азартна гра, а оптимізація продуктивності — стрільба наосліп.

У DevOpsVibe ми проєктуємо й розгортаємо платформи спостережуваності, адаптовані до вашої інфраструктури. Від початкового налаштування до кастомних дашбордів і SLO-фреймворків — ми дбаємо, щоб ваша команда мала видимість, яка їй потрібна. Зв'яжіться з нами, щоб обговорити ваші потреби в моніторингу.

у категорії
monitoringobservabilityprometheusprometheusgrafanagrafanakuberneteskubernetesalerting
працювати з нами

Хочете, щоб наша команда допомогла з вашою інфраструктурою?

talk to an engineerFree 30-min discovery callBook
close