Я держу небольшую инфраструктуру: 5 VPS, MySQL и ClickHouse кластеры. На них работают пет-проекты и небольшие продукты вроде AskAds, VkAdsTool и ClearTranscriptBot. Есть реальные пользователи, которым важна стабильность.
Сервисы редко падают мгновенно. Обычно они сначала деградируют: под нагрузкой процессы начинают вытесняться в swap, RAM Usage постепенно растёт на несколько мегабайт в час, I/O Latency увеличивается до неприличных значений из-за шумного соседа на общем хосте. Но к моменту, когда приходит алерт "сервис недоступен", инцидент уже влияет на пользователей.
Я использую Netdata на своих серверах достаточно давно, и не один раз она помогала увидеть признаки деградации до того, как становилось поздно. Ниже я расскажу как Netdata работает у меня на проде: установка, конфиги, алерты, как смотреть метрики всех серверов в одном месте и три реальных случая, в которых Netdata спасла меня от даунтайма.
Что я хочу от мониторинга
От мониторинга мне нужно одно: когда в 3 ночи что-то сломалось, быстро понять, что именно деградировало и с какого момента.
Для этого мне нужны метрики по:
- CPU по ядрам, отдельно system / user / iowait.
- Memory pressure, swap-in / swap-out.
- Диск: throughput, IOPS, длина очереди, ошибки.
- Сеть: throughput, retransmits, packet drops.
- Здоровье сервисов: Nginx, Postgres, MySQL, Redis, Docker, systemd-юниты.
- Алерты: потому что дашборды помогают расследовать проблему, но редко помогают вовремя её заметить.
Почему именно Netdata
Обычно для таких задач используют Prometheus + Grafana. Но в моей инфраструктуре Netdata оказалась удобнее из-за другого набора компромиссов:
- Установка одной командой. Достаточно запустить
kickstart.sh, и через несколько минут агент уже собирает базовые метрики сервера. - Низкое потребление ресурсов. На моих серверах Netdata обычно укладывается в 50–100 МБ RAM и 1–5% CPU.
- Метрики с разрешением в 1 секунду. При агрегации метрик с интервалом 10–30 секунд короткий 4-секундный спайк легко теряется. С 1-секундным разрешением Netdata такие короткие пики остаются видимыми.
- Автоматическое обнаружение локальных сервисов. Если Nginx, Postgres, Redis, Docker или systemd находятся на той же машине, где установлен Netdata agent, метрики начинают собираться автоматически после перезапуска агента.
- Алерты из коробки. Базовые алерты на CPU, RAM, disk, swap, load average и другие типичные проблемы уже настроены. Дальше остаётся адаптировать пороги под свою инфраструктуру.
Три инцидента, которые начинались незаметно
Приведу три ситуации, где обычный healthcheck заметил бы проблему слишком поздно — уже когда она влияет на пользователей. Именно такие деградации метрики Netdata помогают увидеть раньше.
Случай 1. Утечка памяти, которая копилась неделю
Предыстория. В какой-то момент получаю сообщение от клиента, что сервис не работает. Быстро захожу по SSH, не нахожу процесса сервиса, смотрю в journalctl и вижу неприятные OOM Killed. Быстро перезапускаю и иду смотреть в код, чтобы найти проблему.
Неверное предположение. Конечно, я не хотел долго копаться в старом коде, поэтому просто предположил, что пользователь залил в сервис очень большой файл (который полностью загружается в RAM), для которого не хватало памяти. Поэтому просто поставил лимит на размер загружаемого файла.
Помогло ли это. Конечно нет! Это наоборот ухудшило ситуацию: я стал меньше следить за uptime сервиса, предполагая, что теперь точно не будет никакой ошибки.
Чем всё закончилось. После очередного падения я нашёл банальную проблему в Python-коде - добавлял данные в массив и никогда его не очищал. Если бы я использовал Netdata, то увидел бы тренд роста памяти задолго до OOM.
Случай 2. Шумный сосед на общем диске
Преамбула. Простой бекенд на VPS начал тормозить в произвольные моменты. Ошибок никаких нет, ни в логах, ни в системных сообщениях.
Что увидел в Netdata. Здесь Netdata помогла почти сразу: disk.iops и disk.await улетели вверх, но моя виртуалка при этом почти ничего не читала и не писала. Значит, проблема была не в моём сервисе, а, скорее всего, в соседней виртуалке на том же shared-хосте, которая забивала общий диск.
Что помогло. Поддержка перенесла мою виртуалку на другой хост, и проблема ушла. А я вернул и нормально настроил I/O-алерты, которые до этого сам же выключил.
Случай 3. Постепенный рост swap usage
С чего всё началось. Один из бекендов начал отдавать случайные 500-е. Health-дашборд показывал рост response time p95, но не объяснял причину. Первый инстинкт был простой: перезапустить сервис и посмотреть, повторится ли. Но это как раз тот случай, когда рестарт замаскировал бы причину.
Что показала Netdata. На графике mem.swapio было видно, что последние 36 часов постепенно увеличивался swap-out. Свободной памяти почти не оставалось. CPU Usage выглядел нормально, но на самом деле процессор часто ждал диск: система тратила время не на полезную работу, а на постоянный обмен страницами памяти со swap.
Где была проблема. В предыдущем обновлении конфига сервиса один из параметров был увеличен в 5 раз, но запаса по памяти на сервере уже не было. Даже небольшие дополнительные аллокации начали уходить в swap. Откатил конфиг и добавил два алерта: на system.ram available_percent < 15 и на mem.swapio out > 1MB/s в течение 5 минут. Теперь такую деградацию видно заранее.
Быстрая установка Netdata без лишней возни
1. Установка агента. Официальный установочный скрипт сам определит дистрибутив и настроит запуск Netdata через systemd.
# Скачиваем скрипт в /tmp/netdata-kickstart.sh
wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh
# Запускаем установку агента
sh /tmp/netdata-kickstart.sh --stable-channel --disable-telemetry2. Закрытие публичного доступа. По умолчанию дашборд Netdata разворачивается на порту 19999 и доступен без логина и пароля. Если этот порт открыт, метрики сможет посмотреть любой, кто знает адрес сервера. Поэтому Netdata остаётся доступной только локально, а внешний доступ я проксирую через Nginx с basic auth.
[web]
bind to = 127.0.0.1Ставим утилиту htpasswd и заводим пользователя (например, stats):
sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/netdata.htpasswd statsДобавляем в конфиг Nginx новый location, который проксирует запросы на локальный Netdata и требует basic auth:
location /netdata/ {
proxy_pass http://127.0.0.1:19999/;
auth_basic "Netdata";
auth_basic_user_file /etc/nginx/netdata.htpasswd;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}Перезагружаем Nginx, и дашборд становится доступным по https://your-domain/netdata/ за логином и паролем:
sudo systemctl reload nginx3. Настройка уведомлений в Telegram. Для одного человека Telegram удобнее остальных каналов: алерт прилетает мгновенно, видно прямо на экране, настраивается за пару минут.
Сначала создаём бота: пишем @BotFather, отправляем /newbot, придумываем имя — в ответе будет токен вида 1234567890:AAA.... Свой chat ID берём через @userinfobot: достаточно отправить ему любое сообщение.
Дальше указываем оба значения в конфиге уведомлений:
SEND_TELEGRAM="YES"
TELEGRAM_BOT_TOKEN="1234567890:AAA..."
DEFAULT_RECIPIENT_TELEGRAM="123456789"Отправляем тестовое сообщение, чтобы убедиться, что алерты доходят:
sudo netdatacli reload-health
sudo -u netdata /usr/libexec/netdata/plugins.d/alarm-notify.sh test4. Убираем лишний шум и нагрузку. Netdata из коробки показывает много метрик, но не все они нужны каждый день. Я советую немного отредактировать конфиги, чтобы уведомления не засирали чатик с алертами.
Например, отключить то, что вам скорее всего не пригодится:
[plugins]
# Очень прожорливый, нужен только для deep kernel tracing
ebpf = no
# Low-level профилирование CPU
perf = no
# Читает логи, лишняя нагрузка
systemd-journal = no
# Отключайте только если вы не используете OpenTelemetry
otel = no
otel-signal-viewer = no
network-viewer = no
# Низкоуровневые метрики ядра, почти никогда не нужны
nfacct = no
slabinfo = no
debugfs = noКак смотреть метрики всех серверов в одном месте
Если у вас несколько VPS, у Netdata есть схема с одним parent-агентом и несколькими child-агентами. Каждый child-агент собирает метрики своего сервера и отправляет их на parent-агент, который хранит эти данные и показывает состояние всей инфраструктуры в одном месте.
┌──────────────────────────┐
│ vps-01 │
│ Netdata parent │
│ alerts → Telegram │
└──────────▲───────────────┘
│
┌───────────────┴────────────────┐
│ │
stream collect metrics
│ │
┌───────────┼───────────┐ ┌─────────┴─────────┐
│ │ │ │ │
┌────▲────┐ │ ┌────▲────┐ ┌───▼──────────┐ ┌──────▼──────────┐
│ vps-02 │ ... │ vps-05 │ │ MySQL │ │ ClickHouse │
│ child │ │ child │ │ cluster │ │ cluster │
└─────────┘ └─────────┘ └──────────────┘ └─────────────────┘
На parent-сервере, где уже настроен доступ через Nginx с basic auth, в /etc/netdata/stream.conf настраиваем приём метрик от child-серверов. Для этого можно создать один общий стрим с одним API key или отдельные стримы для каждого child-сервера:
[788df748-08ef-4f6b-be56-78247dec3ac5]
enabled = yes
default history = 21600
[9edcf9b2-cb5b-4654-b5c0-78acacbad8cd]
enabled = yes
default history = 21600default history = 21600 - это размер локальной истории для child-метрик на parent-сервере (измеряется в entries: при update every = 1 получается примерно 6 часов). Долговременное хранение метрик на parent-сервере настраивается отдельно в файле /etc/netdata/netdata.conf в секции [db].
Один UUID (и по совместительству API key) можно использовать для нескольких child-агентов, а можно завести отдельный ключ для каждого child-сервера. Второй вариант удобнее, если для разных серверов нужны разные настройки: например, разное время хранения метрик.
На child-сервере нужно добавить настройки стриминга в /etc/netdata/stream.conf (дефолтный шаблон лежит в /usr/lib/netdata/conf.d/stream.conf: его можно скопировать и отредактировать):
[stream]
enabled = yes
destination = stats.gistrec.cloud:19999
api key = 788df748-08ef-4f6b-be56-78247dec3ac5После рестарта обоих агентов child начинает стримить метрики, и они появляются в дашборде parent. Уведомления я настраиваю только на parent: так все алерты приходят из одного места, а пороги можно править централизованно.
Сбор метрик с внешних сервисов
Parent-сервер может запускать collectors, которые подключаются к внешним managed-сервисам по сети и забирают метрики напрямую. Это отлично работает для MySQL, ClickHouse, Redis и т.д.
Например, для сбора метрик из моего managed-кластера ClickHouse я сделал вот такой конфиг collector’а (указал host, port и учётные данные):
jobs:
- name: clickhouse_projects
url: https://projects.clickhouse.gistrec.cloud:8443
username: ...
password: ...
Плюс Netdata из коробки умеет собирать метрики не только с внешних сервисов, но и с локальных: MySQL, PostgreSQL, Redis, ClickHouse, MongoDB, RabbitMQ, Elasticsearch, Nginx, HAProxy и десятки других. Метрики и базовые алерты — из коробки, без отдельного exporter-процесса.
Грабли, на которые важно не наступить:
- Порт
19999по умолчанию открыт. Все данные доступны без логина и пароля, поэтому порт точно не стоит открывать наружу. - Использовать все дефолтные алерты. Netdata из коробки включает много базовых проверок, но не все они одинаково важны для конкретной инфраструктуры. Я отключил сбор лишних метрик (пример в конфиге выше) и подобрал пороги так, чтобы уведомления не были шумными.
- Реагировать на каждый warning как на инцидент. Варнинг не значит, что что-то сломалось. Но это сигнал, что скоро что-то может сломаться. Поэтому мьютить варнинги всё-таки не стоит.
- Забить на регулярный просмотр дашбордов. Раз в день полезно открыть дашборд и быстро проверить основные метрики. Раз в неделю — посмотреть историю алертов и подкрутить пороги для всего, где было false-positive срабатывание.
Если у вас есть Linux-сервер, но нет понятного мониторинга, смело начинайте использовать Netdata! Часто уже за первые десять минут становится видно то, что раньше оставалось незаметным.