Мониторинг сервера с Prometheus и Grafana
Зачем мне понадобился мониторинг
Когда у меня появился собственный сервер, я довольно долго жил без нормального мониторинга. Проверял всё вручную: зашёл по SSH, глянул на top, посмотрел свободное место — и так по кругу. Какое-то время этого хватало, но потом сервер начал подтормаживать, а я понял, что не могу сказать, когда именно это началось и что стало причиной. Именно тогда я решил, что пора поставить полноценный мониторинг.
Я рассматривал несколько вариантов. Сначала думал про лёгкие решения вроде Netdata, потом примерился к Zabbix. В итоге остановился на связке Prometheus и Grafana. Меня привлекло то, что это открытое ПО без лицензионных ограничений, у него огромное сообщество, а конфигурация описывается обычными файлами, которые удобно хранить в git. Плюс со временем к этой системе можно подключить практически что угодно.
Как устроена связка Prometheus и Grafana
Связка работает так: Prometheus периодически опрашивает метрики у приложений, а Grafana отображает эти метрики в виде красивых графиков и дашбордов. Между ними нет никакого сложного взаимодействия — Grafana просто подключается к Prometheus как к источнику данных и строит запросы на специальном языке PromQL.
Сам Prometheus хранит метрики у себя в собственной базе данных. Это удобно тем, что для старта не нужна никакая внешняя БД — всё работает из коробки. А метрики от систем собираются с помощью так называемых экспортёров, самый популярный из которых — Node Exporter. Он отдаёт Prometheus информацию о процессоре, памяти, дисках, сети и температуре сервера.
Установка через Docker Compose
Я решил запускать всё через Docker Compose, чтобы конфигурация была воспроизводимой и не зависела от конкретной машины. Создал файл docker-compose.yml, в котором описал три сервиса: Prometheus, Node Exporter и Grafana. Ниже — как выглядит базовая конфигурация.
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
node-exporter:
image: prom/node-exporter:latest
network_mode: host
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
Обратите внимание на network_mode: host у Node Exporter. Так экспортёр видит сетевые интерфейсы хоста напрямую и отдаёт корректные метрики сети, а не те, что видны внутри контейнерной сети. Без этого трюка некоторые показатели оказываются неточными.
Конфигурация Prometheus
Сам Prometheus настраивается через файл prometheus.yml. В нём нужно указать, какие сервисы он должен опрашивать и с какой периодичностью. Минимальная конфигурация выглядит так.
global:
scrape_interval: 15s
scrape_configs:
- job_name: node
static_configs:
- targets: ["localhost:9100"]
Здесь scrape_interval задаёт периодичность опроса — у меня это 15 секунд. Блок job_name описывает группу целей. Для дома частоты в 15 секунд более чем достаточно, а вот для критичных продакшен-систем интервал часто уменьшают до 5 секунд, чтобы быстрее замечать проблемы.
Первый дашборд в Grafana
После того как связка поднялась, я открыл Grafana в браузере на порту 3000 и добавил источник данных Prometheus. По умолчанию логин и пароль админки — admin/admin, при первом входе система попросит их сменить. Затем я не стал рисовать дашборд с нуля, а скачал готовый шаблон с официального сайта Grafana — для Node Exporter их много, и они проверены сообществом.
Импорт готового дашборда занял у меня меньше минуты, а результат превзошёл ожидания: сразу стало видно загрузку CPU по ядрам, использование памяти, нагрузку на диск и сетевой трафик. Для старта этого достаточно, чтобы понимать, что происходит с сервером.
Алерты в Telegram
Графики — это хорошо, но смотреть на них каждый день никто не будет. Настоящая ценность мониторинга в том, чтобы он сам сообщал о проблемах. Для этого я настроил алерты, которые уходят в Telegram. В Prometheus за оповещения отвечает отдельный компонент — Alertmanager.
Сначала я описал правила в файле rules.yml, подключил его к Prometheus, а потом настроил Alertmanager на отправку сообщений в мой чат через бота. В правилах я прописал два основных триггера: высокую загрузку CPU и переполнение памяти. Выглядело это примерно так.
groups:
- name: server_alerts
rules:
- alert: HighCPU
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
- alert: HighMemory
expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 90
for: 5m
Ключевое здесь — параметр for: 5m. Он означает, что алерт сработает только если условие выполняется непрерывно пять минут. Это защищает от ложных срабатываний на кратковременные пики, которые случаются при обычной работе.
Как это работает на практике
Через пару недель эксплуатации я заметил, что начал лучше понимать свой сервер. Когда кто-то из моих сервисов вдруг начинал тормозить, я открывал дашборд и сразу видел, упирается ли он в память или в диск. Это сильно ускоряет поиск причин неполадок.
Один раз алерт в Telegram реально спас мне вечер. Ночью у меня начала расти нагрузка на диск, и я получил уведомление. Оказалось, что бекапы начали писаться на переполненный раздел, и без алерта я узнал бы об этом только когда всё окончательно встало бы.
Что я советую настроить в первую очередь
Если вы только начинаете с мониторинга, не пытайтесь охватить всё сразу. Начните с базового набора метрик: загрузка процессора, использование памяти, свободное место на диске и сетевой трафик. Этого достаточно, чтобы закрыть 90% реальных ситуаций.
Обязательно настройте хотя бы один канал оповещений. Даже простой алерт на низкий процент свободного места на диске — уже огромная польза. Именно диски обычно заполняются незаметно и доставляют больше всего проблем.
И не забывайте про периодическую проверку самого мониторинга. Иногда бывает так, что Prometheus тихо падает, а вы об этом не знаете, потому что алертов об этом нет. Я добавил себе проверку доступности всех сервисов, чтобы сам мониторинг не превращался в источник ложной уверенности.
Почему я отказался от Netdata и Zabbix
Перед тем как остановиться на Prometheus и Grafana, я пробовал и другие инструменты, и у каждого были свои причины отпасть. Netdata очень хорош для быстрого старта: он ставится одной командой и сразу показывает красивые графики по сотне метрик. Но меня смущало, что настройка уведомлений и собственных дашбордов там менее гибкая, а для связки с моими сценариями приходилось докручивать лишнее.
Zabbix, наоборот, показался мне избыточным для домашнего сервера. Он очень мощный и подходит для больших инфраструктур, но его агент и система триггеров требуют заметно больше времени на изучение. Для пары серверов это выглядело как перебор, поэтому я переключился на более лёгкое решение и не жалею.
Что ещё можно мониторить
После того как базовая связка заработала, я начал расширять охват. Довольно быстро добавил мониторинг контейнеров через cAdvisor — он отдаёт метрики использования CPU и памяти по каждому контейнеру. Это позволило видеть, какой именно сервис потребляет больше всего ресурсов, а не гадать по общим цифрам.
Ещё я подключил экспортёр для PostgreSQL и стал видеть количество подключений, размер базы и скорость выполнения запросов. А когда настроил бекапы, добавил метрику последнего удачного выполнения. Теперь у меня всё важное в одном месте, и не нужно заходить на сервер, чтобы убедиться, что всё в порядке.
О безопасности мониторинга
Важный момент, о котором легко забыть: панель Grafana и порт Prometheus не стоит открывать наружу без защиты. По умолчанию Grafana ходит по HTTP без пароля у всех в интернете, если вы пробросили порт 3000 в роутере. Я закрыл доступ извне и пользуюсь только через VPN, а если надо быстро глянуть графики с телефона — открываю туннель на время.
Также я ограничил доступ к порту 9090, на котором висит сам Prometheus. Запросы к нему могут рассказать много о внутренней структуре сервера, поэтому лишние глаза здесь ни к чему. Эти простые шаги не требуют много времени, а защищают от неприятных сюрпризов.
Советы по хранению конфигурации
Конфигурационные файлы Prometheus и Alertmanager я храню в git вместе с docker-compose.yml. Это оказалось очень удобным: любое изменение версии отслеживается, а при переезде на новую машину достаточно склонировать репозиторий и поднять контейнеры. Никакой ручной настройки заново.
Ещё я вынес файл с правилами алертов в отдельный каталог и добавил комментарии на каждый триггер. Через месяц уже не помнишь, зачем был добавлен конкретный алерт, поэтому пояснения очень выручают. И регулярно делаю резервную копию данных Grafana — туда могут попадать созданные вами дашборды, которые жалко потерять.
Типичные ошибки при настройке
Самой распространённой проблемой у новичков оказывается неверный адрес целей в prometheus.yml. Если Prometheus и экспортёр живут в разных сетях Docker, то localhost в конфигурации не сработает — нужно указывать имя сервиса или адрес хоста. Я сам наступил на эти грабли и потратил полчаса, разбираясь, почему в интерфейсе нет данных.
Вторая частая ошибка — забыть перезапустить Prometheus после изменения файла конфигурации. В Docker достаточно пересоздать контейнер, но новички часто правят файл и ждут, что всё применится само. Проверка конфигурации командой promtool check config перед перезапуском тоже спасает от долгих разборов, когда синтаксис сломан.
И третье: не игнорируйте логи контейнеров. Если Grafana не видит источник данных, почти наверняка ошибка написана в логах. Чтение логов через docker logs grafana решает большинство вопросов быстрее, чем поиск в интернете.
Как я проверяю, что всё работает
После любой переделки я выполняю простой чек-лист. Сначала смотрю, что все три контейнера живы через docker ps. Потом открываю интерфейс Prometheus и проверяю, что таргеты в состоянии UP — это видно на странице Targets. И наконец, открываю Grafana и убеждаюсь, что графики отображаются и на них есть свежие данные. На весь процесс уходит пара минут, зато я спокоен.
Периодически я специально проверяю алерты вручную: временно снижаю порог CPU до одного процента и смотрю, приходит ли уведомление в Telegram. Если не пришло — значит, где-то в цепочке ошибка, и лучше узнать об этом заранее, чем тогда, когда сервер действительно упадёт. После проверки возвращаю порог на место.
Итог
Prometheus и Grafana стали для меня стандартным инструментом. Несмотря на то что поначалу кажется, что это сложно, на деле базовая настройка занимает один вечер. Зато потом у вас есть наглядная картина состояния сервера и автоматические уведомления о проблемах. Я уверен, что после установки вы тоже не захотите возвращаться к ручной проверке сервера по SSH.