Мониторинг дисков и inode в Linux: развертывание Netdata + Grafana на базе Prometheus | AdminWiki

Мониторинг дисков и inode в Linux: развертывание Netdata + Grafana на базе Prometheus

24 июля 2026 12 мин. чтения

Зачем мониторить диски и inode в Linux

Заполненный до 100% корневой раздел или исчерпанный лимит inode останавливает сервисы мгновенно. Базы данных падают, веб-серверы перестают обрабатывать запросы, cron-задачи не выполняются. Восстановление занимает часы, если нет резервной копии конфигураций. Мониторинг дискового пространства и индексных дескрипторов - это страховка от таких аварий.

На практике администраторы сталкиваются с двумя типовыми сценариями. Первый: лог-файлы приложения заполняют весь доступный объем за несколько часов. Второй: проект с миллионами мелких файлов (почтовые серверы, файловые хранилища, кэши) исчерпывает лимит inode задолго до физического заполнения раздела. Команда df -h показывает свободное место, а df -i - 100% использования inode. Сервер отказывается создавать новые файлы при наличии свободных гигабайт.

Стек Netdata, Prometheus и Grafana решает обе проблемы. Netdata собирает детальные метрики по каждому разделу: занятое место, количество свободных inode, время ожидания ввода-вывода (iowait). Prometheus агрегирует эти данные в централизованное хранилище временных рядов. Grafana визуализирует тренды и строит прогноз заполнения на основе скользящего среднего. Добавьте Alertmanager с Telegram-интеграцией - и вы получите оповещение за несколько дней до того, как диск заполнится критически.

Этот материал - пошаговое руководство по развертыванию полного контура мониторинга дисков. Вы пройдете путь от установки Netdata-агента до создания кастомного дашборда с прогнозированием заполнения. Все конфигурации проверены на Ubuntu 24.04 LTS и CentOS Stream 10, актуальны на 2026 год.

Архитектура мониторинга: Netdata, Prometheus и Grafana

Система строится на трех компонентах с четким разделением ответственности. Netdata работает в режиме агента на каждом целевом сервере, собирает метрики дисков и экспортирует их в формате Prometheus. Prometheus по расписанию забирает данные с эндпоинтов Netdata и сохраняет в своей time-series базе. Grafana подключается к Prometheus как к источнику данных и отрисовывает дашборды. Alertmanager обрабатывает правила оповещений и отправляет уведомления в Telegram.

Схема взаимодействия: Netdata-агент (порт 19999) → Prometheus (скрапинг каждые 15 секунд) → Grafana (PromQL-запросы) + Alertmanager (webhook в Telegram Bot API). Такой подход вендор-агностичен: вы можете заменить Netdata на Node Exporter, Grafana на другое средство визуализации, а Alertmanager на скрипт-обработчик алертов. Prometheus остается центральным звеном, гарантируя совместимость компонентов.

Почему Netdata, а не Node Exporter

Node Exporter - стандартный экспортер Prometheus, который покрывает базовые метрики CPU, памяти, дисков и сети. Он легковесен и аскетичен. Netdata предлагает на порядок более глубокую детализацию дисковой подсистемы: метрики по каждому разделу и устройству, статистику inode, iowait в миллисекундах, количество операций чтения/записи, размер очереди запросов к диску. Эти данные критичны для диагностики узких мест ввода-вывода.

Сравним ключевые различия. Node Exporter отдает метрику node_filesystem_avail_bytes - свободное место в байтах. Netdata экспортирует netdata_disk_space_GiB_average с разбивкой по точкам монтирования и типам использования (свободно, занято, зарезервировано). Для inode Node Exporter предоставляет node_filesystem_files_free, Netdata - netdata_disk_inodes_average с тегами монтирования. По iowait Node Exporter ограничен общим процентом из /proc/stat, Netdata выдает временные ряды с точностью до миллисекунды на каждое блочное устройство.

Потребление ресурсов: Netdata в режиме агента без веб-интерфейса занимает 80-120 МБ RAM и 1-3% CPU на среднестатистическом сервере. Node Exporter - 20-40 МБ RAM и менее 1% CPU. Разница существенна для embedded-систем, но на типовом VPS с 2 ГБ памяти она некритична. Выбор зависит от приоритетов: минимальное потребление - Node Exporter, максимальная детализация дисковой статистики - Netdata. Для задач прогнозирования заполнения и анализа inode мы используем Netdata.

