Мониторинг без системных метрик похож на приборную панель без спидометра: служебные графики самого стека наблюдения рисуют его собственное здоровье, а вот что происходит в машине - вопрос без ответа. Node Exporter закрывает эту дыру: крошечный агент читает внутренности операционной системы и отдаёт их в формате Prometheus, из которого собираются дашборды процессора, памяти, дисков, сети и даже температуры железа. Ниже установка по шагам, разбор ключевых метрик с формулами, температура с сенсоров и лечение типичных пустых графиков.

Node Exporter как агент метрик самой операционной системы

Node Exporter - самый популярный экспортёр экосистемы, и работа у него честная: он читает файлы виртуальной файловой системы - proc-и sysfs-каталоги ядра - и перепаковывает их в текстовые метрики по запросу. Никакой своей логики анализа, никакого хранения, никакой отправки: спросили - ответил, и это делает его одновременно простым и надёжным, как датчик уровня топлива.

Ресурсный профиль агента скромный: десяток-другой мегабайт памяти и незаметная доля процессора. Работает от отдельного служебного пользователя без прав администратора, слушает один порт и не пишет на диск вовсе. На фоне сервера его присутствие не видно ни в топе процессов, ни в графиках, кроме одного - собственной метрики готовности.

Пара с сервером Prometheus выглядит так: экспортёр на каждой машине, сборщик ходит по их портам, Grafana рисует. Один и тот же агент живёт на рабочем столе, в контейнере рядом с приложениями и на боевом сервере, и графики везде одинаковые - сравнение машин не требует привыкания.

Числа в его метриках знакомы по top и htop: те же нагрузки и режимы, но собранные в ряды за годы, а не в момент. Отдельно стоит проговорить границы: Node Exporter показывает саму операционную систему. Метрики приложений - базы, веб-серверы, очереди - живут в собственных экспортёрах, и полная картина сервера собирается из обоих слоёв. Системный слой - фундамент, и с него наблюдение начинается.

Установка из официального бинарника и юнит systemd

В системных репозиториях Ubuntu экспортёра нет, и ставится он из официальных сборок проекта - один бинарный файл без зависимостей. На момент написания актуальная версия - 1.12.1, и адрес загрузки собирается из имени выпуска и архитектуры: для arm64 меняется только суффикс архива, остальное не различается.

wget https://github.com/prometheus/node_exporter/releases/download/v1.12.1/node_exporter-1.12.1.linux-amd64.tar.gz
tar xzf node_exporter-1.12.1.linux-amd64.tar.gz
sudo cp node_exporter-1.12.1.linux-amd64/node_exporter /usr/local/bin/

Служебный пользователь заводится одной строкой - без домашнего каталога и оболочки.

sudo useradd -r --no-create-home --shell /usr/sbin/nologin node_exporter

Юнит systemd живёт в привычном каталоге и умещается в десять строк.

[Unit]
Description=Node Exporter
After=network-online.target

[Service]
User=node_exporter
ExecStart=/usr/local/bin/node_exporter
Restart=on-failure

[Install]
WantedBy=multi-user.target

Включение - три команды, знакомые по любой службе.

sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
systemctl status node_exporter

Зелёный статус означает, что агент поднялся и слушает. Обновление до новой версии делается той же последовательностью с заменой бинарника: остановить, скопировать, запустить, и конфигурация не меняется между минорными выпусками.

Открытие порта 9100 и проверка отдачи метрик

Порт у экспортёра один - 9100, и открывать его наружу не нужно: сборщик метрик в типовой схеме живёт на той же машине или в той же закрытой сети. Правило firewall разрешает порт только для адреса сборщика, а лучшая схема - вообще не открывать: localhost для локального Prometheus закрывает вопрос целиком. Если firewall ведётся списками правил, строка для порта пишется под конкретный адрес сборщика и ни для кого больше.

Проверка отдачи делается curl-ом за секунду.

curl -s localhost:9100/metrics | head -10

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

Отдельная проверка конкретной метрики делается grep-ом по ответу.

curl -s localhost:9100/metrics | grep node_load1

Строка с числом означает, что метрика жива и готова к рисованию. Полезная пара команд для живой диагностики: рестарт службы и проверка порта слушателем. Порт 9100 в выводе ss принадлежит экспортёру - простое подтверждение, что ничего не перехватило и не заняло.

sudo systemctl restart node_exporter
sudo ss -ltnp | grep 9100

Ключевые метрики процессора, памяти, дисков и сети с расшифровкой

Десятки рядов в ответе экспортёра на первый взгляд пугают, но на практике графиками становятся пять групп, и у каждой своя формула здоровья.

Процессор - самый хитрый ряд: node_cpu_seconds_total это счётчик времени по режимам, и прямым текстом он не читается. Загрузка в процентах получается из скорости счётчика в режиме простоя.

100 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100

Формула читается как предложение: сто минус средний простой за пять минут - и есть занятость. Гибкость в том, что режимы - подписи: idle, user, system, iowait - и каждый рисуется отдельно, показывая, куда именно уходит время. Особое внимание заслуживают два экзотических режима: iowait считает ожидание диска, а steal на виртуальных серверах - время, украденное соседями по гипервизору, и полка steal на графике говорит о площадке больше, чем о собственной машине.

Память короче: два датчика, node_memory_MemAvailable_bytes и node_memory_MemTotal_bytes, и их отношение в процентах - рабочий график.

node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100

Диски живут рядом с подписями точек монтирования: node_filesystem_avail_bytes с подписью mountpoint рисует свободное место по каждому разделу, и отдельная подпись device отделяет одно устройство от другого. График по корневой точке монтирования - главный на любом дашборде.

