Prometheus + Grafana

Берем linux сервер и устанавливаем (если нет) wget и tar
apt install wget tar

время
apt install chrony
systemctl enable chrony
systemctl start chrony


Брандмауэр
На фаерволе, при его использовании, необходимо открыть порты:

TCP 9090 — http для сервера прометеус.
TCP 9093 — http для алерт менеджера.
TCP и UDP 9094 — для алерт менеджера.
TCP 9100 — для node_exporter.

а) с помощью firewalld:

firewall-cmd --permanent --add-port=9090/tcp --add-port=9093/tcp --add-port=9094/{tcp,udp} --add-port=9100/tcp

firewall-cmd --reload

б) с помощью iptables:

iptables -I INPUT -p tcp --match multiport --dports 9090,9093,9094,9100 -j ACCEPT

iptables -I INPUT -p udp --dport 9094 -j ACCEPT


Сохраняем правила с помощью iptables-persistent:

apt install iptables-persistent

netfilter-persistent save


в) с помощью ufw:
ufw allow 9090,9093,9094,9100/tcp

ufw allow 9094/udp

ufw reload

Установка prometeus
идем на https://prometheus.io/download/
копируем ссылку на пакет для Linux (желательно, использовать версию LTS)
скачиваем
wget https://github.com/prometheus/prometheus/releases/download/v2.53.4/prometheus-2.53.4.linux-amd64.tar.gz

Для начала создаем каталоги, в которые скопируем файлы для prometheus:

mkdir /etc/prometheus /var/lib/prometheus

Распакуем наш архив:

tar -zxf prometheus-*.linux-amd64.tar.gz

... и перейдем в каталог с распакованными файлами:

cd prometheus-*.linux-amd64

Распределяем файлы по каталогам:

cp prometheus promtool /usr/local/bin/

cp prometheus.yml /etc/prometheus


Выходим из каталога и удаляем исходник:

cd .. && rm -rf prometheus-*.linux-amd64/ && rm -f prometheus-*.linux-amd64.tar.gz


Создаем пользователя, от которого будем запускать систему мониторинга:

useradd --no-create-home --shell /bin/false prometheus

* мы создали пользователя prometheus без домашней директории и без возможности входа в консоль сервера.

задаем владельца для каталогов, которые мы создали на предыдущем шаге:

chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus

Задаем владельца для скопированных файлов:

chown prometheus:prometheus /usr/local/bin/{prometheus,promtool}
Запуск и проверка

Запускаем prometheus от одноименного пользователя:

sudo -u prometheus /usr/local/bin/prometheus --config.file /etc/prometheus/prometheus.yml --storage.tsdb.path /var/lib/prometheus/

... мы увидим лог запуска — в конце «Server is ready to receive web requests»:

level=info ts=2025-01-06T06:25:15.849Z caller=main.go:621 msg="Server is ready to receive web requests."

Открываем веб-браузер и переходим по адресу http://<IP-адрес сервера>:9090 — загрузится консоль Prometheus:

Автозапуск
vim /etc/systemd/system/prometheus.service

[Unit]
Description=Prometheus Service
Documentation=https://prometheus.io/docs/introduction/overview/
After=network.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target


systemctl enable prometheus
systemctl start prometheus
systemctl status prometheus

Alertmanager
идем https://prometheus.io/download/#alertmanager

Теперь используем ссылку для загрузки alertmanager:
wget https://github.com/prometheus/alertmanager/releases/download/v0.25.0/alertmanager-0.25.0.linux-amd64.tar.gz

Установка
Создаем каталоги для alertmanager:
mkdir -p /etc/alertmanager /var/lib/prometheus/alertmanager

Распакуем наш архив:
tar -zxf alertmanager-*.linux-amd64.tar.gz

... и перейдем в каталог с распакованными файлами:
cd alertmanager-*.linux-amd64

Распределяем файлы по каталогам:
cp alertmanager amtool /usr/local/bin/
cp alertmanager.yml /etc/alertmanager


Выходим из каталога и удаляем исходник:
cd .. && rm -rf alertmanager-*.linux-amd64/

Назначение прав
Создаем пользователя, от которого будем запускать alertmanager:
useradd --no-create-home --shell /bin/false alertmanager

* мы создали пользователя alertmanager без домашней директории и без возможности входа в консоль сервера.

Задаем владельца для каталогов, которые мы создали на предыдущем шаге:
chown -R alertmanager:alertmanager /etc/alertmanager /var/lib/prometheus/alertmanager