Если вы уже работаете с Node Exporter и хотите расширить мониторинг дисков, посмотрите руководство по мониторингу Linux-серверов с Node Exporter. Там разобраны метрики ZFS, импорт готовых дашбордов и настройка алертов.

Установка и настройка Netdata в режиме агента

Установка выполняется одним скриптом, который работает на всех основных дистрибутивах Linux. Подключаемся к целевому серверу по SSH и выполняем:

wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh
sh /tmp/netdata-kickstart.sh --stable-channel --disable-telemetry --non-interactive

Флаги важны: --stable-channel фиксирует стабильную ветку релизов, --disable-telemetry отключает отправку анонимной статистики разработчикам, --non-interactive подавляет интерактивные запросы в процессе установки. Через 2-3 минуты Netdata запущена и доступна на порту 19999.

Для работы в режиме агента отключаем встроенный веб-интерфейс и API, оставляя только экспорт метрик для Prometheus. Редактируем /etc/netdata/netdata.conf:

[web]
    mode = none
    bind to = 127.0.0.1

[health]
    enabled = no

Секция [web] с параметром mode = none полностью отключает HTTP-сервер Netdata. Привязка к localhost оставлена для локальной диагностики через curl. Секция [health] отключает встроенную систему алертов Netdata - мы будем использовать Alertmanager Prometheus.

Проверяем, что метрики экспортируются:

curl -s http://127.0.0.1:19999/api/v1/allmetrics?format=prometheus | head -50

Вывод должен содержать строки вида netdata_disk_space_GiB_average{...} и netdata_disk_inodes_average{...}. Если метрики отдаются, переходим к тонкой настройке сбора.

Настройка сбора метрик inode и iowait

Netdata по умолчанию собирает метрики дисков, но для детального контроля inode и iowait нужно проверить конфигурацию коллекторов. Файл /etc/netdata/netdata.conf дополняем секциями:

[plugin:proc:diskspace]
    enabled = yes
    update every = 15

[plugin:proc:/proc/diskstats]
    enabled = yes
    update every = 15

Коллектор diskspace отвечает за метрики занятого места и inode по точкам монтирования. Коллектор /proc/diskstats собирает статистику ввода-вывода, включая iowait, количество операций и размер очереди. Интервал обновления в 15 секунд - компромисс между оперативностью данных и нагрузкой на систему.

Для верификации выполняем прямой запрос к API Netdata и фильтруем вывод по интересующим метрикам:

# Проверка метрик inode
curl -s http://127.0.0.1:19999/api/v1/allmetrics?format=prometheus | grep -i inode

# Проверка метрик iowait
curl -s http://127.0.0.1:19999/api/v1/allmetrics?format=prometheus | grep -i iowait

# Проверка метрик дискового пространства
curl -s http://127.0.0.1:19999/api/v1/allmetrics?format=prometheus | grep disk_space

Каждая строка содержит название метрики, значение и набор labels: mount_point (точка монтирования), filesystem (тип ФС), device (блочное устройство). Эти labels понадобятся при построении PromQL-запросов в Grafana.

Интеграция Netdata с Prometheus

Prometheus должен знать, откуда забирать метрики Netdata. Предполагаем, что Prometheus уже установлен. Если нет - воспользуйтесь пошаговой инструкцией по развертыванию стека мониторинга с нуля, где описана установка Prometheus, node_exporter и Grafana за 1-2 часа.

В файл /etc/prometheus/prometheus.yml добавляем новую job для Netdata:

scrape_configs:
  - job_name: 'netdata'
    scrape_interval: 15s
    metrics_path: '/api/v1/allmetrics'
    params:
      format: ['prometheus']
    static_configs:
      - targets: ['192.168.1.10:19999', '192.168.1.11:19999']
        labels:
          environment: 'production'
          team: 'infrastructure'

