Распределённый мониторинг 7 серверов: Zabbix 7 + TimescaleDB + два канала алертов
Было: 7 серверов у разных провайдеров — 4 ноды Outline VPN, MTProxy-узел, Matrix-стек и несколько веб-сервисов без централизованного мониторинга.
Стало: 1 выделенный Zabbix-сервер (7.0.26 LTS, PostgreSQL 18.4 + TimescaleDB 2.26.4), 6 хостов с active-mode agent2 и уникальным 256-битным TLS-PSK, 9 гипертаблиц вместо housekeeping, два параллельных канала алертов (Telegram + Matrix) с severity-маршрутизацией и grace 10/5/2 минут. Разбираем каждый блок решения.

Как мы развернули собственный Zabbix 7.0.26 с TimescaleDB для мониторинга распределённой инфры: 7 серверов, 9 гипертаблиц, два параллельных канала алертов (Telegram + Matrix), severity-маршрутизация с grace 10/5/2 минут и «без выдуманных SaaS».
Содержание
Задача: распределённая инфра без централизованного контроля
Распределённая инфраструктура клиента выросла органично: 4 ноды Outline VPN, 1 MTProxy-узел, отдельный хост с Matrix-стеком (Synapse + 12 контейнеров) и несколько веб-сервисов, включая Matrix-federation на нестандартном порту 8448. До внедрения о падениях узнавали постфактум — от пользователей, когда сервис уже лежал. Ни один хост не отдавал метрики наружу, сроки жизни TLS-сертификатов не отслеживались, WHOIS доменов был «на памяти», а Matrix-федерация работала без контроля очередей федерации.
На этапе аудита зафиксировали конкретные пробелы: нет централизованного мониторинга по CPU/RAM/диску/сети, нет отслеживания состояния Docker-контейнеров, нет ICMP-проверок доступности внешних адресов с разных точек, нет прикладных проверок на состояние ключевых веб-эндпоинтов, нет внешнего мониторинга Outline shadowbox.
Сформулировали требования к мониторинговому решению: один выделенный Zabbix-сервер с публичным IP, агенты на 6 удалённых хостах (4 Outline + 1 MTProxy + 1 Matrix), шифрование канала «агент → сервер», два независимых канала уведомлений (Telegram плюс резерв в Matrix), хранение истории без блокирующего housekeeping — вместо него TimescaleDB.
Отдельно поставили задачу мониторинга внешних артефактов — доменов, TLS-сертификатов и доступности веб-сервисов. WHOIS-проверка на 30/7/1 день до истечения, TLS expiry на 30/14/7 дней, HTTP-доступность каждые 60 секунд. На наших проектах это даёт запас в неделю на оплату и обновления без аврала.
По итогам аудита зафиксировали бюджет работ и приступили к развёртыванию: 1 выделенный сервер мониторинга + 6 удалённых хостов. Общее число серверов под наблюдением — 7, плюс виртуальные web-services-хосты в UI Zabbix для отслеживания доменов и сертификатов.

Архитектура решения: Zabbix 7 + TimescaleDB на выделенном сервере
Для внедрения Zabbix мы выбрали ветку 7.0 LTS — поддержка до Q4 2029, без обязательных major-апгрейдов на горизонте планирования проекта. Конкретный патч в проде — Zabbix server 7.0.26 и zabbix-agent2 7.0.26.
Под сам сервер мониторинга выделили отдельную VM: 4 vCPU, 8 ГБ RAM, 50 ГБ диск плюс 4 ГБ swap-файл. Класть Zabbix на одну из боевых машин клиента нельзя: изоляция отказов важнее сэкономленных ресурсов. Мониторинг должен переживать падение любого из наблюдаемых хостов.
Операционная система — Ubuntu 24.04 LTS, установка из официальных пакетов Zabbix. Сборка из исходников или контейнеризация для одного экземпляра только усложняют последующие обновления.
Базу данных строили на PostgreSQL 18.4 с расширением TimescaleDB 2.26.4. Это ключевое архитектурное решение: вместо встроенного housekeeping работают гипертаблицы с native compression и retention policies. Подробнее — в следующем разделе.
Веб-интерфейс обслуживает Nginx 1.24 с PHP-FPM 8.3, HTTP/2, TLS 1.3 и HSTS (max-age=31536000). TLS-сертификат — ECDSA P-256 от Let’s Encrypt с автообновлением через snap.certbot.renew.timer.
Архитектурно используется один Zabbix-сервер без Zabbix-proxy: 6 удалённых хостов не оправдывают усложнение схемы. Связь агент→сервер идёт напрямую через интернет с шифрованием TLS-PSK — об этом отдельно ниже.

