Про диски обычно вспоминают в момент, когда Grafana начинает мигать красным: «место заканчивается», «диск вырос/уменьшился», «на одном сервере нормально, на другом — странные цифры». И часто проблема не в железе и не в файловой системе, а в том, что именно Node Exporter считает «файловой системой» и какие точки монтирования отдаёт в метрики.
В этой заметке разберём три источника «кривых» размеров и дублей:
- overlayfs (Docker overlay2, containerd) и расхождения
dfvs метрики; - bind mount и задвоение одной ФС в Prometheus/Grafana;
- LVM, включая thin pool, где «размер» бывает логическим и физическим.
В конце будет практичная PromQL-шпаргалка и чек-лист, чтобы дашборды перестали шуметь и начали отражать реальный риск.
Как Node Exporter «видит» диски: это не диски, а mountpoints
Node Exporter отдаёт дисковые метрики коллектором filesystem. Ключевые метрики:
node_filesystem_size_bytes— общий размер файловой системы;node_filesystem_avail_bytes— доступно непривилегированному пользователю;node_filesystem_free_bytes— свободно всего (включая reserved blocks на ext*);node_filesystem_filesиnode_filesystem_files_free— иноды.
Важно: в метриках речь про файловые системы и точки монтирования, а не про «диски» как устройства. Поэтому:
- одна и та же «физика» может встречаться несколько раз (bind mount);
- контейнерные overlay-слои могут выглядеть как отдельные ФС;
- псевдо-ФС (tmpfs, proc, sysfs) тоже могут попасть в выдачу, если их не исключать.
Быстрая диагностика на хосте: фиксируем «истину»
Перед правками в Prometheus/Grafana сначала сверяемся с тем, что реально смонтировано:
df -hT
findmnt -rno TARGET,SOURCE,FSTYPE,OPTIONS
lsblk -f
Дальше простой принцип:
- если расхождение уже в
df— разбираем storage-слой (overlay/LVM/монтирование); - если
df«правильный», а Grafana «врет» — почти всегда вы суммируете не те mountpoints или не фильтруете мусор. - overlayfs — это слой поверх базовой ФС, а для процессов контейнера он выглядит как «своя» файловая система;
- runtime (Docker overlay2, containerd) создаёт overlay mountpoints на хосте;
- Node Exporter по умолчанию честно собирает метрики со всех mountpoints, до которых дотягивается.
Overlayfs: почему появляется «wrong disk size» на контейнерных хостах
Самый частый кейс сегодня — хосты с контейнерами. В Prometheus внезапно появляются десятки или сотни файловых систем с fstype="overlay", и размеры/свободное место «скачут» или выглядят как дубли.
Почему так происходит:
Если строить «использование диска сервера» суммой по всем mountpoints, overlayfs почти гарантированно даст завышение и дубли.
Как быстро убедиться, что виноват overlay
Проверьте наличие overlay в метриках:
node_filesystem_size_bytes{fstype="overlay"}
node_filesystem_avail_bytes{fstype="overlay"}
И сопоставьте с реальными монтированиями на хосте:
findmnt -t overlay
Быстрое решение: фильтрация overlay в PromQL
Если ваша задача — показать «диск хоста» (а не контейнерные слои), обычно overlay исключают:
node_filesystem_size_bytes{job="node",fstype!="overlay"} - node_filesystem_avail_bytes{job="node",fstype!="overlay"}
Процент использования:
100 * (1 - (node_filesystem_avail_bytes{job="node",fstype!="overlay"} / node_filesystem_size_bytes{job="node",fstype!="overlay"}))
Но одного fstype!="overlay" часто недостаточно: кроме overlay есть tmpfs, squashfs, nsfs и системные mountpoints, которые тоже ломают «итоги» и топы.