Параметр metrics_path указывает на эндпоинт Netdata, который отдает метрики в формате Prometheus. scrape_interval: 15s синхронизирован с интервалом обновления Netdata - чаще собирать нет смысла. В targets перечисляем все серверы с Netdata-агентами. Дополнительные labels environment и team упростят фильтрацию в Grafana, если у вас несколько окружений.

После изменения конфигурации перезагружаем Prometheus:

systemctl reload prometheus

Проверяем, что таргеты появились и находятся в состоянии UP. Открываем веб-интерфейс Prometheus (по умолчанию порт 9090), переходим в Status → Targets. Для каждого сервера должна отображаться зеленая строка с временем последнего успешного скрапинга.

Фильтрация метрик дисков в Prometheus

Netdata экспортирует тысячи метрик: CPU, память, сеть, диски, системные вызовы. Хранить все - расточительно по дисковому пространству и замедляет выполнение запросов. Нам нужны только метрики дисковой подсистемы. Добавляем фильтрацию на уровне входящих данных через metric_relabel_configs:

scrape_configs:
  - job_name: 'netdata'
    scrape_interval: 15s
    metrics_path: '/api/v1/allmetrics'
    params:
      format: ['prometheus']
    metric_relabel_configs:
      - source_labels: [__name__]
        regex: 'netdata_disk_space_GiB_average|netdata_disk_inodes_average|netdata_disk_iowait_average|netdata_disk_utilization_average'
        action: keep
    static_configs:
      - targets: ['192.168.1.10:19999']

Директива action: keep оставляет только метрики, имена которых совпадают с регулярным выражением. Остальные отбрасываются на этапе приема данных, не попадая в хранилище. Список можно расширить под свои нужды: добавьте netdata_disk_read_MiB_average и netdata_disk_write_MiB_average для отслеживания пропускной способности.

Проверяем, что фильтрация работает. В интерфейсе Prometheus открываем Graph и вводим {job="netdata"}. Должны отобразиться только метрики, прошедшие через фильтр. Если видите лишние - скорректируйте регулярное выражение.

Создание дашборда в Grafana

Grafana подключается к Prometheus как к источнику данных. В разделе Configuration → Data Sources добавляем новый источник: тип Prometheus, URL http://localhost:9090. Если Prometheus на другом сервере - указываем его адрес. Жмем Save & Test, убеждаемся в успешном соединении.

Создаем новый дашборд: нажимаем «+» → Dashboard → Add new panel. Начинаем с панели свободного места на дисках.

Панель «Свободное место по разделам» - тип Table. Запрос PromQL:

netdata_disk_space_GiB_average{job="netdata", dimension="avail"}

Метрика возвращает доступное пространство в гигабайтах для каждой точки монтирования. В настройках панели выбираем формат Table, в колонках оставляем mount_point и Value. Добавляем цветовые пороги: зеленый > 20 ГБ, желтый 5-20 ГБ, красный < 5 ГБ. Панель готова.

Панель «Использование inode» - тип Graph. Запрос:

100 - (netdata_disk_inodes_average{job="netdata", dimension="avail"} / netdata_disk_inodes_average{job="netdata", dimension="total"} * 100)

Формула вычисляет процент использованных inode от общего количества. В легенде отображаем {{mount_point}}. Добавляем горизонтальную линию на уровне 80% - это порог, после которого риск исчерпания inode становится критическим.

Панель «iowait по устройствам» - тип Graph. Запрос:

netdata_disk_iowait_average{job="netdata"}

Метрика показывает процент времени, которое процессор тратит на ожидание завершения операций ввода-вывода. Значения выше 10-15% указывают на проблемы с дисковой подсистемой. Группируем по device, отображаем временной ряд за последние 6 часов.

Панель прогнозирования заполнения на основе скользящего среднего

Прогнозирование - ключевая фича дашборда. Мы используем функцию predict_linear, которая на основе линейной регрессии предсказывает, когда значение достигнет заданного порога. Для повышения точности применяем скользящее среднее за 1 час, чтобы сгладить краткосрочные всплески.

Создаем панель типа Stat. Запрос PromQL:

predict_linear(avg_over_time(netdata_disk_space_GiB_average{job="netdata", dimension="avail"}[1h]), 86400 * 7) < 0

