В этой статье соберём минимально достаточный, но боеспособный стек мониторинга для VDS: Prometheus, Node Exporter, Nginx Prometheus Exporter, Alertmanager и Grafana. Весь путь — от нуля до алертов — реалистично пройти за ~60 минут на одном или нескольких серверах. По ходу я дам готовые конфиги, безопасные настройки и проверенные PromQL-запросы, чтобы вы сразу получили практическую пользу: графики производительности, метрики Nginx и уведомления при сбоях.
Что конкретно мы получим за час
В результате вы развернёте:
- Сбор метрик с ОС через Node Exporter: CPU, RAM, диски, сеть, нагрузка.
- Метрики Nginx через Nginx Prometheus Exporter (на основе
stub_status): активные соединения, чтение/запись/ожидание, принятые/обработанные запросы. - Prometheus как центральную TSDB с правилами алертов.
- Alertmanager для маршрутизации уведомлений.
- Grafana для дашбордов и быстрых графиков.
Мы делаем упор на надёжность и простоту: только необходимые компоненты, безопасные дефолты, минимум лишней магии. Этот стек хорошо подходит для одиночного VDS и для пула серверов.
Схема и требования
Базовая схема: на каждом целевом сервере (VDS) ставим Node Exporter и Nginx Prometheus Exporter. На одном выбранном сервере (можно отдельном) ставим Prometheus, Alertmanager и Grafana. Prometheus опрашивает экспортеры по сети.
Порты по умолчанию:
- Prometheus: 9090
- Alertmanager: 9093
- Grafana: 3000
- Node Exporter: 9100
- Nginx Prometheus Exporter: 9113
Минимальные требования: современный Linux, systemd, доступ по SSH с правами root или sudo. Синхронизация времени (ntp/chrony) сильно рекомендована — без корректного времени алерты и графики будут врать. Если вы только выбираете сервер под мониторинг, обратите внимание на VDS — удобно выделить отдельный экземпляр под Prometheus и Grafana.