apt install postgresql-18 postgresql-18-timescaledb \
zabbix-server-pgsql zabbix-frontend-php \
zabbix-nginx-conf zabbix-sql-scripts zabbix-agent2
TimescaleDB вместо housekeeping: 9 гипертаблиц с сжатием
Схема Zabbix использует девять таблиц истории и трендов: history, history_uint, history_str, history_text, history_log, trends, trends_uint плюс две служебные (всего 9). На активной инсталляции без TimescaleDB эти таблицы быстро разрастаются, а встроенный housekeeping удаляет строки поштучно в одной транзакции — это конкурирует с записью новых метрик и приводит к раздуванию таблиц.
После установки расширения превратили все девять таблиц в гипертаблицы скриптами из поставки zabbix-sql-scripts. Гипертаблица в TimescaleDB разбивает данные на чанки по времени (поставили 7 дней), и удаление старых данных превращается в DROP чанка — операция O(1) вместо O(N).
Включили нативную компрессию на чанках старше 7 дней. По бенчмаркам docs.timescale.com на исторических числовых метриках сжатие достигает ×10. На уровне всей схемы это экономит порядка 90% диска. Общее ускорение очистки по сравнению со стандартным housekeeping — до ×100.
Ретеншн настроили асимметричным: сырая история хранится 7 дней и сжимается, тренды остаются 365 дней в сжатом виде. Этого достаточно для разбора инцидентов и годовых отчётов по доступности.
В веб-интерфейсе Zabbix в Administration → General → Housekeeping отключили внутренний housekeeping для всех таблиц, переведённых на TimescaleDB. Иначе обе системы конкурируют за один набор строк и появляются блокировки.
Инсталляция развёрнута с чистого листа, поэтому своих конкретных «до/после» по размеру БД мы в статье не приводим — работаем на общих бенчмарках TimescaleDB плюс фактических режимах работы наших прошлых проектов.
SELECT create_hypertable('history', 'clock', chunk_time_interval => 604800, migrate_data => true);
ALTER TABLE history SET (timescaledb.compress, timescaledb.compress_segmentby = 'itemid');
SELECT add_compression_policy('history', INTERVAL '2 days');
SELECT add_retention_policy('history', INTERVAL '90 days');
TLS-PSK + active-mode агенты для удалённых хостов
Канал агент→сервер идёт через публичный интернет без VPN. Поэтому выбрали TLS-PSK шифрование: симметричный pre-shared key, без PKI и без затрат на выдачу сертификата на каждый хост. Для шести внешних хостов PKI избыточен.
Каждый хост получает уникальный 256-битный PSK (32 байта рандома). PSK хранится в файле с правами 600 и владельцем root. Важная операционная практика: PSK копируется через рабочую станцию инженера, а не «host-to-host» — чтобы компрометация одного хоста не давала доступ к данным остальных.
На каждом хосте используется Zabbix Agent 2 в active-mode — агент сам устанавливает исходящее соединение к серверу на 10051/tcp и пушит метрики. Это упрощает файрвол: NAT клиента не трогаем, входящие порты на VPN-нодах открывать не нужно.
Набор шаблонов на удалённых хостах: Linux by Zabbix agent active, Docker by Zabbix agent 2, ICMP ping и кастомный шаблон для Outline shadowbox (HTTP-agent + Prometheus-экспортер внутри контейнера). Поддерживаются одновременно Ubuntu 22.04 и 24.04 LTS.
UFW на сервере мониторинга разрешает входящее на 10051/tcp только с IP целевых хостов — второй контур защиты поверх TLS. Отправление было настроено в active mode с временем на переподключение 30 секунд, поэтому кратковременные обрывы сети не создают ложных «nodata»-алертов ниже порога в 5 минут.
openssl rand -hex 32 | tee /etc/zabbix/zabbix_agent2.psk
chmod 600 /etc/zabbix/zabbix_agent2.psk
chown zabbix:zabbix /etc/zabbix/zabbix_agent2.psk
Мониторинг доменов и TLS-сертификатов (zabbix-webservices)
Мониторинг железа без прикладного слоя — половина решения. Для каждого публичного адреса клиента критичны три параметра: домен зарегистрирован и не истекает в ближайшие 30 дней, HTTP/HTTPS эндпоинт отвечает корректным кодом, TLS-сертификат валиден и обновится вовремя. Подробнее о принципах «внешнего взгляда» и SSL-проверок разбирали в статье мониторинг веб-сайтов и SSL-сертификатов через check_http.
Мы открыли GitHub-репозиторий IT-for-Prof/zabbix-webservices со своим шаблоном. Он объединяет все три проверки (HTTP, TLS, WHOIS) в один виртуальный хост Zabbix с макросом списка URL — в нашем кейсе в списке 4 адреса, включая Matrix-federation на нестандартном порту 8448. Не плодить по отдельному хосту на каждый домен — это упрощает инвентаризацию и вид в UI.
HTTP-доступность проверяется каждые 60 секунд, ответ должен быть 200/301/302. TLS expiry собирается раз в час через web.certificate.get и выводит триггеры на 30, 14 и 7 дней до истечения. WHOIS-проверка выполняется раз в сутки и поднимает триггеры на 30/7/1 день до истечения регистрации. Похожую логику мы ранее применяли в шаблоне мониторинга DNS почтового домена.
Для веб-сценариев, где нужно открывать страницы как браузер, используется Zabbix Web Service — отдельный systemd-юнит из поставки Zabbix 7. Он запускает headless Chromium и умеет проверять рендеринг и ошибки в консоли.
Собственный мониторинг WHOIS важен потому, что письма от регистратора о скором истечении регистрации легко пропустить — они часто уходят на адрес бывшего сотрудника или в спам. Мониторинг в Zabbix с явными триггерами и теми же двумя каналами уведомлений снимает этот класс рисков.
zabbix_get -s 127.0.0.1 -k 'web.certificate.get[api.example.com,443,api.example.com]'
Алерты, которые доходят: Telegram + Matrix параллельно
Алерт, который не дошёл до инженера, хуже отсутствия алерта — создаёт ложное чувство контроля. Поэтому при внедрении Zabbix мы всегда настраиваем минимум два параллельных (не каскадных) канала уведомлений. В этом проекте это ZNT-бот в Telegram + Matrix-бот в собственный Synapse-хоумсервер клиента. Мы продвигаем Matrix как корпоративный мессенджер под ключ; сравнение с альтернативами см. в обзоре Matrix vs Mattermost vs Rocket.Chat.
Telegram-канал поднят на собственном боте (выдан через BotFather). Сообщения форматируются как HTML с явным хостом, тегами триггера, ссылкой на дашборд и inline-кнопками «Acknowledge» по webhook. График прикрепляется к Problem-сообщению через cookie-логин в веб-фронт.
Прямая доставка с российских IP-адресов к Telegram API периодически нестабильна из-за сетевых ограничений и нестабильной маршрутизации. Именно поэтому нужен второй канал. Для стабилизации Telegram опционально прописывается SOCKS5/HTTPS-прокси через VPS вне РФ — в конфиге /usr/lib/zabbix/alertscripts/zbxTelegram_config.py поля tg_proxy=True и tg_proxy_server.
Matrix-канал реализован на отдельном боте через long-lived compatibility-token от MAS внутреннего Synapse-хоумсервера клиента. О подходах к webhook-ботам в Matrix мы подробно писали в «Бот для Matrix через webhook». Сообщения всех severity падают в одну комнату дежурной смены. Канал идёт напрямую, не зависит от внешних API.
Severity-маршрутизация вынесена в три отдельных action с собственным grace-периодом перед отправкой: Average — 10 минут, High — 5 минут, Disaster — 2 минуты. Если триггер закрылся внутри grace-периода — сообщение не уходит (фильтр кратковременных всплесков, анти-флаппинг). На каждый action — три операции: Problem (после grace), Recovery (при закрытии) и Update (при подтверждении/комментарии в UI).
Подавление во время техработ настраивается флагом pause_suppressed в action, symptom-триггеры скрываются через pause_symptoms. Для тонкой подстройки на уровне отдельных триггеров используются тэги: ZNTSettings=no_alert или not_notify или no_graph или period=43200, а ZNTMentions=@username вызывает упоминание конкретного человека.
curl -sS "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
-d "chat_id=${CHAT_ID}" \
-d "parse_mode=HTML" \
-d "text=${MESSAGE}"
Инженерные тонкости: ECDSA-сертификат, fail2ban, UFW, swap
Несколько мелких, но влияющих на эксплуатацию решений, которые мы включаем по умолчанию на каждом внедрении Zabbix «под ключ».
TLS-сертификат выпустили как ECDSA P-256 через Let’s Encrypt. Меньше сигнатуры, быстрее handshake по сравнению с RSA-2048. Обновление автоматическое через systemd-таймер snap.certbot.renew.timer. HSTS включён с max-age=31536000.
UFW на сервере мониторинга пускает входящие только на 22/tcp, 80/tcp, 443/tcp и 10051/tcp (для агентов). Стандартная процедура при настройке правил firewall — включён kill-switch (автоматический откат набора правил через 5 минут, если оператор не подтвердил).
fail2ban поднят с двумя jails: sshd (5 неудачных попыток → бан на час) и zabbix-web (защита от подбора паролей в веб-интерфейсе Zabbix). Без fail2ban публичный SSH всегда получает сотни ботовых попыток в сутки.
Swap на сервере мониторинга — 4 ГБ файл с vm.swappiness=10. PostgreSQL под TimescaleDB при штатной нагрузке укладывается в 8 ГБ RAM, но при VACUUM или массовом удалении чанков пиковые всплески выжимают всё доступное. Swap страхует от OOM-killer и потери нескольких секунд метрик при перезапуске PostgreSQL-процесса.
Для работы с Zabbix API выпустили бессрочный bearer-токен (через User settings → API tokens). Токен не зависит от смены пароля Admin, работает в заголовке Authorization: Bearer ... и удобен для CI-скриптов клиента. При компрометации отзывается через UI или token.delete.
Что осталось как зона роста
Честные границы решения, которые мы сознательно вынесли в «open tasks» в документе передачи:
- Бэкапы PostgreSQL лежат на том же диске. Скрипт
/etc/cron.daily/zabbix-backupделаетpg_dump -F c -Z 6и хранит 14 последних копий в/var/backups/zabbix/. Это защищает от случайного удаления, но не от потери всей VM. Рекомендуем настроить выгрузку этого каталога на внешнее хранилище (S3 или rsync на другую машину). - Нет monitoring-of-monitoring. Если сам сервер Zabbix «упадёт» — о проблеме будет известно только по отсутствию входящих алертов. Рекомендуем внешний пинг с другой машины — UptimeRobot, Healthchecks или отдельный хост с проверкой HTTPS-фронта Zabbix.
- LDAP/SAML/SSO не подключены. Аутентификация в Zabbix — только локальная. При росте команды и появлении прав по ролям имеет смысл рассмотреть интеграцию с SSO-провайдером.
Это намеренные границы первого захода — заказчик хотел production за один этап, вынос бэкапов и прочие расширения мы передаём в рамках услуги администрирования серверов.
ssl_certificate /etc/letsencrypt/live/zabbix.example.com/fullchain-ecdsa.pem;
ssl_certificate_key /etc/letsencrypt/live/zabbix.example.com/privkey-ecdsa.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
Итог
- Один выделенный Zabbix-сервер и 6 удалённых хостов (Outline VPN-ноды, MTProxy, Matrix-стек) — 7 серверов под наблюдением.
- PostgreSQL 18.4 + TimescaleDB 2.26.4: 9 гипертаблиц, native compression, до ~90% экономии диска.
- TLS-PSK 256 бит + active-mode agent2 для всех удалённых хостов без VPN.
- Два параллельных канала алертов (Telegram + Matrix), severity 3 уровней с grace 10/5/2 минут (анти-флаппинг).
- Мониторинг доменов: WHOIS 30/7/1 день и TLS expiry 30/14/7 дней через готовый шаблон из GitHub IT-for-Prof/zabbix-webservices.
Часто задаваемые вопросы
Ответы на часто задаваемые вопросы по теме статьи.
openssl rand -hex 32), который копируется через рабочую станцию инженера. NAT клиента трогать не нужно — входящих портов на целевых хостах открывать не приходится.Константин Тютюнник — инженер IT For Prof. Специализируется на внедрении и поддержке self-hosted инфраструктуры: Zabbix, TimescaleDB, Matrix Synapse, Outline VPN, Nextcloud. Автор шаблонов IT-for-Prof/zabbix-webservices и других open-source-решений в GitHub-организации IT-for-Prof.
Развернём ваш собственный сервер мониторинга за 3–5 рабочих дней с передачей проекта и git-репозиторием всех конфигов — см. «Внедрение Zabbix под ключ». Для расширения по бэкапам, SSO и внешнему пингу — в рамках нашего администрирования серверов. Из связанных кейсов полезны: мониторинг Proxmox на Pulse и круглосуточный мониторинг серверов Zabbix.



