HomeLab.net.ua

Твоє залізо. Твої правила. Твоя мова.

Моніторинг домашнього сервера через Prometheus і Grafana: CPU, диск, SMART і контейнери Docker

Опубліковано

моніторинг домашнього сервера

Моніторинг домашнього сервера через Prometheus і Grafana дає одну практичну річ: нормальну картину стану хоста без SSH щоразу, коли щось починає підвисати. У такій схемі видно навантаження CPU, заповнення і latency диска, SMART-атрибути та поведінку контейнерів Docker. Нижче – робоча структура, які експортери ставити, що саме збирати і де ця схема зазвичай ламається.

Для homelab цього достатньо у більшості випадків. Не потрібен важкий enterprise-стек, але й одних графіків load average мало. Коли диск уже сипле reallocated sectors, а контейнер перезапускається раз на годину, проблема давно не в “загальному навантаженні”.

Сенс у тому, щоб збирати не все підряд, а тільки сигнали, за якими реально видно деградацію системи. Для CPU – steal, iowait, saturation по ядрах. Для диска – не лише usage, а й I/O time. Для SMART – помилки, temperature, ознаки деградації. Для Docker – restarts, memory pressure, стан окремих контейнерів.

Що саме має збирати моніторинг домашнього сервера

Базова схема проста: Prometheus опитує експортери, Grafana показує дашборди, а сам сервер віддає метрики хоста, дисків і контейнерів. Для домашнього вузла цього вистачає, якщо не намагатися тягнути кожен kernel counter без розбору.

  • Prometheus – зберігання та опитування метрик через pull-модель.
  • Prometheus коректно працює як центральна точка збору навіть у малому homelab.
  • Grafana потрібна не для краси, а для швидкого читання аномалій по часових рядах.
  • node_exporter віддає метрики CPU, RAM, файлових систем, мережі та блочних пристроїв.
  • Для SMART зазвичай додають окремий exporter, який читає дані через smartctl.
  • Для Docker потрібен cAdvisor або інший сумісний збирач контейнерних метрик.

На одному хості все це працює без проблем. Коли контейнерів стає багато, починається інше: не брак інструментів, а шум у метриках. На практиці після кількох десятків контейнерів цінність має не кількість графіків, а нормальний набір alerting-умов і фільтрація службових контейнерів.

Як налаштувати моніторинг домашнього сервера

Найпростіший варіант – підняти Prometheus, Grafana і cAdvisor у Docker, а node_exporter запустити з доступом до хостових метрик. SMART-експортер краще ставити окремо, бо доступ до дисків і smartctl майже завжди впирається в права та device mapping.

  1. Створити окрему мережу Docker для сервісів моніторингу.
  2. Підняти Prometheus з файлом targets.
  3. Підняти Grafana і підключити Prometheus як data source.
  4. Запустити node_exporter для метрик хоста.
  5. Додати cAdvisor для контейнерів Docker.
  6. Додати SMART exporter або скрипт-експортер на базі smartctl.

Мінімальний docker-compose для старту

services:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
    ports:
      - "9090:9090"
    restart: unless-stopped

  grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
    restart: unless-stopped

  node-exporter:
    image: prom/node-exporter
    container_name: node-exporter
    command:
      - '--path.rootfs=/host'
    network_mode: host
    pid: host
    volumes:
      - '/:/host:ro,rslave'
    restart: unless-stopped

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    container_name: cadvisor
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker:/var/lib/docker:ro
    restart: unless-stopped

volumes:
  grafana-data:

Мінімальний prometheus.yml

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    static_configs:
      - targets: ['192.168.1.10:9100']

  - job_name: 'cadvisor'
    static_configs:
      - targets: ['192.168.1.10:8080']

Якщо Prometheus і node_exporter стоять на одному хості в Docker, адреса targets залежить від режиму мережі. Тут часто помиляються: контейнер бачить не той localhost, який очікується. Найменше сюрпризів дає або host network для exporter, або явний IP хоста.

CPU, диск, SMART і Docker – які метрики справді корисні

Для одного сервера достатньо кількох груп метрик, які показують не просто факт навантаження, а тип проблеми. Саме це відрізняє робочий моніторинг домашнього сервера від набору красивих дашбордів, де нічого не видно в момент збою.

CPU

  • Завантаження по ядрах, а не лише середнє по системі.
  • iowait – якщо росте разом із latency диска, вузьке місце майже напевно в storage.
  • steal – актуально для віртуалізованого хоста.
  • context switches і load average корисні як допоміжний сигнал, не як основний.

Високий CPU сам по собі часто не проблема. Набагато гірший сценарій – коли середнє навантаження виглядає спокійно, але одне ядро забите контейнером із погано налаштованим transcoding або backup-job.

Диск

  • usage файлових систем.
  • read/write throughput.
  • disk I/O time і await-подібні показники, якщо exporter їх віддає.
  • inode usage для томів із великою кількістю дрібних файлів.