Bind mount: почему одна файловая система задваивается в Grafana
Bind mount — нормальная практика: смонтировать /srv/data в /var/www/data, подложить каталог в chroot, «пробросить» директорию в другой путь. Но для метрик это ловушка: один и тот же источник виден под разными mountpoint. Если вы где-то делаете «итого по серверу» через sum() по mountpoints — получите задвоение.
Диагностика bind mount на сервере
Посмотрите, где одинаковый SOURCE встречается несколько раз:
findmnt -rno TARGET,SOURCE,FSTYPE | sort -k2,2
Если для одного SOURCE есть несколько TARGET — это и есть причина «почему сумма не сходится».
Как не задваивать в Prometheus/Grafana
Правило простое: «итог по серверу» почти никогда нельзя получать суммой всех node_filesystem_* без фильтра.
- Для панелей «по разделам» показывайте ряды по
mountpoint, но исключайте заведомо вторичные bind-точки. - Для панелей «итого» выбирайте один целевой mountpoint:
/или ваш отдельный data-раздел.
Например, «сколько доступно на разделе, куда пишутся бэкапы»:
node_filesystem_avail_bytes{job="node",mountpoint="/srv"}
Если вы как раз планируете переносить проекты на отдельный сервер и хотите контролировать диски без сюрпризов, удобнее делать это на VDS: там проще закрепить предсказуемую разметку и избежать контейнерных «слоёв» на системном разделе.
Игнорирование mountpoints на стороне Node Exporter: фильтруем мусор у источника
Фильтрация в PromQL полезна, но иногда правильнее отрезать шум прямо в Node Exporter — чтобы «мусорные» ФС не попадали ни в алерты, ни в дашборды, ни в recording rules.
В Node Exporter (в зависимости от версии) встречаются флаги семейства:
--collector.filesystem.mount-points-exclude(актуальный вариант);--collector.filesystem.ignored-mount-points(часто в старых примерах);- в статьях это нередко называют
node_filesystem_ignore_mount_pointsкак «понятное имя», но оно не обязательно совпадает с реальным флагом вашей версии.
Проверьте доступные флаги:
node_exporter --help | grep -E "filesystem.*mount"
Пример исключения типовых системных путей (адаптируйте под себя):
--collector.filesystem.mount-points-exclude=^/(dev|proc|sys|run)($|/)
Не исключайте контейнерные директории «вслепую». Если место заканчивается в
/var/lib/dockerили/var/lib/containerd, мониторить нужно файловую систему, на которой они лежат, а не overlay-монты.
LVM и «не тот размер»: thin pool, логический объём и физические лимиты
С LVM путаница другого типа: Node Exporter показывает размер файловой системы (ext4/xfs) на mountpoint’е, а LVM добавляет уровни абстракции (PV/VG/LV) и, в случае thin, виртуализацию пространства.
Типовые сценарии:
- LV расширили, а файловую систему внутри не растянули — в Grafana «диск не вырос» (потому что
node_filesystem_size_bytesсмотрит на ФС, а не на LV). - thin pool: внутри thin LV файловая система может показывать «места ещё много», но физически забивается thin pool — запись внезапно останавливается.
Проверка размеров и заполнения LVM
lvs -a -o +devices,lv_size,data_percent,metadata_percent
vgs -o +vg_free,vg_size
pvs -o +pv_used
Для thin pool критичны data_percent и metadata_percent: проблемы с метаданными могут проявляться резко, даже если data ещё не 100%.
Почему Node Exporter не спасёт thin pool «из коробки»
При thin provisioning node_filesystem_avail_bytes отражает логическое свободное место внутри ФС, но физический лимит задаётся заполнением thin pool. Поэтому для thin почти всегда нужен отдельный мониторинг заполнения pool.
Метрики thin pool через textfile collector (без сторонних экспортеров)
Если у вас включён textfile collector, можно писать метрики в файл в каталоге, заданном флагом --collector.textfile.directory.
Ниже пример скрипта, который выгружает data_percent и metadata_percent для thin pool LV. Обратите внимание: в командах нет переносов строк обратным слэшем.
cat > /usr/local/sbin/lvm-thin-metrics.sh <<'EOF'
#!/bin/sh
OUT=/var/lib/node_exporter/textfile_collector/lvm_thin.prom
TMP=$(mktemp)
lvs --noheadings --separator ';' -o lv_name,vg_name,lv_attr,data_percent,metadata_percent 2>/dev/null | awk -F';' '
{
gsub(/^ +| +$/, "", $1);
gsub(/^ +| +$/, "", $2);
gsub(/^ +| +$/, "", $3);
gsub(/^ +| +$/, "", $4);
gsub(/^ +| +$/, "", $5);
if ($3 ~ /t/) {
printf "lvm_thin_data_percent{vg=\"%s\",lv=\"%s\"} %s\n", $2, $1, ($4==""?0:$4);
printf "lvm_thin_metadata_percent{vg=\"%s\",lv=\"%s\"} %s\n", $2, $1, ($5==""?0:$5);
}
}' > "$TMP"
mv "$TMP" "$OUT"
EOF
chmod +x /usr/local/sbin/lvm-thin-metrics.sh
Запуск — через cron или systemd timer. После этого в Prometheus появятся lvm_thin_data_percent и lvm_thin_metadata_percent, и можно заводить алерты именно по ним.

