Сбор метрик инфраструктуры: CPU, память, диск, сеть
«Инфраструктура — это фундамент. Если фундамент кривой, приложение не устоит»
Node Exporter — официальный экспортёр Prometheus для сбора метрик Linux/Unix серверов.
Собирает:
Не собирает:
Добавьте в docker-compose.yml:
services:
node_exporter:
image: prom/node-exporter:v1.7.0
container_name: node_exporter
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
restart: unless-stoppedВажно: volumes дают доступ к системной информации хоста из контейнера.
# Скачать
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
# Распаковать
tar xvfz node_exporter-1.7.0.linux-amd64.tar.gz
cd node_exporter-1.7.0.linux-amd64
# Запустить
./node_exporter &
# Или как systemd сервис
sudo systemctl enable node_exporter
sudo systemctl start node_exporterДобавьте job в prometheus.yml:
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
# Для нескольких серверов:
# - targets:
# - 'server1:9100'
# - 'server2:9100'
# labels:
# env: 'production'
# datacenter: 'us-east'Перезапустите Prometheus и проверьте в UI:
Node Exporter экспортирует сотни метрик. Вот основные.
# Загрузка CPU по ядрам (процент)
100 - (avg by (instance, cpu) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Загрузка по режимам (user, system, iowait, irq)
sum by (mode) (rate(node_cpu_seconds_total{mode=~"user|system|iowait|irq"}[5m]))
# Средняя загрузка по всем ядрам
100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)Режимы CPU:
user — время пользовательских процессовsystem — время ядраidle — простойiowait — ожидание I/O (диск, сеть)irq — обработка прерыванийВажно: высокий iowait указывает на узкое место в диске или сети.
# Процент использования памяти
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)
/
node_memory_MemTotal_bytes
* 100
# Использованная память (байты)
node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes
# Swap usage
(node_memory_SwapTotal_bytes - node_memory_SwapFree_bytes)
/
node_memory_SwapTotal_bytes
* 100
# Кэш и буферы
node_memory_Cached_bytes + node_memory_Buffers_bytesВажно: используйте MemAvailable, а не MemFree. Linux использует свободную память для кэша, что хорошо для производительности.
# Использование диска (процент)
(node_disk_size_bytes - node_disk_free_bytes)
/
node_disk_size_bytes
* 100
# Чтение/запись (байт в секунду)
sum(rate(node_disk_read_bytes_total[5m]))
sum(rate(node_disk_written_bytes_total[5m]))
# I/O операции в секунду (IOPS)
sum(rate(node_disk_reads_completed_total[5m]))
sum(rate(node_disk_writes_completed_total[5m]))
# Время ожидания диска (секунд)
rate(node_disk_io_time_seconds_total[5m])Важно: высокий io_time_seconds_total (>0.8) указывает на перегрузку диска.
# Входящий трафик (бит в секунду)
sum(rate(node_network_receive_bytes_total{device!="lo"}[5m])) * 8
# Исходящий трафик (бит в секунду)
sum(rate(node_network_transmit_bytes_total{device!="lo"}[5m])) * 8
# Ошибки приёма/передачи
sum(rate(node_network_receive_errs_total[5m]))
sum(rate(node_network_transmit_errs_total[5m]))
# Drop packets (потерянные пакеты)
sum(rate(node_network_receive_drop_total[5m]))
sum(rate(node_network_transmit_drop_total[5m]))Важно: исключите lo (loopback интерфейс), если не нужен внутренний трафик.
# Uptime в секундах
node_time_seconds - node_boot_time_seconds
# Uptime в днях
(node_time_seconds - node_boot_time_seconds) / 86400
# Количество загрузок
node_boot_time_seconds # меняется при перезагрузке# Количество процессов
node_procs_running
# Количество потоков
node_procs_blocked
# Состояние процессов (running, sleeping, zombie)
sum by (state) (node_processes_state)# CPU Usage %
100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Memory Usage %
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)
/
node_memory_MemTotal_bytes
* 100
# Disk Usage %
(node_disk_size_bytes - node_disk_free_bytes)
/
node_disk_size_bytes
* 100
# Uptime (days)
(node_time_seconds - node_boot_time_seconds) / 86400# CPU по режимам
sum by (mode) (rate(node_cpu_seconds_total{mode=~"user|system|iowait|idle"}[5m])) * 100
# Memory breakdown
node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes, # Used
node_memory_Cached_bytes + node_memory_Buffers_bytes, # Cached
node_memory_MemFree_bytes # Free
# Network traffic
sum by (device) (rate(node_network_receive_bytes_total{device!="lo"}[5m])) * 8,
sum by (device) (rate(node_network_transmit_bytes_total{device!="lo"}[5m])) * -8
# Disk I/O
sum(rate(node_disk_read_bytes_total[5m])),
sum(rate(node_disk_written_bytes_total[5m]))- alert: HighCPUUsage
expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 15m
labels:
severity: warning
annotations:
summary: "High CPU usage on {{ $labels.instance }}"
description: "CPU usage is {{ $value | humanizePercentage }} for more than 15 minutes"- alert: HighMemoryUsage
expr: |
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)
/
node_memory_MemTotal_bytes
* 100 > 90
for: 15m
labels:
severity: warning
annotations:
summary: "High memory usage on {{ $labels.instance }}"
description: "Memory usage is {{ $value | humanizePercentage }}"- alert: DiskSpaceLow
expr: |
(node_disk_size_bytes - node_disk_free_bytes)
/
node_disk_size_bytes
* 100 > 85
for: 1h
labels:
severity: warning
annotations:
summary: "Disk space low on {{ $labels.instance }}"
description: "Disk usage is {{ $value | humanizePercentage }} on {{ $labels.device }}"- alert: DiskWillFillIn24Hours
expr: |
predict_linear(node_disk_free_bytes[24h], 24*3600) < 0
for: 30m
labels:
severity: critical
annotations:
summary: "Disk will fill in 24 hours on {{ $labels.instance }}"
description: "Based on 24h trend, disk {{ $labels.device }} will be full"- alert: HighIOWait
expr: |
avg by (instance) (rate(node_cpu_seconds_total{mode="iowait"}[5m]))
/
count by (instance) (node_cpu_seconds_total{mode="idle"})
* 100 > 20
for: 15m
labels:
severity: warning
annotations:
summary: "High I/O wait on {{ $labels.instance }}"
description: "I/O wait is {{ $value | humanizePercentage }} — possible disk bottleneck"- alert: ServerRebooted
expr: changes(node_boot_time_seconds[5m]) > 0
for: 0m
labels:
severity: info
annotations:
summary: "Server {{ $labels.instance }} was rebooted"
description: "Boot time changed at {{ $value | humanizeTimestamp }}"Импортируйте готовый дашборд из каталога Grafana:
Node Exporter Full (ID: 8919)
8919Что включает:
scrape_configs:
- job_name: 'node'
static_configs:
- targets:
- 'server1:9100'
- 'server2:9100'
- 'server3:9100'
labels:
env: 'production'
datacenter: 'us-east'Для динамического добавления серверов используйте file_sd:
scrape_configs:
- job_name: 'node'
file_sd_configs:
- files:
- '/etc/prometheus/targets/node.json'
refresh_interval: 5mФайл node.json:
[
{
"targets": ["server1:9100", "server2:9100"],
"labels": {
"env": "production",
"datacenter": "us-east"
}
},
{
"targets": ["server3:9100"],
"labels": {
"env": "staging",
"datacenter": "eu-west"
}
}
]Преимущество: можно обновлять список серверов без перезапуска Prometheus.
Причины:
Решение:
# Проверьте статус
systemctl status node_exporter
# Проверьте порт
curl http://localhost:9100/metrics
# Проверьте сеть
telnet server1 9100Причины:
Решение:
--path.procfs, --path.sysfsNode Exporter экспортирует 1000+ метрик. Если не все нужны:
scrape_configs:
- job_name: 'node'
metric_relabel_configs:
# Отбросить метрики, не начинающиеся с node_cpu или node_memory
- source_labels: [__name__]
regex: 'node_(cpu|memory)_.*'
action: keepmetric_relabel_configs для фильтрации.Теперь вы умеете мониторить инфраструктуру. В следующей теме вы изучите Service Discovery — автоматическое обнаружение целей в динамических средах.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.