Собираем стек мониторинга в Docker
Вот мы и подошли к финалу цикла. В финальной части, я покажу как можно быстро развернуть стек: zabbix, grafana, prometheus, postgresql, node-exporter, postgres-exporter в Docker. То что мы разворачивали целым циклом, можно развернуть в docker и запускать одной командой. Давайте приступим.
Создадим отдельную директорию, в которой будем хранить докер компоус файл для старта и стопа контейнеров.
mkdir monitoring
Теперь перейдем в нее:
cd monitoring
Создадим файл для оркестрации контейнеров:
nvim docker-compose.yml
services:
# ==========================================
# Базы данных
# ==========================================
zabbix-db:
image: postgres:16-alpine
container_name: zabbix-db
environment:
POSTGRES_USER: zabbix
POSTGRES_PASSWORD: Qwerty12
POSTGRES_DB: zabbix
volumes:
- zabbix_db_data:/var/lib/postgresql/data
networks:
- monitoring-net
restart: unless-stopped
grafana-db:
image: postgres:16-alpine
container_name: grafana-db
environment:
POSTGRES_USER: grafana
POSTGRES_PASSWORD: Qwerty12
POSTGRES_DB: grafana
volumes:
- grafana_db_data:/var/lib/postgresql/data
networks:
- monitoring-net
restart: unless-stopped
# ==========================================
# Zabbix
# ==========================================
zabbix-server:
image: zabbix/zabbix-server-pgsql:alpine-7.0-latest
container_name: zabbix-server
ports:
- "10051:10051"
environment:
DB_SERVER_HOST: zabbix-db
POSTGRES_USER: zabbix
POSTGRES_PASSWORD: Qwerty12
POSTGRES_DB: zabbix
depends_on:
- zabbix-db
networks:
- monitoring-net
restart: unless-stopped
zabbix-web:
image: zabbix/zabbix-web-nginx-pgsql:alpine-7.0-latest
container_name: zabbix-web
ports:
- "8080:8080"
environment:
ZBX_SERVER_HOST: zabbix-server
DB_SERVER_HOST: zabbix-db
POSTGRES_USER: zabbix
POSTGRES_PASSWORD: Qwerty12
POSTGRES_DB: zabbix
depends_on:
- zabbix-server
- zabbix-db
networks:
- monitoring-net
restart: unless-stopped
# ==========================================
# Grafana
# ==========================================
grafana:
image: grafana/grafana:11.4.0
container_name: grafana
ports:
- "3000:3000"
environment:
#Настройка подключения к базе данных PostgreSQL
GF_DATABASE_TYPE: postgres
GF_DATABASE_HOST: grafana-db:5432
GF_DATABASE_USER: grafana
GF_DATABASE_PASSWORD: Qwerty12
GF_DATABASE_NAME: grafana
volumes:
- grafana_data:/var/lib/grafana
depends_on:
- grafana-db
networks:
- monitoring-net
restart: unless-stopped
# ==========================================
# Prometheus Stack
# ==========================================
prometheus:
image: prom/prometheus:v2.55.1
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=15d'
- '--web.enable-lifecycle'
networks:
- monitoring-net
restart: unless-stopped
node-exporter:
image: prom/node-exporter:v1.9.0
container_name: node-exporter
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
networks:
- monitoring-net
restart: unless-stopped
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.51.0
container_name: cadvisor
ports:
- "8081:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
privileged: true
networks:
- monitoring-net
restart: unless-stopped
postgres-exporter:
image: prometheuscommunity/postgres-exporter:v0.16.0
container_name: postgres-exporter
ports:
- "9187:9187"
environment:
DATA_SOURCE_NAME: "postgresql://zabbix:Qwerty12@zabbix-db:5432/zabbix?sslmode=disable"
depends_on:
- zabbix-db
networks:
- monitoring-net
restart: unless-stopped
# ==========================================
# Сети и тома
# ==========================================
networks:
monitoring-net:
driver: bridge
volumes:
zabbix_db_data:
grafana_db_data:
grafana_data:
prometheus_data:

Рядом создаем конфиг prometheus.yml
nvim prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
- job_name: 'postgres'
static_configs:
- targets: ['postgres-exporter:9187']

Запускаем оркестрацию. Если запуск впервые, то докер будет загружать контейнеры, это займет время. При следующих запусках это будет мгновенно.
docker compose up -d
После запуска, пошла загрузка образов контейнеров.

После загрузки, докер создаст контейнеры.

Теперь можно проверять.
Настройка стека
Заходим в Zabbix: http://192.168.31.55:8080 (логин по умолчанию: Admin, пароль: zabbix).

