Полный стек мониторинга для серверов и Kubernetes
Полный стек мониторинга — это не Grafana с красивым дашбордом. Дашборд помогает смотреть на систему, но сам по себе он не отвечает на главный вопрос эксплуатации: что сломалось, где именно, насколько это важно и кого надо разбудить.
Для небольшого продукта обычно нужны пять слоёв: метрики, логи, трейсы, алерты и понятная архитектура хранения. Prometheus, Grafana, Loki, Tempo, OpenTelemetry и Alertmanager закрывают эти слои без привязки к одному облачному провайдеру. Такой стек можно поставить на один VPS, на несколько серверов или в Kubernetes. Но его нельзя ставить как набор модных контейнеров. Его надо собирать как систему, которую команда реально сможет обслуживать и получать пользу от этого.
Что должен покрывать полный стек
Мониторинг начинается не с выбора инструмента, а с списка вопросов, на которые команда хочет отвечать в продакшене.
Первый вопрос: жив ли сервис. Для этого нужны availability-метрики, health checks, latency, error rate и базовые SLO. Если API отвечает 200, но p95 latency выросла до пяти секунд, это уже инцидент, даже если uptime формально не нарушен.
Второй вопрос: хватает ли ресурсов. CPU, RAM, disk I/O, свободное место, сеть, file descriptors, состояние контейнеров, давление на базу данных — это скучная часть мониторинга, но именно она часто спасает от ночных падений. Переполненный диск или runaway log volume ломают маленькие продукты чаще, чем сложные распределённые баги.
Третий вопрос: что произошло внутри приложения. Здесь одних метрик мало. Нужны структурированные логи и трассировка запросов: какой endpoint тормозит, какой внешний вызов завис, где появилась ошибка, через какие сервисы прошёл запрос.
Четвёртый вопрос: кто узнает о проблеме. Алерт без маршрутизации — это просто запись в UI. Нужны правила, группировка, подавление зависимых алертов, silence на время работ и доставка в Telegram, Slack, email, PagerDuty или другую on-call-систему.
Пятый вопрос: сколько это стоит хранить. Retention для метрик, логов и трейсов должен быть осознанным. Хранить все debug-логи за год в self-hosted Loki обычно не стратегия, а будущая авария диска.
Роли компонентов
В этом стеке у каждого инструмента есть своя зона ответственности.
Prometheus собирает и хранит метрики как time series. Его сильная сторона — pull-модель, service discovery, labels и PromQL. Для серверов он забирает данные из node_exporter, для контейнеров — из cAdvisor или runtime-метрик, для Kubernetes — из kubelet, kube-state-metrics, ingress controller, баз данных и приложений. Prometheus хорошо отвечает на вопросы «сколько», «как быстро», «как часто» и «когда началось». (Prometheus)
Grafana — это интерфейс расследования. Grafana подключается к Prometheus, Loki, Tempo и другим источникам данных, строит dashboards, помогает исследовать данные через Explore и связывать разные сигналы между собой. Grafana не должна быть единственным местом правды: если исчез Prometheus или Loki, красивые панели не спасут. Но как единое окно для эксплуатации она стала привычным выбором. (Grafana)
Loki хранит логи. Его важное отличие от Elasticsearch-подхода в том, что Loki не индексирует весь текст логов, а индексирует labels для потоков логов. Это снижает стоимость хранения, но требует дисциплины: labels должны помогать фильтровать сервис, namespace, pod, host и environment, а не превращаться в бесконечный набор уникальных значений. (Loki)
Tempo хранит distributed traces. Трейсы нужны там, где один пользовательский запрос проходит через API, очередь, worker, базу данных и внешний сервис. Метрика покажет рост latency. Лог покажет отдельное событие. Trace покажет путь запроса и место, где время было потрачено. (Tempo)
OpenTelemetry — слой инструментирования и маршрутизации телеметрии. Его ценность не в том, что он «ещё один агент», а в том, что приложение можно инструментировать один раз и отправлять traces, metrics и logs в разные backends через общий протокол и Collector. Это снижает vendor lock-in и помогает не переписывать приложение при смене хранилища. (OpenTelemetry)
Alertmanager получает алерты от Prometheus, группирует, дедуплицирует, подавляет зависимые события и отправляет уведомления получателям. Prometheus решает, что условие стало истинным. Alertmanager решает, как не превратить это в спам и кому именно отправить сигнал. (Alertmanager)
Архитектура для одного или нескольких серверов
Для одного VPS или небольшой группы серверов не нужно начинать с Kubernetes-native схемы. Достаточно аккуратного self-hosted стека, который можно поднять через Docker Compose или systemd-сервисы.
Минимальная схема выглядит так:
| Слой | Компоненты | Что собирает |
|---|---|---|
| Метрики сервера | node_exporter + Prometheus |
CPU, RAM, диск, сеть, load average |
| Метрики контейнеров | cAdvisor или runtime exporter | использование контейнеров, рестарты, лимиты |
| Метрики приложения | Prometheus endpoint или OpenTelemetry Collector | request rate, latency, errors, business metrics |
| Логи | Grafana Alloy или другой Loki-compatible агент + Loki | stdout/stderr контейнеров, system logs, app logs |
| Трейсы | OpenTelemetry SDK/agent + Collector + Tempo | путь запроса между сервисами |
| UI и алерты | Grafana + Alertmanager | dashboards, Explore, уведомления |
Для одного сервера Prometheus, Loki, Tempo, Grafana и Alertmanager можно держать рядом с приложением, если нагрузка небольшая. Но это компромисс: когда сервер умирает целиком, мониторинг умирает вместе с ним. Более зрелая схема — отдельный маленький monitoring VPS, который наблюдает за production-серверами извне и хранит хотя бы базовые метрики отдельно от приложения.
Практический минимум для VPS: node_exporter, Prometheus, Grafana, Loki, агент для логов и Alertmanager. Tempo и OpenTelemetry стоит добавлять тогда, когда у вас есть несколько сервисов, очереди, внешние зависимости или регулярные расследования latency. Для монолита на одном сервере traces могут быть полезны, но они не должны задерживать запуск базового мониторинга.
Архитектура для Kubernetes
В Kubernetes мониторинг становится не просто набором процессов, а частью control plane для эксплуатации. Здесь важны service discovery, labels, namespaces, ownership и правила сбора.
Обычно базовый слой строят вокруг kube-prometheus-stack. Он устанавливает Prometheus Operator, Prometheus, Alertmanager, Grafana, node exporter, kube-state-metrics и набор готовых правил. Главная ценность Prometheus Operator — не в том, что он «ставит Prometheus», а в Kubernetes-native модели конфигурации: ServiceMonitor, PodMonitor, PrometheusRule и declarative-управление scrape targets. (Prometheus Operator)
Для логов в кластере агент ставится DaemonSet-ом на каждую ноду. Он читает container logs, добавляет labels вроде namespace, pod, container, app, cluster и отправляет потоки в Loki. Здесь действует та же дисциплина labels, что и выше: request_id, user_id и raw URL должны оставаться внутри строки лога или structured payload, а не в индексе.
Для traces приложения инструментируются через OpenTelemetry SDK, auto-instrumentation или sidecar/agent-подход. OpenTelemetry Collector можно ставить как DaemonSet для node-local приёма телеметрии или как Deployment-gateway для централизованной обработки. На маленьком кластере чаще достаточно gateway-режима. На большом — комбинации agent + gateway, чтобы снизить сетевые потери и централизовать sampling, enrichment и экспорт.
Tempo в Kubernetes обычно принимает traces через OTLP, Jaeger или Zipkin-compatible endpoints и хранит их в object storage или локальном backend, если это небольшой стенд. Для production-кластера локальный диск как долгосрочное хранилище трейсов — слабое место. Object storage почти всегда честнее.
Как связать метрики, логи и трейсы
Главная ошибка self-hosted observability — поставить три хранилища и оставить их тремя разными мирами. Тогда инженер видит скачок показателя в Prometheus, потом вручную ищет логи в Loki, потом угадывает trace в Tempo. Это лучше, чем ничего, но это ещё не полный стек.
Связка начинается с одинаковых labels: service, environment, cluster, namespace, pod, instance. Если в Prometheus сервис называется api, в Loki backend-api, а в traces main-http, расследование превращается в ручной перевод между системами.
Вторая связка — trace_id и span_id в логах. Когда приложение пишет структурированные логи с trace context, Grafana может открыть trace из конкретной строки лога. В обратную сторону Tempo может показывать связанные логи для span-а. Это особенно полезно при ошибках, которые видны только на одном запросе и не создают заметного всплеска на dashboard-е.
Третья связка — exemplars. Метрика latency показывает агрегат, но exemplar может привязать точку на графике к конкретному trace. Тогда путь расследования становится короче: spike на графике → trace медленного запроса → логи конкретного span-а → причина.
Именно здесь OpenTelemetry важнее, чем кажется на старте. Он задаёт общий контекст для telemetry signals и позволяет не собирать метрики, логи и traces как три независимых проекта.
Где self-hosted стек оправдан
Self-hosted monitoring stack имеет смысл, когда у команды есть причина владеть данными и эксплуатацией.
Первая причина — контроль. В закрытых сетях, regulated-средах, B2B-продуктах с чувствительными логами или инфраструктуре без стабильного outbound-доступа отправлять телеметрию во внешний SaaS может быть нельзя или неудобно.
Вторая причина — стоимость на объёме. У managed observability стоимость часто растёт от количества metrics series, logs ingestion, traces volume и retention. На малом объёме SaaS может быть дешевле, потому что не требует инженера. На большом объёме self-hosted стек иногда выигрывает, если команда умеет управлять cardinality, retention и object storage.
Третья причина — независимость. Prometheus, Loki, Tempo и OpenTelemetry позволяют строить переносимую архитектуру: приложение не обязано знать, что сегодня traces уходят в Tempo, а завтра часть телеметрии дублируется в другой backend.
Четвёртая причина — обучение эксплуатации. Команда, которая сама настроила alerts, dashboards, scrape configs и retention, обычно лучше понимает свои системы. Но это преимущество появляется только тогда, когда есть владелец. Брошенный self-hosted мониторинг хуже managed-сервиса, потому что создаёт иллюзию контроля.
Где self-hosted стек опасен
Главный риск — недооценить, что мониторинг тоже production-система. Его надо обновлять, бэкапить, защищать, масштабировать и проверять.
Первая типичная ошибка — cardinality. В Prometheus нельзя бездумно добавлять labels вроде user_id, email, session_id, path с raw-параметрами или request_id. Каждая уникальная комбинация лэйблов создаёт новую time series. Одна плохая метрика может съесть больше ресурсов, чем всё приложение.
Вторая ошибка — логи без бюджета. Если каждое приложение пишет debug-уровень в production, Loki быстро превращается в систему утилизации диска. Логи надо нормировать: уровни, sampling, retention, исключение шумных строк, отдельная политика для audit logs.
Третья ошибка — шумные алерты. Алерт, который срабатывает десять раз в день и не требует действия, учит команду игнорировать мониторинг. Хороший алерт должен означать: нужно вмешательство человека, иначе пользователь или бизнес пострадают.
Четвёртая ошибка — мониторинг внутри той же зоны отказа. Если вся observability живёт в том же кластере, который она должна диагностировать, при сетевой или storage-аварии вы можете потерять и приложение, и инструменты расследования. Для небольших проектов это допустимый компромисс, но его надо понимать.
Минимальный стартовый вариант
Для VPS это тот же базовый набор метрик, логов, Grafana и Alertmanager из раздела про серверы. Отдельно стоит добавить только одно: внешнюю uptime-проверку. Внутренний Prometheus не всегда покажет, что сервис недоступен пользователям из интернета, потому что сам может оказаться по ту же сторону аварии.
Для Kubernetes стартовый вариант другой: kube-prometheus-stack, Loki с DaemonSet-агентом, Grafana datasources для Prometheus и Loki, Alertmanager routes, отдельные PrometheusRule для приложений. Затем добавляйте OpenTelemetry Collector и Tempo для сервисов, где latency и межсервисные вызовы действительно требуют traces.
Не начинайте с Thanos, Mimir, multi-cluster federation, сложной HA-схемы и годового retention, если у вас один кластер и команда из нескольких человек. Это инструменты для следующего этапа. Первый этап — видеть симптомы раньше пользователя, иметь рабочие алерты и быстро переходить от графика к логам.
Практичный baseline:
| Сценарий | Минимум | Когда расширять |
|---|---|---|
| Один VPS | Prometheus, node_exporter, Grafana, Loki, Alertmanager | Когда появляются несколько сервисов, очереди или частые расследования latency |
| Несколько серверов | Отдельный monitoring VPS, exporters на хостах, централизованный Loki | Когда нужен HA Prometheus или долгий retention |
| Один Kubernetes-кластер | kube-prometheus-stack, Loki, Grafana, Alertmanager | Когда нужны traces, cross-signal correlation и object storage для долгого хранения |
| Несколько кластеров | Отдельный observability-контур, remote write или federation, единые labels | Когда команды и окружения начинают мешать друг другу |
Короткий вывод
Полный стек мониторинга для серверов и Kubernetes — это не список модных open-source проектов. Это архитектура, в которой Prometheus отвечает за метрики, Loki за логи, Tempo за traces, OpenTelemetry за сбор и переносимость телеметрии, Grafana за исследование, а Alertmanager за доставку уведомлений.
Self-hosted вариант хорош, когда вам нужен контроль, предсказуемая стоимость и независимость от managed-платформы. Но он требует дисциплины: labels, retention, алерты, обновления, хранение и владельцы должны быть продуманы с первого дня.
Если нужен короткий практический совет: начните с метрик, логов и нормальных алертов. Потом добавляйте traces и OpenTelemetry там, где они реально сокращают расследования. Мониторинг должен уменьшать время до понимания проблемы, а не становиться ещё одной системой, которую никто не успевает мониторить.
А если команде или продукту такой мониторинг нужен, но нет ресурса собирать и держать его самостоятельно, делегировать настройку и эксплуатацию — нормальное инженерное решение. Что из этого можно отдать на сторону, видно в каталоге наших услуг: от разовой настройки мониторинга и логирования до постоянного SRE-сопровождения.