Шаг 1. Установка Node Exporter на целевой сервер
Node Exporter — это стандарт для системных метрик в мире Prometheus. Ставим, запускаем как отдельного пользователя, открываем порт только для сервера Prometheus (или слушаем на 127.0.0.1, если Prometheus на той же машине).
Создаём пользователя и директории:
sudo useradd --no-create-home --shell /usr/sbin/nologin nodeexp
sudo mkdir -p /etc/node_exporter
sudo mkdir -p /var/lib/node_exporter
Разместите бинарник node_exporter в /usr/local/bin с правами на исполнение и владельцем root. Затем создайте unit-файл:
sudo tee /etc/systemd/system/node_exporter.service > /dev/null << 'EOF'
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=nodeexp
Group=nodeexp
Type=simple
ExecStart=/usr/local/bin/node_exporter \
--web.listen-address=0.0.0.0:9100
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
Проверьте локально метрики:
curl -s localhost:9100/metrics | head -n 20
Ограничьте доступ к порту 9100 фаерволом (разрешите только адрес Prometheus). Если Prometheus стоит здесь же, замените --web.listen-address=127.0.0.1:9100.
Шаг 2. Метрики Nginx через stub_status и Nginx Prometheus Exporter
Базовый способ мониторинга Nginx — включить stub_status и поставить экспортер, который конвертирует эти данные в формат Prometheus. Это быстро и не требует модулей третьих сторон.
2.1. Включаем stub_status в Nginx
Добавьте в конфигурацию Nginx отдельный location в сервере, доступный только с localhost. Например:
location /stub_status {
stub_status;
allow 127.0.0.1;
deny all;
}
Перезагрузите Nginx и убедитесь, что статус отдаётся локально:
nginx -t
sudo systemctl reload nginx
curl -s 127.0.0.1/stub_status
2.2. Ставим Nginx Prometheus Exporter
Разместите бинарник nginx-prometheus-exporter в /usr/local/bin. Создайте системный сервис, который слушает на 9113 и читает stub_status по 127.0.0.1/stub_status:
sudo useradd --no-create-home --shell /usr/sbin/nologin ngexp
sudo tee /etc/systemd/system/nginx_prometheus_exporter.service > /dev/null << 'EOF'
[Unit]
Description=NGINX Prometheus Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=ngexp
Group=ngexp
Type=simple
ExecStart=/usr/local/bin/nginx-prometheus-exporter \
-nginx.scrape-uri http://127.0.0.1/stub_status \
-web.listen-address 0.0.0.0:9113
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now nginx_prometheus_exporter
curl -s localhost:9113/metrics | head -n 30
Как и в случае с Node Exporter, ограничьте доступ к 9113 только для Prometheus. На одно приложение Nginx — один экспортер.
Хотите HTTP-коды, latency и upstream-метрики? Рассмотрите модуль VTS или специализированные экспортеры логов. Но для «часовой» установки проще начать со
stub_status.
Шаг 3. Установка и настройка Prometheus
Prometheus — центральная TSDB и планировщик опроса целей. Установите бинарник в /usr/local/bin, создайте пользователя, каталоги и конфиг.
sudo useradd --no-create-home --shell /usr/sbin/nologin prom
sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo chown -R prom:prom /etc/prometheus /var/lib/prometheus
Создаём конфигурацию /etc/prometheus/prometheus.yml с интервалом опроса 15s и тремя джобами:
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- /etc/prometheus/alert.rules.yml
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['app1.internal:9100', 'app2.internal:9100']
- job_name: 'nginx'
static_configs:
- targets: ['app1.internal:9113', 'app2.internal:9113']
Unit-файл /etc/systemd/system/prometheus.service:
sudo tee /etc/systemd/system/prometheus.service > /dev/null << 'EOF'
[Unit]
Description=Prometheus Server
Wants=network-online.target
After=network-online.target
[Service]
User=prom
Group=prom
Type=simple
ExecStart=/usr/local/bin/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/var/lib/prometheus \
--web.listen-address=0.0.0.0:9090 \
--storage.tsdb.retention.time=15d
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
Проверка здоровья:
curl -s localhost:9090/-/healthy
В web-интерфейсе Prometheus (порт 9090) вкладка Targets должна показать статусы UP по джобам node и nginx. Если цель не поднимается, проверьте фаервол и DNS-имена в static_configs.
Шаг 4. Alertmanager и алерты
Prometheus сам оценивает правила, а Alertmanager отвечает за маршрутизацию уведомлений: группировку, повторы, подавление и доставку.
4.1. Настройка Alertmanager
Создайте пользователя и каталог, затем базовый конфиг /etc/alertmanager/alertmanager.yml:
global:
resolve_timeout: 5m
route:
receiver: 'team-email'
group_by: ['alertname', 'instance']
group_wait: 30s
group_interval: 5m
repeat_interval: 2h
receivers:
- name: 'team-email'
email_configs:
- to: 'ops@example.org'
from: 'alerts@example.org'
smarthost: 'smtp.internal:25'
require_tls: true
Unit-файл /etc/systemd/system/alertmanager.service:
sudo useradd --no-create-home --shell /usr/sbin/nologin alertman
sudo mkdir -p /etc/alertmanager /var/lib/alertmanager
sudo chown -R alertman:alertman /etc/alertmanager /var/lib/alertmanager
sudo tee /etc/systemd/system/alertmanager.service > /dev/null << 'EOF'
[Unit]
Description=Alertmanager
Wants=network-online.target
After=network-online.target
[Service]
User=alertman
Group=alertman
Type=simple
ExecStart=/usr/local/bin/alertmanager \
--config.file=/etc/alertmanager/alertmanager.yml \
--storage.path=/var/lib/alertmanager \
--web.listen-address=0.0.0.0:9093
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now alertmanager
Подключите Alertmanager в prometheus.yml:
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
Перезапустите Prometheus после правки.
4.2. Правила алертов
Добавим базовые правила в /etc/prometheus/alert.rules.yml. Это покроет доступность инстансов, CPU, RAM, диск и Nginx соединения.
groups:
- name: node.rules
rules:
- alert: InstanceDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: 'Экспортер недоступен: {{ $labels.instance }}'
description: 'Цель {{ $labels.job }} не отвечает более 2 минут.'
- alert: HighCPULoad
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
for: 10m
labels:
severity: warning
annotations:
summary: 'Высокая загрузка CPU на {{ $labels.instance }}'
description: 'CPU > 85% более 10 минут.'
- alert: HighMemoryUsage
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 85
for: 10m
labels:
severity: warning
annotations:
summary: 'Мало памяти на {{ $labels.instance }}'
description: 'Доля занятой памяти > 85%.'
- alert: DiskSpaceLow
expr: (node_filesystem_size_bytes{fstype!~"tmpfs|overlay"} - node_filesystem_free_bytes{fstype!~"tmpfs|overlay"}) / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"} * 100 > 85
for: 10m
labels:
severity: warning
annotations:
summary: 'Мало места на диске {{ $labels.instance }} {{ $labels.mountpoint }}'
description: 'Занято > 85% на {{ $labels.device }} ({{ $labels.mountpoint }}).'
- name: nginx.rules
rules:
- alert: NginxHighActiveConnections
expr: nginx_connections_active > 1000
for: 5m
labels:
severity: warning
annotations:
summary: 'Много активных соединений Nginx на {{ $labels.instance }}'
description: 'Активных соединений > 1000 более 5 минут. Проверьте трафик/балансировку.'
- alert: NginxNoTraffic
expr: rate(nginx_http_requests_total[5m]) == 0
for: 10m
labels:
severity: info
annotations:
summary: 'Нет запросов к Nginx на {{ $labels.instance }}'
description: 'Запросов 0 в течение 10 минут. Возможно, трафик пропал или upstream упал.'
Перезагрузите Prometheus. Убедитесь, что в веб-интерфейсе правила загружены и их состояние корректно.
Пороговые значения подбирайте под свою нагрузку. Хорошая практика — начинать с предупреждений (warning), наблюдать и уже потом повышать до critical.
Шаг 5. Grafana: быстрый старт
Установите Grafana из репозитория дистрибутива или через бинарник, запустите сервис, зайдите в веб-интерфейс на порту 3000. Добавьте источник данных Prometheus (URL — адрес и порт Prometheus, например http://prometheus.internal:9090), сохраните.
Для старта достаточно импортировать типовые дашборды:
- Node Exporter Full — системные метрики.
- Nginx Metrics (stub_status) — активные соединения и запросы.
Полезные PromQL-запросы для панелей:
# CPU usage %
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# RAM usage %
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100
# Disk used % по каждому mountpoint
(node_filesystem_size_bytes{fstype!~"tmpfs|overlay"} - node_filesystem_free_bytes{fstype!~"tmpfs|overlay"}) / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"} * 100
# Nginx active, reading, writing, waiting
nginx_connections_active
nginx_connections_reading
nginx_connections_writing
nginx_connections_waiting
# Общее число запросов
rate(nginx_http_requests_total[1m])

Если управляете серверами через панели, вам может пригодиться обзор: сравнение панелей для VDS.
Тестируем алерты и метрики
Перед тем как полагаться на мониторинг, обязательно протестируйте уведомления.
- Симуляция нагрузки CPU: на пару минут выполните
openssl speed -multi 2и посмотрите, как растёт метрика и срабатывает алерт. - Падение экспортера: временно остановите
node_exporterи убедитесь, чтоInstanceDownприходит в Alertmanager. - Nginx: создайте небольшой всплеск запросов с помощью утилиты нагрузки (например,
abилиwrk) и проверьте рост активных соединений.
Если алерты не приходят — проверьте конфиг Alertmanager, разрешение портов, корректность e-mail настроек и синхронизацию времени.
Производительность, надёжность и безопасность
Retention и место на диске
Ключевые параметры хранения Prometheus: --storage.tsdb.retention.time и/или --storage.tsdb.retention.size. Для одиночного VDS обычно достаточно 15–30 дней. Следите за свободным местом и добавьте алерт на заполнение дисков.
Снижение нагрузки
- Не делайте
scrape_intervalслишком маленьким (15s — разумно). - Не добавляйте тяжёлые recording rules без необходимости.
- Разносите Prometheus и нагрузочные приложения по разным дискам, если доступно.
Безопасность
- Ограничьте сетевой доступ к портам 9090, 9093, 9100, 9113 и 3000 фаерволом.
- Слушайте экспортеры на
127.0.0.1, если Prometheus на той же машине. - Запускайте сервисы под отдельными не-привилегированными пользователями.
- Резервируйте каталоги конфигураций и данных.
Расширения и следующий шаг
- Blackbox Exporter — для HTTP/TCP/ICMP-проб снаружи.
- Pushgateway — для краткоживущих batch-задач.
- Лог-метрики Nginx (коды ответов, percentiles) через специализированные экспортеры логов или модуль VTS.
- Сегментация алертов по окружениям (prod/stage) через лейблы и маршрутизацию Alertmanager.
- Silence-правила в Alertmanager на время плановых работ.
Чек-лист «60 минут»
- 0–10 мин: Node Exporter — установка, проверка, фаервол.
- 10–25 мин: Nginx
stub_statusи Nginx Prometheus Exporter. - 25–40 мин: Prometheus — конфиг
prometheus.yml, запуск, проверка целей. - 40–50 мин: Alertmanager — конфиг, запуск, подключение к Prometheus.
- 50–60 мин: Grafana — источник данных, импорт базовых дашбордов, тест алертов.
FAQ
Можно ли держать всё на одном сервере?
Да. Для небольшого проекта Prometheus, Alertmanager, Grafana и экспортеры могут жить на одном VDS. Важно ограничить доступ к портам и контролировать потребление ресурсов.
Почему я не вижу HTTP-коды по Nginx?
stub_status их не даёт. Нужен модуль VTS или парсер логов в метрики. Для «быстрого» старта достаточно активных соединений и счётчиков запросов.
Что критичнее: CPU или Load Average?
Для контейнеризованных и современных систем CPU-метрики надёжнее. node_load* учитывают планировщик и количество ядер, их сложнее интерпретировать без контекста.
Как правильно подобрать пороги?
Соберите недельную историю, посмотрите на типичный уровень и всплески. Поставьте предупреждения чуть выше медианы «пиков», а критические — значительно выше или при длительном превышении.
Почему алерты срабатывают «слишком часто»?
Добавьте for: в правила, увеличьте интервал оценки и сгладьте метрики агрегатами (например, avg_over_time). Избегайте алертов «на каждую секунду».
Готово. У вас базовый, но рабочий monitoring-стек на Prometheus с Node Exporter, nginx metrics через экспортер, Alertmanager и графиками в Grafana. Далее можно развивать систему под ваши нагрузки, добавлять новые экспортеры, настраивать маршрутизацию алертов и «шлифовать» дашборды под команду.