Порт 8080 используется только для веб-интерфейса (чтобы мы могли заходить в панель управления через браузер). Для общения между Zabbix Agent и Zabbix Server используется специальный порт 10051 (он уже успешно проброшен в нашем docker-compose.yml: "10051:10051").
Как правильно прописать сервер zabbix в контейнере агенту на машине по шагам:
Шаг 1. Настройка файла конфигурации агента (zabbix_agentd.conf или zabbix_agent2.conf)
На той машине, где установлен агент (даже если это тот же самый сервер 192.168.31.55), открываем конфиг агента и указываем:
# IP-адрес Zabbix Server (можно указать несколько через запятую, если нужно)
Server=192.168.31.55
# IP-адрес для активных проверок (отправка данных инициатором агентом)
ServerActive=192.168.31.55
# Уникальное имя этого хоста. Оно должно БУКВА В БУКВУ совпадать с именем,
# которое вы создадите в веб-интерфейсе Zabbix.
Hostname=my-astra-server
После изменения конфига обязательно перезапускаем службу агента на этой машине (например, sudo systemctl restart zabbix-agent).
Шаг 2. Добавление хоста в веб-интерфейсе Zabbix
Заходим в Zabbix: http://192.168.31.55:8080 (логин по умолчанию: Admin, пароль: zabbix).
Переходим в «Сбор данных (или Configuration)» → «Узлы сети (Hosts)» → «Создать узел сети (Create host)».
Заполняем поля:
- Имя узла сети: ИМЯ_СЕРВЕРА (должно точно совпадать с Hostname в конфиге агента).
- Видимое имя: любое понятное (например, Astra Linux Main Server).
- Группы узлов сети: выберите, например, Linux servers.
- В блоке Интерфейсы - нажмите "Добавить" -> "Агент":
- IP-адрес: 192.168.31.55 (если агент стоит на этом же сервере. Если на другом - указываем IP того другого сервера).
- Порт подключения: 10051 (оставляем как есть, это стандартный порт).
Нажмите «Добавить (Add)».
Теперь переходим и проверяем node-exporter:

Проверяем сервер prometheus:
http://localhost:9090

Теперь графану:

Логин и пароль в графане:
adminadmin

За несколько минут, мы с Вами развернули несколько сервисов. Давайте теперь попроуем это настроить. Мы уже проделывали настройки zabbix+grafana, а так же prometheus, по этому я быстро пробегусь по настройкам без объяснений.
Начнем со связки графаны и заббикса. Идем в графану и добавляем плагин.

Активируем его.

Создаем соединение для zabbix:

Так как у нас контейнеры находятся в одной сети и они друг друга видят (одна сеть между контейнерами), то мы указываем имя контейнера.
http:// к имени контейнера, на что получил ошибку, после скриншотов по zabbix будет скриншот ошибки. Вы же указывайте сразу правильную: http://zabbix-web:8080/api_jsonrpc.php
Идем на zabbix, нам нужно создать учетную запись и сгенерировать API ключ, для подключения с графаны к заббиксу.


Создаем пользователя grafana-user

Создаем API ключ

Копируем его и возвращаемся в графану.
Вставляем ключ в соединение

Как я уже говорил ранее, ругнулся на отсутствие http://

Дописал http://

Но при сохранении снова ошибка.

Из ошибки видно, что у учетной записи не хватает прав на вызов метода отображения групп хостов.
Идем снова в заббикс и редактируем созданную учетную запись grafana-user. Я случайно создал ее не User role, а Guest role.
Исправляем.


Снова идем в графану и пробуем сохранить еще раз.

Сразу добавим еще одно соединение, а именно prometheus.


Указываем http://prometheus:9090


Мы добавили два соединения

Теперь добавим готовые дашборды.
Импортируем готовые дашборды
Готовые дашборды - это готовые «пульты управления» (шаблоны), которые показывают состояние систем в реальном времени. Не нужно рисовать графики самому - скачал, подключил, смотришь.
Плюсы:
- Экономия времени - не надо с нуля придумывать графики, все уже нарисовано.
- Проверено сообществом - миллионы людей используют, все важные метрики учтены.
- Быстрый старт - подключил экспортер → импортировал дашборд по ID → готово.
Проще говоря: это «готовые торпеды» для Grafana, чтобы сразу видеть, что происходит, а не строить приборы с нуля.
Первым добавим Node exporter


Node exporter под ID 1860 - указываем его и нажимаем «Load».


Как видим, метрики собираются, данные выводятся.
Теперь импортируем готовый дашборд, который отображается состояние контейнеров cadvisor exporter под ID 14282




Теперь мы отслеживаем состояние контейнеров.
Импортируем дашборд для Postgres exporter под ID 9628



Так же есть альтернатива этому дашборду под ID 14114



В двух словах про каждый:
Node exporter - дашборд про «железо» сервера: сколько CPU, RAM, места на диске, нагрузка. Как спидометр и датчики в машине.
cAdvisor - дашборд про Docker контейнеры: кто сколько ест памяти и процессора, сколько сетевого трафика. Как диспетчерская в аэропорту, где видно каждый самолет.
Postgres exporter - дашборд про базу данных PostgreSQL: сколько запросов, какие медленные, размер базы, блокировки. Как приборная панель у врача - сразу видно, где болит.
Я не буду здесь показывать, как мы будем рисовать дашборды в zabbix или grafana, так как все абсолютно так же, как и в цикле статей по мониторингу. Вся лишь разница в настройках соединений, где указан не ip адрес, а имя контейнера Docker. Вот так, за несколько секунд, можно быстро развернуть полноценную систему мониторинга в докере. Можно использовать как карманную/портативную эту сборку, а можно включать когда это нужно и отключать когда нет.
В данном цикле мы прошлись по основным системам мониторинга. Есть разные системы мониторинга, но в основном платные. Здесь же мы рассмотрели opensource проекты. Мониторить инфраструктуру нужно обязательно - это считается хорошей практикой, как правила этикета. Надеюсь для Вас данный цикл был познователей ну а я завершаю его и увидимся в других статья. Удачи в построении своей системы мониторинга!