Разберем выражение. avg_over_time(...[1h]) вычисляет скользящее среднее за час, устраняя шум. predict_linear(..., 86400 * 7) строит линейную регрессию и прогнозирует значение через 7 дней (86400 секунд в сутках × 7). Условие < 0 возвращает 1, если через неделю свободное место станет отрицательным - то есть диск заполнится.

Настройки панели: Value options → Show = Calculate, Calculation = Last. Thresholds: 0 - зеленый (прогноз благоприятный), 1 - красный (диск заполнится в течение 7 дней). Добавляем override для отображения понятного текста: значение 0 → «OK», значение 1 → «Заполнится через 7 дней».

Для более точного прогноза можно варьировать период скользящего среднего. Если данные имеют выраженный дневной паттерн (активная запись днем, простой ночью), используйте окно в 24 часа:

predict_linear(avg_over_time(netdata_disk_space_GiB_average{job="netdata", dimension="avail"}[24h]), 86400 * 7) < 0

Добавляем вторую панель - Graph с визуализацией тренда. Запрос:

netdata_disk_space_GiB_average{job="netdata", dimension="avail"}

В настройках панели включаем отображение прогноза: Add series override → поле «Predict» → значение «7 days». Grafana автоматически построит пунктирную линию прогноза на основе встроенной функции predict_linear. Это дает наглядную картину: исторические данные сплошной линией, прогноз - пунктиром.

Если вам нужен мониторинг дисковой подсистемы в контейнеризированных средах, обратитесь к руководству по мониторингу дисков в Docker и Kubernetes. Там разобрана связка cAdvisor, kube-state-metrics и Alertmanager для контроля Persistent Volumes.

Настройка оповещений в Telegram

Alertmanager принимает алерты от Prometheus, группирует их и маршрутизирует получателям. Нам нужна доставка в Telegram. Предполагаем, что Alertmanager установлен и базово настроен. Если нет - начните с инструкции по настройке стека мониторинга, где описан полный цикл от установки до Telegram-оповещений.

Создаем Telegram-бота через @BotFather. Получаем токен - строку вида 123456:ABC-DEF1234ghikl-zyx57W2v1u123ew11. Узнаем chat_id: добавляем бота в контакты, отправляем ему любое сообщение, затем выполняем запрос:

curl -s "https://api.telegram.org/bot<ТОКЕН>/getUpdates" | jq '.result[0].message.chat.id'

Полученный числовой идентификатор - это chat_id. Он понадобится в конфигурации Alertmanager.

Файл /etc/alertmanager/alertmanager.yml:

global:
  telegram_api_url: "https://api.telegram.org"

route:
  receiver: 'telegram-critical'
  group_by: ['alertname', 'instance']
  group_wait: 10s
  group_interval: 5m
  repeat_interval: 1h

receivers:
  - name: 'telegram-critical'
    telegram_configs:
      - bot_token: '123456:ABC-DEF1234ghikl-zyx57W2v1u123ew11'
        chat_id: 123456789
        parse_mode: 'HTML'
        message: |
          {{ .Status | toUpper }}: {{ .CommonAnnotations.summary }}
          Описание: {{ .CommonAnnotations.description }}
          Сервер: {{ .CommonLabels.instance }}
          Время: {{ .StartsAt.Format "15:04:05 02.01.2006" }}

Параметр group_by объединяет однотипные алерты в одно сообщение, чтобы не спамить в чат при массовом сбое. group_interval: 5m означает, что новые алерты в группе будут отправляться не чаще раза в 5 минут. repeat_interval: 1h задает периодичность повторной отправки, если алерт не снят.

Перезагружаем Alertmanager:

systemctl reload alertmanager

Примеры правил оповещений для дисков и inode

Правила алертов определяются в Prometheus. Файл /etc/prometheus/rules/disk_alerts.yml:

groups:
  - name: disk_alerts
    interval: 30s
    rules:
      - alert: DiskSpaceLow
        expr: netdata_disk_space_GiB_average{job="netdata", dimension="avail"} < 10
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Мало свободного места на {{ $labels.mount_point }}"
          description: "На сервере {{ $labels.instance }} раздел {{ $labels.mount_point }} имеет менее 10 ГБ свободного места. Текущее значение: {{ $value }} ГБ."

      - alert: DiskSpaceCritical
        expr: netdata_disk_space_GiB_average{job="netdata", dimension="avail"} < 5
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Критически мало места на {{ $labels.mount_point }}"
          description: "На сервере {{ $labels.instance }} раздел {{ $labels.mount_point }} имеет менее 5 ГБ свободного места. Текущее значение: {{ $value }} ГБ. Требуется немедленное вмешательство."

      - alert: InodeUsageHigh
        expr: (1 - netdata_disk_inodes_average{job="netdata", dimension="avail"} / netdata_disk_inodes_average{job="netdata", dimension="total"}) * 100 > 80
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Высокое использование inode на {{ $labels.mount_point }}"
          description: "На сервере {{ $labels.instance }} раздел {{ $labels.mount_point }} использовано более 80% inode. Текущее значение: {{ $value }}%. Проверьте количество мелких файлов."

      - alert: InodeUsageCritical
        expr: (1 - netdata_disk_inodes_average{job="netdata", dimension="avail"} / netdata_disk_inodes_average{job="netdata", dimension="total"}) * 100 > 95
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Критическое использование inode на {{ $labels.mount_point }}"
          description: "На сервере {{ $labels.instance }} раздел {{ $labels.mount_point }} использовано более 95% inode. Текущее значение: {{ $value }}%. Создание новых файлов скоро станет невозможным."

      - alert: DiskIowaitHigh
        expr: netdata_disk_iowait_average{job="netdata"} > 15
        for: 15m
        labels:
          severity: warning
        annotations:
          summary: "Высокий iowait на {{ $labels.device }}"
          description: "На сервере {{ $labels.instance }} устройство {{ $labels.device }} показывает iowait {{ $value }}% в течение 15 минут. Возможны проблемы с дисковой подсистемой."

Директива for задает время, в течение которого условие должно выполняться непрерывно, прежде чем алерт будет отправлен. Это фильтрует кратковременные всплески. Для критических алертов (свободное место < 5 ГБ) задержка минимальна - 1 минута. Для предупреждений - 5-15 минут.

Подключаем файл правил в prometheus.yml:

rule_files:
  - '/etc/prometheus/rules/disk_alerts.yml'

Перезагружаем Prometheus и проверяем, что правила загрузились: интерфейс Prometheus → Status → Rules. Все правила должны отображаться без ошибок.

Тестируем Telegram-оповещение. Временно снижаем порог в правиле DiskSpaceLow до заведомо высокого значения, например < 1000. Ждем 5 минут. В Telegram-чат должно прийти сообщение с информацией о сервере, разделе и текущем свободном месте. После проверки возвращаем порог обратно.

Заключение и дальнейшие шаги

Развернута система мониторинга дискового пространства и inode: Netdata собирает детальные метрики с каждого сервера, Prometheus агрегирует и хранит их, Grafana визуализирует тренды и прогнозирует заполнение на неделю вперед, Alertmanager отправляет оповещения в Telegram при достижении критических порогов. Вы получаете упреждающую информацию о проблемах с дисками, а не констатацию факта после аварии.

Дальнейшие шаги для расширения мониторинга:

  • Добавьте метрики CPU, памяти и сети - Netdata собирает их из коробки, достаточно убрать фильтрацию в Prometheus и создать дополнительные панели в Grafana.
  • Используйте Grafana Alerting вместо Alertmanager, если хотите управлять алертами через веб-интерфейс Grafana без правки YAML-файлов.
  • Настройте дополнительные каналы оповещений: Slack, email, PagerDuty - Alertmanager поддерживает их нативно.
  • Интегрируйте мониторинг дисков в общий дашборд инфраструктуры. Для кластерных сред обратитесь к руководству по мониторингу кластеров, где разобраны специфичные метрики Pacemaker и Ceph.
  • Настройте резервное копирование конфигураций Grafana (дашборды, источники данных) через экспорт JSON-моделей в систему контроля версий.

Для быстрого старта с облачной инфраструктурой рассмотрите Timeweb Cloud - облачные серверы с предустановленными шаблонами мониторинга, которые сокращают время развертывания с часов до минут.

Поделиться:
Сохранить гайд? В закладки браузера