PromQL-шпаргалка для Grafana: чтобы панели не врали
Процент использования по каждому mountpoint (с фильтрацией мусора)
100 * (1 - (
node_filesystem_avail_bytes{job="node",fstype!~"tmpfs|overlay|squashfs|nsfs|cgroup2",mountpoint!~"^/(run|proc|sys|dev)($|/)"}
/
node_filesystem_size_bytes{job="node",fstype!~"tmpfs|overlay|squashfs|nsfs|cgroup2",mountpoint!~"^/(run|proc|sys|dev)($|/)"}
))
Используйте как Time series или Table. Если у вас специфичные пути (kubelet, snap, custom runtime) — расширяйте фильтр по mountpoint.
Свободно в GiB на конкретном разделе (удобно для алертов)
node_filesystem_avail_bytes{job="node",mountpoint="/"} / 1024 / 1024 / 1024
Топ-10 самых «забитых» файловых систем
topk(10,
100 * (1 - (
node_filesystem_avail_bytes{job="node",fstype!~"tmpfs|overlay|squashfs|nsfs|cgroup2",mountpoint!~"^/(run|proc|sys|dev)($|/)"}
/
node_filesystem_size_bytes{job="node",fstype!~"tmpfs|overlay|squashfs|nsfs|cgroup2",mountpoint!~"^/(run|proc|sys|dev)($|/)"}
))
)
Иноды: когда «места полно», но писать уже нельзя
100 * (1 - (node_filesystem_files_free{job="node",mountpoint="/"} / node_filesystem_files{job="node",mountpoint="/"}))
Частые ошибки в дашбордах и алертах
Ошибка 1: суммировать размер по всем mountpoints
Запрос вида:
sum(node_filesystem_size_bytes)
почти всегда даёт «цифру без смысла»: tmpfs, bind mount, overlay и runtime-точки неизбежно испортят итог. Для «итого по серверу» выбирайте один целевой mountpoint или строьте панель «по файловым системам» без суммирования.
Ошибка 2: путать free_bytes и avail_bytes
На ext4 есть reserved blocks под root. Поэтому «свободно всего» и «доступно сервису» — разные значения. Для прикладных сервисов чаще корректнее алертить по node_filesystem_avail_bytes.
Ошибка 3: игнорировать LVM thin pool
Если у вас thin provisioning, алерт только по заполнению файловых систем внутри thin LV может не поймать приближение аварии. Добавляйте отдельные алерты по lvm_thin_data_percent и lvm_thin_metadata_percent.
Практический чек-лист: приводим мониторинг дисков в порядок
На хосте зафиксируйте реальность:
df -hT,findmnt,lsblk -f.В Prometheus посмотрите, какие
fstypeиmountpointреально приходят (overlay/tmpfs/bind).Решите, что вы мониторите: корень, data-раздел, «все реальные ФС», а для LVM thin — ещё и pool.
Сделайте фильтры: либо в PromQL, либо на стороне Node Exporter через
--collector.filesystem.mount-points-exclude.На контейнерных хостах не пытайтесь считать overlay как «диски». Мониторьте ФС, на которой лежат данные runtime (например, где расположен
/var/lib/dockerили/var/lib/containerd).Для thin provisioning добавьте метрики заполнения pool через textfile collector и отдельные алерты.
Итог
История про node exporter wrong disk size почти всегда сводится к неправильному «слою»: overlayfs и bind mount создают лишние mountpoints, а LVM thin подменяет физическую реальность логическим объёмом. Комбинация фильтрации mountpoints, аккуратных PromQL-запросов и отдельного мониторинга thin pool обычно полностью убирает «скачущие» панели и ложные алерты.