Сеть - снова счётчики: node_network_receive_bytes_total и передающий сосед растут постоянно, и скорость из них достаётся той же rate. Пятиминутное окно сглаживает всплески, а подпись с именем интерфейса разделяет трафик по карточкам.

Диски заслуживают второй метрики: node_disk_io_time_seconds_total показывает занятость устройства, и её скорость - готовый график нагрузки на диск.

rate(node_disk_io_time_seconds_total{device="sda"}[5m])

Единица на графике означает непрерывную работу устройства, и длительные полки - сигнал, что диск стал узким местом.

rate(node_network_receive_bytes_total{device="eth0"}[5m])

Замыкает пятёрку классика top: node_load1, node_load5 и node_load15 - усреднённая загрузка системы за минуты, и на неё удобно смотреть как на пульс: мгновенный скачок ничего не значит, длинный - значит всё.

Температура сенсоров и дополнительные коллекторы

Температура - метрика, за которую любят Node Exporter на машинах с физическим железом. Ряд называется node_hwmon_temp_celsius и появляется из подсистемы ядра hwmon, а вот наполнение этой подсистемы - отдельная история.

На виртуальной машине сенсоров нет, и это честно: гипервизор не отдаёт гостю термометры. На физике модули ядра для сенсоров процессора и дисков грузятся стандартными средствами, после чего сенсоры появляются и в утилите, и в метриках экспортёра. На физике же сенсоры появляются после загрузки модулей ядра: модуль процессорных датчиков у Intel, свой у AMD, отдельный для дисков. Утилита из пакета lm-sensors показывает, что система вообще знает о сенсорах, и её вывод подсказывает, какой модуль не загружен.

sudo apt install lm-sensors
sudo sensors

После появления сенсоров в системе метрика подхватывается сама: коллектор hwmon включён по умолчанию и читает всё, что нашлось. График температуры рисуется запросом с подписью сенсора, и здоровая машина держит ровные ступеньки с шагами под нагрузкой - внезапный пологий рост без причины заслуживает взгляда на кулеры и пыль.

Кроме системных метрик у экспортёра есть включаемые дополнения. Коллектор systemd по умолчанию выключен и включается флагом, после чего в метриках появляются состояния юнитов.

ExecStart=/usr/local/bin/node_exporter --collector.systemd

Ряд node_systemd_unit_state с подписью имени службы рисует живость каждого юнита, и падение службы видно на графике раньше, чем приходит алерт. Флаги включения перечислены в справке утилиты.

/usr/local/bin/node_exporter --help

Справка же показывает список коллекторов с их состояниями, и половина вопросов про отсутствующие метрики читается прямо из неё.

Подключение к Prometheus и готовый дашборд в Grafana

Цель для сборщика описывалась в настройке Prometheus из предыдущего разбора: задание node с портом 9100. После того как она стала зелёной, метрики системы текут в хранилище, и в Grafana остаётся собрать или взять готовую визуализацию.

Знаменитый дашборд Node Exporter Full существует в публичной библиотеке Grafana годами и импортируется по номеру 1860: десятки панелей от процессора до температуры, аккуратные ряды и переменные для выбора инстанса. После импорта выбирается источник метрик, и панели наполняются живыми графиками - десятки ручных панелей пишутся только тем, кому интересно само ремесло.

Скромная альтернатива полному дашборду - свой экран из пяти формул выше: процессор, память, корневой диск, сеть и загрузка. Пять панелей закрывают ежедневный осмотр, и лента начинается с них, а полный дашборд открывается, когда нужно глубже.

Дальше подключается второй и третий сервер: экспортёр на каждой машине, строка в списке целей, выбор инстанса в переменной дашборда. Первые графики наполняются сразу - история копится с момента подключения, и через сутки экран обретает суточные волны, по которым видно норму каждой машины. Сравнение машин на одном экране - момент, когда мониторинг перестаёт быть проектом и становится привычкой.

Типичные проблемы от пустых графиков до молчащих сенсоров

Здоровье экспортёра сводится к четырём проверкам:

  1. Служба активна и порт 9100 отвечает текстом метрик;
  2. Цель в Prometheus зелёная и возраст метрик свежий;
  3. Ключевые графики наполняются и реагируют на нагрузку;
  4. Сенсоры температуры видны на машинах с физическим железом.

Пустой график лечится чтением подписей: формула с точкой монтирования не покажет ничего, если подпись называется иначе, и самый быстрый способ свериться - посмотреть реальные подписи в ответе экспортёра. Молчащие сенсоры на виртуалке - не поломка, а свойство площадки. Высокая загрузка на внешне пустом сервере почти всегда оборачивается iowait-ом: режим простоя из-за ожидания диска рисуется отдельной подписью, и после этого загадочный load обретает объяснение.

Разрыв в графике после перезагрузки машины - норма: экспортёр стартует вместе с системой, и дыра длиной в минуту не должна никого тревожить. Реже встречается конфликт портов: вторая копия экспортёра или соседний сервис занимает 9100, и ss по порту отвечает владельцем. Ещё реже - устаревший юнит после обновления бинарника, и лечится перечитыванием конфигурации systemd.

По сути, Node Exporter - это глаза Prometheus на саму операционную систему: маленький агент, вечный юнит, пять формул для главных графиков и один номер дашборда для всего остального. Ставится за десять минут, живёт годами, и каждая новая машина подключается к наблюдению одной строкой в списке целей. Ровно так и растут парки наблюдения: не проектами, а строками. А когда машин станет больше десятка, тем же манером подключается отдельный экспортёр для чёрных ящиков вроде источников бесперебойного питания с SNMP, и картинка остаётся единой.