Я держу небольшой парк Linux-серверов — bare metal, VPS, пара container-хостов — на которых тихо живут pet-проекты и пара платных продуктов. Ничего экзотичного, но реальные клиенты зависят от того, что всё работает.
Прод почти никогда не падает разом. Обычно он деградирует: сервис начинает свопиться под нагрузкой, память тихо подтекает по нескольку мегабайт в час, шумный сосед на общем диске превращает 5 мс чтение в 500. К моменту, когда алерт «сайт лежит» пришёл, вы уже не разбираете пожар — вы объясняете его клиентам.
Я держу Netdata на этих серверах несколько лет, и не один раз она ловила «медленное горение» до того, как оно становилось настоящим инцидентом. Эта статья — как я её использую: установка, дефолты, которые я меняю, parent–child для масштаба и три продакшен-истории, в которых Netdata спасла меня от простоя.
Что мы хотим от мониторинга
До инструмента — про цели. Мониторинг — это не красивые дашборды, это быстрые ответы на три вопроса:
- Что изменилось? Когда сервер начал чудить в 02:14, что было иначе в 02:13?
- Где узкое место? CPU, RAM, swap, диск, сеть, дескрипторы, конкретный процесс?
- Как узнать раньше пользователей? На каком пороге нас должны были разбудить за 20 минут до факапа?
Конкретно, мне нужны метрики на:
- CPU по ядрам, отдельно system / user / iowait.
- Давление на память, swap-in / swap-out.
- Диск: throughput, IOPS, длина очереди, ошибки.
- Сеть: throughput, retransmits, packet drops.
- Здоровье сервисов: nginx, Postgres, MySQL, Redis, Docker, systemd-юниты.
- Алерты, которые реально будят, — а не 200 дашбордов, в которые я не захожу.
Почему именно Netdata
Есть хорошие причины выбрать Prometheus + Grafana — длинная ретенция, язык запросов, экосистема экспортёров. Я выбираю Netdata из-за другого набора компромиссов:
- Установка одной командой.
kickstart.sh— и через минуту агент уже собирает сотни метрик с разумными дефолтами, включёнными из коробки. - Маленький footprint. Типичный агент — меньше 2% CPU и 50–100 МБ RAM. Не нужно выделять серверы под мониторинг.
- Per-second разрешение, в реальном времени. Большинство стеков агрегируют по 10–30 секундам. С 1-секундным разрешением 4-секундный спайк — это видимая засечка, а не призрак.
- Auto-discovery. Поставил nginx, перезапустил Netdata — есть графики nginx. То же для Postgres, Redis, Docker, systemd. Никаких scrape config писать не надо.
- Health-алерты из коробки. Сотни преднастроенных alarm’ов (swap, заполнение диска, ramping load) приезжают включёнными. Стартуете с разумных дефолтов, тюните дальше.
Я воспринимаю Netdata как day-1 инструмент: 80% видимости за 5% усилий. Если со временем понадобится длинная ретенция, custom-запросы или экзотические SLO — Netdata можно дополнить или заменить. Но начинать не оттуда.
Когда Netdata поймала то, что стало бы инцидентом
Три конкретные истории. Ни одна не показалась бы на «healthcheck сервиса доступен» — к моменту, когда тот переключится в красное, клиенты уже пишут.
Тихий swap-storm
Симптомы. Бэкенд API утром начал отдавать случайные 500-е. Latency-дашборд показывал повышенный p95 без явной причины. CPU — «нормально». Первый инстинкт команды — «перезапустить и посмотреть».
Что показала Netdata. На графике mem.swapio последние 36 часов тихо рос swap-out. Свободная память — около нуля. Ядро thrash’ило — CPU был «нормально», потому что просто ждал диск, а не делал ничего полезного.
Решение. Предыдущий конфиг-rollout увеличил pool size в 5 раз, headroom’а под него на сервере уже не было, и любая мелкая аллокация утекала в swap. Откатили конфиг. Добавили алерт на system.ram available_percent < 15 и второй на mem.swapio out > 1MB/s в течение 5 минут. Теперь такая memory creep будит нас за сутки до того, как пользователи заметят.
Утечка памяти, которая копилась неделю
Симптомы. Python-воркер дрейфовал с ~400 МБ до ~3.5 ГБ за шесть дней. Без падений — на сервере было место, — но каждый деплой с рестартом ресетил утечку и маскировал её от любого мониторинга, который смотрит только на текущее значение RAM.
Что показала Netdata. График apps.mem для этого процесса — красивая линейная рампа. Рестарты на нём — чёткие падения, шесть штук за неделю. Как только паттерн стал виден, причина (кэш без eviction policy) — 30 минут с tracemalloc.
Решение. Ограничили кэш, добавили алерт на apps.mem, если воркер превысит 1 ГБ, повторили охоту на утечки с алертом как safety net. Без истории по памяти на процесс, переживающей рестарты, утечка крутилась бы до тех пор, пока OOM killer не сделал бы её всеобщей.
Шумный сосед на общем диске
Симптомы. Postgres на VPS начал тормозить в произвольные моменты. EXPLAIN — нормально. Коннекшены — нормально. CPU — нормально.
Что показала Netdata. disk.iops и disk.await скакали вместе, при этом наш собственный disk.io в МБ/с был скромным — то есть это не мы делаем эти IOPS. Хост был shared, и сосед стал шумным.
Решение. Переехали с Postgres на хост с выделенным NVMe. Добавили алерт disk.await > 50ms в течение 5 минут, чтобы в следующий раз, когда сосед проснётся, мы знали об этом за минуты, а не за часы клиентских жалоб.
Быстрый старт: от нуля до полезных графиков за 10 минут
Если вы прямо сейчас пробуете на одном сервере, вот мой путь.
1. Установить агент. Официальный kickstart-скрипт сам определит дистрибутив, проверит подписи и пропишет systemd.
# установка одной строкой (Linux)
wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh
sh /tmp/netdata-kickstart.sh --stable-channel --disable-telemetry2. Закрыть дашборд. Дефолтный порт 19999 ни в коем случае не должен смотреть в интернет. Биндим на localhost и заходим через SSH-туннель.
[web]
bind to = 127.0.0.1Дальше с ноутбука:
ssh -L 19999:localhost:19999 user@your-host
# открыть http://localhost:19999 в браузере3. Тюнинг алертов, которые важны. Дефолты разумные, но шумные. Те, что я всегда правлю в первый день:
system.ram— процент свободной памяти.mem.swapio— постоянный swap-out.disk.space— и rate заполнения, и абсолютные %.disk.await— задержки на чтение/запись.- Postgres / MySQL / Redis connection saturation, если что-то из этого есть.
Файлы лежат в /etc/netdata/health.d/. Перезагрузка — netdatacli reload-health, без рестарта.
4. Подключить нотификации. Правим /etc/netdata/health_alarm_notify.conf и выбираем канал. Telegram самый лёгкий: bot token + chat ID, и всё. Slack работает похоже — webhook URL.
Pro tip. Выключайте десятки графиков, которые вам не нужны. Netdata с радостью нарисует температуру каждого NVMe-сенсора — смотреть на это всё необязательно. Глушите агрессивно — дашборд, на котором ничего лишнего, заслуживает больше доверия.
Масштаб: parent–child для парка серверов
На одном хосте Netdata-агент и собирает, и хранит метрики. Когда у тебя больше горсти нод, не хочется логиниться на каждую, чтобы посмотреть графики, и хочется хранить дольше, чем влезает на одну ноду.
Модель parent–child решает обе проблемы:
- Children запускают облегчённого агента, который собирает метрики и стримит их на parent.
- Parents принимают потоки от множества children и хранят их централизованно столько, сколько нужно.
Топология, которая хорошо заходит для маленького парка: app/web/db ноды как children, один parent на отдельной VM с щедрым SSD. Алерты крутятся на parent, children только собирают.
┌──────────────────────┐
│ parent-monitor │
│ 30d retention │
│ alerts → telegram │
└──────────▲───────────┘
│ stream
┌────────────────────┼────────────────────┐
│ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│ web-01 │ │ db-01 │ … │ bg-01 │
│ child │ │ child │ │ child │
└─────────┘ └─────────┘ └─────────┘
children: только сбор · 1ч локального кэша
Настройки, которые трогаю:
/etc/netdata/stream.confна каждом child: API key + URL parent’а.- Тот же файл на parent’е: список разрешённых children с тем же API key.
- Секция
[db]вnetdata.confна parent’е: подкручиваю multi-tier retention — несколько недель в высоком разрешении, несколько месяцев в downsampled tier’ах. - Все алерты — на parent, чтобы тюнить в одном месте.
Когда parent–child не нужен: одна нода или маленький кластер, где встроенного дашборда на каждом агенте хватает. Цена не запредельная, но и не нулевая, и parent — это ещё одна штука, за которой надо следить.
Практические best practices
Что я вынес из эксплуатации этого в небольшом масштабе:
- Тюньте под сигнал, а не покрытие. Дефолтная Netdata показывает много. Глушите графики, в которые не смотрите. Будет больше доверия к дашборду, и вы быстрее заметите аномалию.
- Ежедневный взгляд, недельный обзор. Каждый день: открыть parent, прошерстить RAM/swap/disk-await/error-rate на топ-хостах. Раз в неделю: пройтись по истории алертов и поправить пороги для всего, что бузило, но не должно было.
- Покажите не-инженерам человеческий вид. Полный дашборд страшный. Кастомная страница «API latency, error rate, queue depth» гораздо полезнее продакту, чем стена терминологии ядра.
Анти-паттерны, которые кусают сильнее всего:
- Открыть порт 19999 наружу. Не надо.
- Оставить все дефолтные алерты в Slack, пока не замьютите канал.
- Реагировать на каждый жёлтый. Жёлтый существует, чтобы на него посмотрели, не чтобы по нему будили.
- Забыть, что parent теперь — single point of failure для видимости. Бэкапьте его конфиг; рассмотрите второй parent, если uptime самого мониторинга — требование.
Где Netdata вписывается в observability
Netdata — это слой метрик и реалтайм-алертов. Это не система логов, и это не tracing. Модель, которую я использую:
- Netdata — метрики хоста и сервисов, реалтайм, алерты.
- Логи — в централизованном хранилище (Loki, ELK или managed solution) для разборов постфактум.
- Tracing — только когда есть многосервисный граф запросов, который этого требует. Для маленького парка достаточно структурированных логов плюс Netdata.
Маршрутизация алертов — скучная намеренно: Netdata → Telegram мне, Slack команде. Не оверинженирьте alert pipeline до того, как поняли, какие алерты реально важны.
Заключение
Три года эксплуатации Netdata на проде превратили примерно столько же инцидентов в minor merge requests вместо реальных простоев. Цена — одна команда установки, конфиг с bind to 127.0.0.1, час на тюнинг алертов и дисциплина глушить графики, в которые не смотришь.
Если у вас Linux в проде и нет мониторинга, которому вы доверяете, — поставьте Netdata сегодня на один сервер. Биндитесь на localhost, заходите через туннель, посмотрите графики десять минут. Найдёте как минимум одну вещь, о которой не знали.