У мониторинга репутация дорогого удовольствия: enterprise-системы с агентами на каждом узле и лицензиями за гигабайт пугают небольшие команды. Связка Prometheus и Grafana ломает это представление - обе системы бесплатны, ставятся за полчаса и не требуют ничего, кроме самого сервера. В статье полный путь от пустой Ubuntu Server 24.04 до живого дашборда: установка обеих систем, конфигурация сбора метрик, первый источник метрик и панели, готовые к работе с первого дня.

Из чего состоит связка и почему систем две, а не одна

Разделение обязанностей между системами принципиальное, и понимать его полезно до установки. Prometheus - база метрик с собственным хранилищем: она раз в заданный интервал обходит источники, забирает показания, хранит их в локальной базе времени и умеет вычислять выражения над ними, включая правила алертов. Grafana - витрина: она ничего не собирает, берёт готовые ряды у источников и рисует панели, которыми пользуются люди. У каждой системы своя роль, и попытки использовать одну вместо другой заканчиваются болью: базы метрик рисуют слабо, витрины не хранят.

Схема работы выглядит как конвейер. Источники - экспортеры, приложения, сама база - отдают показания в текстовом формате по HTTP. Prometheus опрашивает их по списку целей, складывает в базу и вычисляет правила. Grafana подключается к базе как к источнику метрик и рисует графики выражениями, которые знает Prometheus. Контур алертов встраивается в ту же схему: правила живут рядом с базой метрик, доставка уходит через Alertmanager, а панели служат рабочим местом дежурного.

Для установки достаточно одного сервера с парой гигабайт памяти: обе системы по отдельности скромны, и мониторинг небольшого парка из пяти-десяти узлов живёт на машинах начального класса без напряга.
Терминология связки короткая, но без неё дальше ни шагу. Метрика - именованный показатель со списком меток, например секунды процессора с метками режима и ядра. Серия - метрика с конкретным набором значений меток, она и есть строка в базе. Метки же служат языком фильтров: в выражениях серии отбирают по меткам, и одна аккуратно размеченная серия экономит десятки панелей.
Отдельный термин - цель, адрес источника в задаче сбора: именно цели связывают конфигурацию базы метрик с реальными машинами, и список целей всегда честно показывает, за чем система следит.

Установка Prometheus из официального релиза и разметка каталогов

Пакет в репозитории дистрибутива существует, но отстаёт от релизов проекта на месяцы, поэтому рабочий путь - официальный архив актуальной версии 3.15. Порядок действий выглядит так:

  1. Заводится системный пользователь prometheus без оболочки для службы;
  2. Создаются каталоги конфигурации /etc/prometheus и хранилища /var/lib/prometheus;
  3. Скачивается и распаковывается официальный архив релиза;
  4. Бинарники и консоли переезжают в постоянные места, файлы получают владельца из шага один.

Команды не сложнее любых других серверных работ.

sudo useradd -rs /usr/sbin/nologin prometheus
sudo mkdir -p /etc/prometheus /var/lib/prometheus
cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v3.15.0/prometheus-3.15.0.linux-amd64.tar.gz
tar xzf prometheus-3.15.0.linux-amd64.tar.gz
sudo cp prometheus-3.15.0.linux-amd64/prometheus /usr/local/bin/
sudo cp -r prometheus-3.15.0.linux-amd64/consoles /etc/prometheus/
sudo chown -R prometheus:prometheus /var/lib/prometheus

Разметка каталогов - маленькое решение с долгими последствиями. Конфигурация в /etc удобна для резервных копий, хранилище в /var/lib переживает обновления, а отдельный пользователь означает, что базе метрик не нужны привилегии суперпользователя. Версию в адресе подставляют актуальную на момент установки, проект выпускает релизы регулярно и предсказуемо.
В архиве вместе с самими бинарниками лежат консоли - готовые веб-страницы с выражениями, рудимент старой эпохи, полезный как шпаргалка по запросам. Утилита проверки конфигурации promtool тоже берётся из архива, её имеет смысл положить рядом с бинарником: проверка синтаксиса перед перезапуском на живой системе - привычка, которая окупается с первого же инцидента.

Файл конфигурации prometheus с задачами сбора и интервалом опроса

Прежде чем запускать службу, ей готовят конфигурацию. Минимальный рабочий файл выглядит скромно.

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: ["localhost:9090"]
  - job_name: node
    static_configs:
      - targets: ["localhost:9100"]
        labels:
          host: web-1

Интервал в пятнадцать секунд - компромисс, выбранный всей отраслью: он достаточно частый, чтобы заметить короткие всплески, и достаточно редкий, чтобы база не распухала. Первая задача сбора следит за самим Prometheus - у него есть собственные метрики здоровья, и мониторинг мониторинга на практике спасает от тихо умершей базы. Вторая задача подключает Node Exporter на этом же сервере, метка host различает узлы, когда их станет несколько. Каждый следующий сервер в будущем - это одна строка в списке целей, и только.

После первого запуска конфигурацию проверяют встроенной проверкой синтаксиса: promtool check config /etc/prometheus/prometheus.yml - утилита входит в поставку и ловит ошибки до старта службы, что экономит минуты перезапусков.

Служба инициализации, хранение и сколько места занимает история

Юнит для базы метрик пишется один раз и дальше не меняется.

[Unit]
Description=Prometheus
After=network-online.target

[Service]
User=prometheus
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus \
  --storage.tsdb.retention.time=180d
Restart=on-failure

[Install]
WantedBy=multi-user.target