Задаем владельца для скопированных файлов:
chown alertmanager:alertmanager /usr/local/bin/{alertmanager,amtool}

Автозапуск
Создаем файл alertmanager.service в systemd:
vim /etc/systemd/system/alertmanager.service

[Unit]
Description=Alertmanager Service
After=network.target

[Service]
EnvironmentFile=-/etc/default/alertmanager
User=alertmanager
Group=alertmanager
Type=simple
ExecStart=/usr/local/bin/alertmanager \
--config.file=/etc/alertmanager/alertmanager.yml \
--storage.path=/var/lib/prometheus/alertmanager \
--cluster.advertise-address=0.0.0.0:9093 \
$ALERTMANAGER_OPTS
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target


Разрешаем автозапуск:
systemctl enable alertmanager

Запускаем службу:
systemctl start alertmanager

Открываем веб-браузер и переходим по адресу http://<IP-адрес сервера>:9093 — загрузится консоль alertmanager
node_exporter
Для получения метрик от операционной системы, установим и настроим node_exporter на тот же сервер прометеуса (и на все клиентские компьютеры). Процесс установки такой же, как у Prometheus и Alertmanager.
Заходим на страницу загрузки и копируем ссылку на node_exporter https://prometheus.io/download/#node_exporter

Теперь используем ссылку для загрузки node_exporter:
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz

Установка

Распакуем скачанный архив:
tar -zxf node_exporter-*.linux-amd64.tar.gz

... и перейдем в каталог с распакованными файлами:
cd node_exporter-*.linux-amd64

Копируем исполняемый файл в bin:
cp node_exporter /usr/local/bin/

Выходим из каталога и удаляем исходник:
cd .. && rm -rf node_exporter-*.linux-amd64/ && rm -f node_exporter-*.linux-amd64.tar.gz

Назначение прав
Создаем пользователя nodeusr:
useradd --no-create-home --shell /bin/false nodeusr

Задаем владельца для исполняемого файла:
chown -R nodeusr:nodeusr /usr/local/bin/node_exporter

Автозапуск

Создаем файл node_exporter.service в systemd:
vim /etc/systemd/system/node_exporter.service

[Unit]
Description=Node Exporter Service
After=network.target

[Service]
User=nodeusr
Group=nodeusr
Type=simple
ExecStart=/usr/local/bin/node_exporter
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target

Разрешаем автозапуск:
systemctl enable node_exporter

Запускаем службу:
systemctl start node_exporter

Открываем веб-браузер и переходим по адресу http://<IP-адрес сервера или клиента>:9100/metrics — мы увидим метрики, собранные node_exporter:

Открываем веб-браузер и переходим по адресу http://<IP-адрес сервера или клиента>:9100/metrics — мы увидим метрики, собранные node_exporter:

Метрики, собранные node_exporter

Установка завершена.

Отображение метрик с node_exporter в консоли prometheus

Открываем конфигурационный файл prometheus:

vim /etc/prometheus/prometheus.yml

В разделе scrape_configs добавим:

scrape_configs:
  …
  — job_name: ‘node_exporter_clients’
    scrape_interval: 5s
    static_configs:
      — targets:
          — 192.168.0.14:9100
          — 192.168.0.15:9100

* в данном примере мы добавили клиента с IP-адресом 192.168.0.14, рабочее название для группы клиентов node_exporter_clients. Для примера, мы также добавили клиента 192.168.0.15 — чтобы продемонстрировать, что несколько клиентов добавляется через запятую.

Чтобы настройка вступила в действие, перезагружаем наш сервис prometheus:

systemctl restart prometheus

Заходим в веб-консоль prometheus и переходим в раздел StatusTargets:

Переходим в раздел Status - Targets

… в открывшемся окне мы должны увидеть нашу группу хостов и сам компьютер с установленной node_exporter:

Группа хостов с установленной node_exporter

* статус также должен быть UP.

Отображение тревог

Создадим простое правило, реагирующее на недоступность клиента.

Создаем файл с правилом:

vim /etc/prometheus/alert.rules.yml

groups:
— name: alert.rules
  rules:
  — alert: InstanceDown
    expr: up == 0
    for: 1m
    labels:
      severity: critical
    annotations:
      description: ‘{{ $labels.instance }} of job {{ $labels.job }} has been down
        for more than 1 minute.’
      summary: Instance {{ $labels.instance }} down