У homelab переповнення диска рідко стається миттєво. Частіше проблема в іншому: storage ще не заповнений, але response time вже поганий через фоновий scrub, backup або log-spam усередині контейнера.

SMART

  • temperature.
  • overall health status.
  • reallocated sectors.
  • pending sectors.
  • CRC errors для перевірки кабелів і контролера.

SMART не дає гарантії, що диск помре завтра. Але він добре ловить повільну деградацію. У домашніх серверах саме CRC errors і temperature часто вказують на проблему раніше, ніж з’являються реальні I/O помилки.

Docker

  • CPU і memory usage по контейнерах.
  • restarts.
  • network I/O.
  • filesystem usage для writable layer, якщо це підтримується в метриках.
  • стан unhealthy або постійні перезапуски.

Тут є одна неочевидна межа. Метрики контейнерів корисні, поки є дисципліна в назвах, labels і restart policy. Без цього дашборд швидко перетворюється на список одноразових контейнерів, де знайти винуватця важче, ніж просто відкрити docker ps.

Які дашборди збирати в Grafana

У Grafana варто розділити хост і контейнери. Один дашборд для стану сервера, другий – для Docker. Інакше аварійні сигнали губляться між дрібними серіями. Перший екран має відповідати на три питання: чи живий хост, чи вперся в диск, чи є контейнер із деградацією.

Дашборд Що показувати Навіщо
Host overview CPU, RAM, filesystem usage, disk I/O time, network Швидка діагностика стану хоста
Storage health SMART, temperature, reallocated/pending sectors Раннє виявлення проблем із диском
Docker overview CPU, memory, restarts, network I/O по контейнерах Пошук шумних або нестабільних сервісів

Гірша практика – виводити десятки панелей на один екран. Коли все зелене, це терпимо. Під час збою такий дашборд марний. Потрібні великі панелі з коротким шляхом до drill-down, а не музей PromQL.

Як перевірити, що моніторинг домашнього сервера працює коректно

Перевірка не зводиться до того, що графік з’явився. Потрібно переконатися, що збираються саме ті метрики, які допоможуть у реальному збої. Мінімум – перевірити targets у Prometheus, доступність exporter endpoints і реакцію графіків на контрольоване навантаження.

  1. Відкрити Prometheus і перевірити статус targets.
  2. Переконатися, що node_exporter і cAdvisor віддають метрики без timeout.
  3. У Grafana відкрити панелі CPU, disk I/O і Docker restarts.
  4. Створити коротке навантаження на CPU або диск.
  5. Перевірити, що зміни видно в межах scrape interval.
  6. Перезапустити тестовий контейнер і подивитися, чи зростає лічильник restart.
curl http://192.168.1.10:9100/metrics
curl http://192.168.1.10:8080/metrics

Якщо SMART-метрики не з’являються, причина майже завжди в доступі до пристрою або в тому, що диск сидить за контролером, який не віддає SMART напряму в контейнер. На USB-SATA адаптерах це трапляється регулярно.

Де ця схема ламається найчастіше

Найтиповіші проблеми не в Prometheus і не в Grafana. Вони нижче: права доступу, мережевий режим контейнера, неправильні mount points, відсутність SMART у віртуалці або шум від короткоживучих контейнерів. Моніторинг домашнього сервера стає крихким саме на стику хоста й контейнерів.

  • node_exporter запущений без доступу до rootfs хоста – частина метрик некоректна.
  • cAdvisor не бачить Docker runtime повністю – контейнерні метрики неповні.
  • Prometheus опитує localhost усередині контейнера замість хоста.
  • SMART у контейнері не працює через device permissions.
  • Дашборди є, але alerting не налаштований – проблема видно тільки постфактум.

Окрема пастка – записувати занадто багато серій із коротким retention без розуміння, навіщо вони потрібні. Для одного домашнього вузла це не вб’є сервер, але забере головне: читабельність. Уже на невеликому обсязі метрик стає видно, що хороший моніторинг – це відбір, а не колекціонування.

Коли цього підходу вже мало

Prometheus і Grafana добре закривають один хост або невеликий homelab. Далі починаються інші вимоги: централізований alerting, довший retention, агрегація кількох майданчиків, нормальна інвентаризація сервісів. У цей момент простий моніторинг домашнього сервера вже треба перетворювати на систему спостереження за інфраструктурою.

Якщо вузлів стає кілька, логічно виносити метрики в окремий моніторинговий хост. Коли з’являється потреба зберігати історію місяцями, варто дивитися на remote storage. А якщо головна проблема не в метриках, а в журналах і трасуванні запитів, самих Prometheus і Grafana вже замало.

Для одного сервера цього стеку вистачає надовго. Але тільки якщо дашборди показують причину, а не просто факт, що “щось повільно”.

Офіційна документація Prometheus
Офіційна документація Grafana