Флаг retention - главный регулятор диска. По умолчанию база хранит историю пятнадцать дней, и для анализа "что случилось на прошлой неделе" этого мало, поэтому на практике ставят 90 или 180 дней. Объём считается просто: одна серия с интервалом пятнадцать секунд даёт около 1.6 миллиона значений за полгода, а хранение значения обходится в пару байт. Типичный сервер с одним экспортером держит около тысячи активных серий, и полугодовая история занимает единицы гигабайт - цифры, которые не пугают даже недорогие VPS с диском в двадцать гигабайт. Порог автоматического удаления по возрасту работает без внешних скриптов, база сама поддерживает себя в заданных рамках.
Ещё один флаг полезен сразу: он разрешает перечитывать конфигурацию без перезапуска службы, вызовом служебной точки перезагрузки. На живом сервере это экономит секунды на каждой правке и убирает риск остаться без мониторинга из-за неудачного рестарта в неудачный момент.

После включения службы проверка занимает секунды: curl к локальному порту 9090 возвращает служебную страницу, а раздел targets показывает обе цели со статусом UP. С этого момента метрики уже копятся.
Если служба не поднялась, ответ всегда в журнале: journalctl с ключами юнита и количества строк выводит последние события, и в девяти случаях из десяти причина - опечатка в YAML или права на каталог хранилища. Проверка прав тривиальна: пользователь, от которого работает служба, должен уметь писать в каталог хранения.

Установка Grafana через пакетный репозиторий и первый вход

Grafana ставится из собственного репозитория проекта и обновляется потом штатными средствами пакетного менеджера, это самый аккуратный путь на Debian-подобных системах.

sudo apt-get install -y apt-transport-https software-properties-common wget
wget -qO- https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install grafana

Актуальная большая ветка системы - тринадцатая, и пакетный репозиторий отдаёт её свежие сборки. После установки служба включается как обычно: systemctl enable --now grafana-server, и через десять секунд витрина отвечает на порту 3000. Первый вход выполняется со стандартной парой логина и пароля admin, система сразу требует сменить пароль, и этот шаг пропускать не стоит: порт 3000 не должен встречать незнакомцев с типовыми паролями.

Порт 3000, как и любой веб-интерфейс, не выставляют в интернет напрямую. Для домашнего контура достаточно доступа по туннелю, для команды - обратный прокси с шифрованием и доменным именем. Сама витрина по нагрузке нетребовательна: сотня-другая мегабайт памяти и проценты процессора на типичном использовании.
Настройки витрины живут в /etc/grafana/grafana.ini, и на старте там правят обычно две строки: доменное имя в секции сервера для корректных ссылок и корневой адрес за обратным прокси. Обновляется система штатно через пакетный менеджер при очередном обновлении пакетов, конфигурация и базы панелей переживают обновления на месте.

Источник метрик и первый дашборд без ручного рисования панелей

Внутри Grafana первым делом подключается источник метрик: раздел соединений, тип Prometheus, адрес локальной базы. Проверка соединения зелёной галочкой закрывает вопрос, и можно переходить к панелям.

Рисовать первый дашборд с нуля незачем: у сообщества накоплены тысячи готовых наборов, и для связки с Node Exporter существует отработанный вариант с досками процессора, памяти, дисков и сети. Импорт по идентификатору занимает минуту: раздел дашбордов, импорт, номер набора, выбор источника метрик - и на экране полноценная панель наблюдения за сервером, которую команда с опытом строила бы вечер. Дальше полезная привычка - отключить лишнее: готовые наборы бывают перегружены, и дашборд из пятнадцати действительно открываемых панелей полезнее стодолларового набора, который листают со скукой.

Для командной работы у витрицы есть свой файловый способ настройки: каталог provisioning хранит источники метрик и дашборды в YAML, и сервер с настроенным провижинингом пересобирается из скрипта за минуты - то, что превращает установку из ремесла в повторяемую процедуру.
Командная работа закрывается штатными папками и учётными записями: дашборды группируются по папкам, права назначаются командам, а типовые роли редактора и наблюдателя избавляют от хаоса полномочий на пустом месте.

apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: localhost:9090
    isDefault: true

Полезные выражения для первых панелей и порядок дальнейшего роста

Набор выражений, с которых начинают все, короткий и закрывает базовые вопросы о здоровье узла.

100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
node_memory_MemAvailable_bytes / 1024 / 1024 / 1024
100 * node_filesystem_avail_bytes / node_filesystem_size_bytes
rate(node_network_receive_bytes_total[5m])

Первая строка - загрузка процессора в процентах, вторая - доступная память в гигабайтах, третья - свободное место по разделам, четвёртая - скорость сети. Каждое выражение годится и для панели, и для правила алерта с порогом, поэтому первые правила мониторинга пишутся из тех же строк копированием.
Для практической работы стоит сразу добавить три выражения про сами системы: время непрерывной работы узла по метрике аптайма, счётчик рестартов через increase по метрике времени старта процесса и метрику успешности сбора up, которая ложится в основу первого алерта о недоступной цели.

Дальнейший рост идёт по двум направлениям. Вширь - новые источники: экспортер базы, счётчики веб-сервера, метрики приложений, и каждый добавляется строкой в конфигурацию сбора. Вглубь - алерты: правила с выдержкой времени, доставка через Alertmanager в мессенджер и на почту, паузы на время работ. Отправная точка одна и та же: сервер с двумя службами, файл конфигурации и витрина, которые были собраны в этой статье, и которые дальше только обрастают источниками, панелями и правилами.