Теперь подключим наше правило в конфигурационном файле prometheus:

vim /etc/prometheus/prometheus.yml


rule_files:
  # — «first_rules.yml»
  # — «second_rules.yml»
  — «alert.rules.yml»

* в данном примере мы добавили наш файл alert.rules.yml в секцию rule_files. Закомментированные файлы first_rules.yml и second_rules.yml уже были в файле в качестве примера.

Перезапускаем сервис:

systemctl restart prometheus

Открываем веб-консоль прометеуса и переходим в раздел Alerts. Если мы добавим клиента и попробуем его отключить для примера, мы увидим тревогу:

Группа хостов с установленной node_exporter

Отправка уведомлений

Теперь настроим связку с алерт менеджером для отправки уведомлений на почту и телеграм-чат.

Уведомления на почту

Настроим alertmanager:

vim /etc/alertmanager/alertmanager.yml

В секцию global добавим:

global:
  …
  smtp_from: monitoring@maksimov-it.ru

* при отсутствии секции global необходимо ее добавить.
** мы будем отправлять сообщения от email monitoring@maksimov-it.ru

Приведем секцию route к виду:

route:
  group_by: [‘alertname’, ‘instance’, ‘severity’]
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: ‘web.hook’

  routes:
    — receiver: send_email
      match:
        alertname: InstanceDown

* в данном примере нами был добавлен маршрут, который отлавливает событие InstanceDown и запускает ресивер send_email.

… далее добавим еще один ресивер:

receivers:

— name: send_email
  email_configs:
  — to: alert
@maksimov-it.ru
    smarthost: localhost:25
    require_tls: false

* в данном примере мы отправляем сообщение на почтовый ящик monitoring@maksimov-it.ru с локального сервера. Обратите внимание, что для отправки почты наружу у нас должен быть корректно настроенный почтовый сервер (в противном случае, почта может попадать в СПАМ).

Перезапустим сервис для алерт менеджера:

systemctl restart alertmanager

Теперь настроим связку prometheus с alertmanager — открываем конфигурационный файл сервера мониторинга:

vim /etc/prometheus/prometheus.yml

Приведем секцию alerting к виду:

alerting:
  alertmanagers:
  — static_configs:
    — targets:
      — 192.168.0.14:9093

* где 192.168.0.14 — IP-адрес сервера, на котором у нас стоит alertmanager.

Перезапускаем сервис:

systemctl restart prometheus

Немного ждем и заходим на веб интерфейс алерт менеджера — мы должны увидеть тревогу:

Событие в алерт менеджере

… а на почтовый ящик должно прийти письмо с тревогой.

Отправка уведомлений в телеграм

Открываем телеграм и ищем пользователя @BotFather:

Ищем @BotFather в телеграме

Переходим в чат с найденным BotFather и запускаем бота:

Запускаем BotFather

Создаем бота, последовательно введя команду /newbot и отвечая на запросы мастера. Например:

/newbot

maksimov_prometheus

maksimovPrometheusBot

* где:

  • /newbot — команда для создания нового телеграм бота.
  • maksimov_prometheus — имя бота.
  • maksimovPrometheusBot — имя учетной записи бота. Обязательно должно быть Bot на конце.

В результате мы должны получить сообщение на подобие:

Done! Congratulations on your new bot. You will find it at t.me/maksimov-itkPrometheusBot. You can now add a description, about section and profile picture for your bot, see /help for a list of commands. By the way, when you’ve finished creating your cool bot, ping our Bot Support if you want a better username for it. Just make sure the bot is fully operational before you do this.

Use this token to access the HTTP API:

4352345345:FKSICSNERJOBMKDJE4rKD4kfsdfEISdkf8E
Keep your token secure and store it safely, it can be used by anyone to control your bot.

For a description of the Bot API, see this page: https://core.telegram.org/bots/api

* где 4352345345:FKSICSNERJOBMKDJE4rKD4kfsdfEISdkf8E токен бота. Его храним в безопасном месте.

Открываем телеграм чат или канал и добавляем созданного бота, чтобы он мог отправлять сообщения.

Из командной строки можно выполнить тестовую отправку сообщения.

curl https://api.telegram.org/bot<BotID>/sendMessage?chat_id=<ChannelName>\&text=<Text>

Настройка бота закончена.

Настроим alertmanager:

vim /etc/alertmanager/alertmanager.yml

Приведем секцию route к виду:

route:
  group_by: [‘alertname’, ‘instance’, ‘severity’]
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: ‘web.hook’

  routes:
    — receiver: telegram

* в данном примере нами был добавлен маршрут, который отлавливает событие InstanceDown и запускает ресивер send_email.

… далее добавим еще один ресивер:

receivers:

  — name: telegram
    telegram_configs:
      — chat_id: <ID чата>
        bot_token: «<Полученыый токен для бота>»
        api_url: «https://api.telegram.org»
        send_resolved: true
        parse_mode: »

* в данном примере мы отправляем сообщение в чат по его ID. В качестве данного идентификатора нужно использовать либо имя через знак @ (@maksimovChatGroup), либо идентификационный номер через — (-4352345345).

Перезапустим сервис для алерт менеджера:

systemctl restart alertmanager

Проверим, что служба запущена:

systemctl status alertmanager

Теперь настроим связку prometheus с alertmanager — открываем конфигурационный файл сервера мониторинга:

vim /etc/prometheus/prometheus.yml

Приведем секцию alerting к виду:

alerting:
  alertmanagers:
  — static_configs:
    — targets:
      — 192.168.0.14:9093

* где 192.168.0.14 — IP-адрес сервера, на котором у нас стоит alertmanager.

Перезапускаем сервис:

systemctl restart prometheus

Мониторинг служб Linux

Для мониторинга сервисов с помощью Prometheus мы настроим сбор метрик и отображение тревог.

Сбор метрие с помощью node_exporter

Открываем сервис, созданный для node_exporter:

vim /etc/systemd/system/node_exporter.service

… и добавим к ExecStart:


ExecStart=/usr/local/bin/node_exporter —collector.systemd

* данная опция указывает экспортеру мониторить состояние каждой службы.

При необходимости, мы можем либо мониторить отдельные службы, добавив опцию collector.systemd.unit-whitelist:

ExecStart=/usr/local/bin/node_exporter —collector.systemd —collector.systemd.unit-whitelist=»(chronyd|mariadb|nginx).service»

* в данном примере будут мониториться только сервисы chronyd, mariadb и nginx.

… либо наоборот — мониторить все службы, кроме отдельно взятых:

ExecStart=/usr/local/bin/node_exporter —collector.systemd —collector.systemd.unit-blacklist=»(auditd|dbus|kdump).service»

* при такой настройке мы запретим мониторинг сервисов auditddbus и kdump.

Чтобы применить настройки, перечитываем конфиг systemd:

systemctl daemon-reload

Перезапускаем node_exporter:

systemctl restart node_exporter

Отображение тревог

Настроим мониторинг для службы NGINX.

Создаем файл с правилом:

vim /etc/prometheus/services.rules.yml

groups:
— name: services.rules
  rules:
    — alert: nginx_service
      expr: node_systemd_unit_state{name=»nginx.service»,state=»active»} == 0
      for: 1s
      annotations:
        summary: «Instance {{ $labels.instance }} is down»
        description: «{{ $labels.instance }} of job {{ $labels.job }} is down.»

Подключим файл с описанием правил в конфигурационном файле prometheus:

vim /etc/prometheus/prometheus.yml


rule_files:
  # — «first_rules.yml»
  # — «second_rules.yml»
  — «alert.rules.yml»
  — «services.rules.yml»

* в данном примере мы добавили наш файл services.rules.yml к уже ранее добавленному alert.rules.yml в секцию rule_files.

Перезапускаем prometheus:

systemctl restart prometheus

Для проверки, остановим наш сервис:

systemctl stop nginx

В консоли Prometheus в разделе Alerts мы должны увидеть тревогу:

Тревога при падении сервиса

Проксирование через NGINX

Если у нас есть обратный прокси на базе NGINX и мы хотим через него отправлять запросы на Prometheus, нам понадобится дополнительная настройка.

Мы рассмотрим 2 варианта:

  1. Когда запросы проксируются на основе виртуального домена.
  2. Когда запросы идут на основе добавления адреса к URL.

Виртуальные домены

server {
    listen       80;
    server_name  prometheus.maksimov-it.ru;

    location / {
        proxy_pass          http://127.0.0.1:9090;
        proxy_redirect      off;
        proxy_http_version  1.1;

        proxy_set_header  Host               $host;
        proxy_set_header  Upgrade            $http_upgrade;
        proxy_set_header  Connection         «upgrade»;
        proxy_set_header  X-Real-IP          $remote_addr;
        proxy_set_header  X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Proto  http;
    }
}