Node Exporter เป็น exporter สำคัญของ Prometheus ที่ใช้เก็บ metric ระดับระบบปฏิบัติการ Linux/Unix เช่น CPU, Memory, Disk, Network, File system และ systemd service — เป็น exporter ตัวแรกที่ทุกคนต้องติดตั้งเมื่อเริ่มวาง monitoring stack เพราะครอบคลุม baseline metric ของ server ทั้งหมด
บทความนี้จะอธิบายวิธีติดตั้ง node_exporter แบบ binary และ Docker, เลือก collector ที่เหมาะสมกับ workload, ตั้ง systemd service, เชื่อมกับ Prometheus server และวิเคราะห์ metric สำคัญ ๆ ที่ควรใช้ในการ monitor ระบบ production
Node Exporter คืออะไร
Node Exporter เป็น official exporter ของ Prometheus ที่เขียนด้วย Go รันเป็น HTTP server ขนาดเล็ก (binary ประมาณ 20MB) เปิด endpoint /metrics บน port 9100 — เก็บ metric จาก /proc, /sys และ system call ของ Linux kernel โดยตรง ไม่พึ่ง external dependency
ข้อดีของ node_exporter คือเบาและประสิทธิภาพสูง — รัน 1000+ collector ได้ในเวลาไม่ถึงวินาที เหมาะกับทั้งเครื่อง production ที่ต้องการ overhead ต่ำ และเครื่องขนาดเล็กอย่าง Raspberry Pi หรือ IoT device
ติดตั้ง Node Exporter แบบ Binary
วิธีนี้เหมาะกับเครื่อง VM หรือ bare metal ที่ต้องการให้ node_exporter รันเป็น systemd service โดยตรง — ไม่ต้องมี Docker layer:
# Download binary ล่าสุดจาก GitHub releases
cd /tmp
VERSION=1.8.2
wget https://github.com/prometheus/node_exporter/releases/download/v${VERSION}/node_exporter-${VERSION}.linux-amd64.tar.gz
tar xzf node_exporter-${VERSION}.linux-amd64.tar.gz
# ติดตั้ง binary
sudo mv node_exporter-${VERSION}.linux-amd64/node_exporter /usr/local/bin/
sudo useradd --no-create-home --shell /usr/sbin/nologin node_exporter
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
การสร้าง user เฉพาะที่ไม่มี shell และ home directory เป็น security best practice — ลดผลกระทบถ้ามีช่องโหว่ใน exporter
สร้าง Systemd Service
# /etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
Restart=on-failure
ExecStart=/usr/local/bin/node_exporter \
--collector.systemd \
--collector.processes \
--collector.filesystem.mount-points-exclude='^/(sys|proc|dev|run)($|/)' \
--web.listen-address=:9100
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
sudo systemctl status node_exporter
# ทดสอบ metric
curl http://localhost:9100/metrics | head -50
ถ้า curl return metric แบบ plain text พร้อม node_cpu_seconds_total, node_memory_MemAvailable_bytes แสดงว่า exporter ทำงานปกติ
ติดตั้ง Node Exporter ด้วย Docker
ถ้าใช้ Docker หรือ Kubernetes การรัน node_exporter ในคอนเทนเนอร์จะสะดวกกว่า แต่ต้อง mount path ของ host เข้าไปเพราะ exporter ต้องอ่าน /proc, /sys, /rootfs จากตัว host ไม่ใช่จากคอนเทนเนอร์:
docker run -d \
--name node-exporter \
--restart unless-stopped \
--net=host \
--pid=host \
-v /:/host:ro,rslave \
quay.io/prometheus/node-exporter:v1.8.2 \
--path.rootfs=/host \
--collector.filesystem.mount-points-exclude='^/(sys|proc|dev|host|etc)($|/)'
ใช้ --net=host และ --pid=host เพื่อให้ exporter เห็น network และ process ของ host — ถ้ารันแบบ bridge network ค่าจะเป็นของคอนเทนเนอร์เท่านั้น
Docker Compose
services:
node-exporter:
image: quay.io/prometheus/node-exporter:v1.8.2
container_name: node-exporter
restart: unless-stopped
network_mode: host
pid: host
volumes:
- /:/host:ro,rslave
command:
- '--path.rootfs=/host'
- '--collector.systemd'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
Collector สำคัญ
Node Exporter มี collector กว่า 50 ตัว — แต่ละ collector เก็บ metric จากระบบคนละส่วน โดย default เปิดบาง collector และปิดบาง collector เพื่อลด overhead:
| Collector | หน้าที่ | Default |
|---|---|---|
| cpu | CPU utilization per core, mode | เปิด |
| meminfo | Memory usage, swap, cache | เปิด |
| diskstats | Disk I/O per device | เปิด |
| filesystem | Disk usage per mount point | เปิด |
| netdev | Network interface traffic | เปิด |
| loadavg | Load average 1/5/15 minute | เปิด |
| systemd | Systemd service status | ปิด (ต้องเปิดเอง) |
| processes | Process count, state | ปิด |
| textfile | Custom metric จากไฟล์ | ปิด |
| ntp | NTP clock sync | ปิด |
เปิด collector เพิ่มด้วย flag --collector.<name> และปิดด้วย --no-collector.<name> — เปิดเฉพาะที่จำเป็น เพราะบาง collector เช่น supervisord, wifi ไม่จำเป็นในเครื่อง server
เพิ่มใน Prometheus Config
scrape_configs:
- job_name: 'node'
scrape_interval: 15s
static_configs:
- targets:
- 'server1:9100'
- 'server2:9100'
- 'server3:9100'
labels:
environment: 'production'
role: 'web'
สำหรับ environment ที่ server เพิ่ม/ลดบ่อย เช่น autoscaling cluster ควรใช้ service discovery แทน static_configs — เช่น Consul, Kubernetes, EC2 SD
CPU Usage
# CPU usage ทุก mode รวมกัน (เป็น rate ต่อวินาที)
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# CPU usage เฉพาะ user space
avg by (instance) (rate(node_cpu_seconds_total{mode="user"}[5m])) * 100
# CPU iowait สูง = disk bottleneck
avg by (instance) (rate(node_cpu_seconds_total{mode="iowait"}[5m])) * 100
Memory Usage
# Memory usage เป็น percentage (ใช้ MemAvailable ที่แม่นกว่า MemFree)
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# Swap usage
(node_memory_SwapTotal_bytes - node_memory_SwapFree_bytes) / node_memory_SwapTotal_bytes * 100
ใช้ node_memory_MemAvailable_bytes แทน node_memory_MemFree_bytes เพราะ Linux kernel ใช้ RAM ว่างเป็น cache — MemAvailable บอกจริง ๆ ว่าเหลือเท่าไหร่ที่ application ใช้ได้
Disk Usage & I/O
# Disk ใช้งานเท่าไหร่ต่อ mount point
(node_filesystem_size_bytes{fstype!~"tmpfs|overlay"} - node_filesystem_avail_bytes)
/ node_filesystem_size_bytes * 100
# Disk read/write rate
rate(node_disk_read_bytes_total[5m])
rate(node_disk_written_bytes_total[5m])
# Disk latency เฉลี่ย
rate(node_disk_read_time_seconds_total[5m]) / rate(node_disk_reads_completed_total[5m])
Network
# Network throughput per interface
rate(node_network_receive_bytes_total{device!~"lo|docker.*"}[5m])
rate(node_network_transmit_bytes_total{device!~"lo|docker.*"}[5m])
# Network error rate
rate(node_network_receive_errs_total[5m])
Load Average
# Load average normalize ด้วยจำนวน CPU core
node_load5 / count by (instance) (node_cpu_seconds_total{mode="idle"})
Load average ค่ามากกว่าจำนวน core แปลว่า process ยืนต่อคิว — ถ้า load/core เกิน 1.0 เป็นระยะเวลานาน เครื่องมี bottleneck
Textfile Collector
textfile collector เป็นของพิเศษที่อ่าน metric จากไฟล์ .prom ใน directory ที่กำหนด — เหมาะกับ metric ที่ไม่ได้มาจาก HTTP server แต่มาจาก cron job หรือ backup script:
# เปิด collector แล้วกำหนด directory
node_exporter --collector.textfile.directory=/var/lib/node_exporter/textfile_collector
# สร้าง metric จาก script
cat > /var/lib/node_exporter/textfile_collector/backup.prom.$$ <<EOF
# HELP backup_last_success_timestamp Last successful backup
# TYPE backup_last_success_timestamp gauge
backup_last_success_timestamp $(date +%s)
EOF
mv /var/lib/node_exporter/textfile_collector/backup.prom.$$ \
/var/lib/node_exporter/textfile_collector/backup.prom
เขียนแบบ atomic ด้วย temp file แล้ว mv เพื่อไม่ให้ exporter อ่านไฟล์กลางทาง — ป้องกัน corrupt metric
Best Practices
- ติดตั้ง node_exporter ทุก server โดย default — baseline metric สำคัญกว่าที่คิด
- เปิด systemd collector ถ้าเครื่องมี service สำคัญที่ต้อง alert เมื่อล่ม
- ปิด collector ที่ไม่ใช้ เช่น
mdadm,nfs,zfsถ้าไม่ได้ใช้เทคโนโลยีเหล่านั้น - ใช้ flag
--web.listen-address=127.0.0.1:9100ถ้าใช้ reverse proxy กั้นหน้า — ไม่ให้ expose ต่อ public network ตรง ๆ - เปิด firewall เฉพาะ Prometheus server ให้เข้า port 9100 ได้
- ใช้ Grafana dashboard 1860 (Node Exporter Full) เป็น starting point — ครอบคลุม metric ทั้งหมด
- Alert บน
up == 0เพื่อจับ exporter ล่ม และ host unreachable - ใช้ label
instanceสม่ำเสมอระหว่าง production/staging — ช่วยทำ dashboard ที่ drill down ได้
Troubleshooting
| อาการ | สาเหตุ | วิธีแก้ |
|---|---|---|
| Port 9100 ไม่เปิด | Firewall block หรือ service ล่ม | systemctl status node_exporter, ss -tlnp | grep 9100 |
| Metric filesystem ซ้ำ | Docker/Kubernetes mount point | เพิ่ม --collector.filesystem.mount-points-exclude |
| Metric ขาด (ไม่มี systemd) | Collector ไม่ได้เปิด | เพิ่ม --collector.systemd ใน ExecStart |
| Memory usage ผิด | ใช้ MemFree แทน MemAvailable | เปลี่ยนมาใช้ node_memory_MemAvailable_bytes |
| Disk usage ผิด (tmpfs ถูกนับ) | ไม่ได้กรอง fstype | เพิ่ม fstype!~"tmpfs|overlay" ใน query |
สรุป
Node Exporter เป็น baseline exporter ที่ทุกระบบ monitoring ต้องมี — ครอบคลุม metric ของ OS, disk, network, process ให้ครบในตัวเดียว ติดตั้งง่าย ใช้ทรัพยากรน้อย และมี Grafana dashboard สำเร็จรูปให้ใช้ทันที การเปิด collector ที่เหมาะสมและตั้งค่า scrape interval อย่างถูกต้องจะช่วยให้ได้ visibility ของ infrastructure ที่สมบูรณ์โดยใช้ effort น้อยที่สุด
ขั้นตอนถัดไปคือเรียนรู้ PromQL เพื่อเขียน query ที่ดึง insight จาก metric เหล่านี้ได้ลึกกว่า dashboard มาตรฐาน และเขียน custom exporter เพื่อ monitor application ของตัวเอง

