Monitor VPS ด้วย Grafana + Prometheus แบบ Pro
การ monitor VPS แบบมืออาชีพไม่ใช่เรื่องยากอีกต่อไป ด้วยคู่หูอย่าง Prometheus และ Grafana คุณสามารถเห็น CPU, RAM, Disk, Network แบบ real-time พร้อม dashboard สวยงามและ alert อัตโนมัติเมื่อ metric เกิน threshold ที่กำหนด บทความนี้จะพาติดตั้งตั้งแต่ศูนย์จนใช้งานได้จริงบน VPS Ubuntu/Debian
สถาปัตยกรรมของระบบ
ก่อนเริ่ม ทำความเข้าใจ component แต่ละตัวก่อน:
- Node Exporter — agent เล็ก ๆ ที่รันบน VPS เพื่อเปิด endpoint metric ของระบบ (CPU/RAM/Disk/Network)
- Prometheus — time-series database ที่คอย scrape (ดึง) metric จาก Node Exporter ทุก 15 วินาที
- Grafana — dashboard engine ที่อ่านข้อมูลจาก Prometheus แล้วแสดงเป็นกราฟสวยงาม พร้อมระบบ alert
ขั้นที่ 1: เตรียม VPS และอัปเดตระบบ
เริ่มต้นด้วยการอัปเดต package และสร้าง user สำหรับรัน service โดยเฉพาะ เพื่อความปลอดภัย
sudo apt update && sudo apt upgrade -y
sudo useradd --no-create-home --shell /bin/false prometheus
sudo useradd --no-create-home --shell /bin/false node_exporter
ขั้นที่ 2: ติดตั้ง Node Exporter
Node Exporter คือ agent ที่เปิด HTTP endpoint บน port 9100 เพื่อให้ Prometheus มาดึง metric ของเครื่อง
# ดาวน์โหลด Node Exporter เวอร์ชันล่าสุด
cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.1/node_exporter-1.8.1.linux-amd64.tar.gz
tar xvf node_exporter-1.8.1.linux-amd64.tar.gz
# คัดลอก binary ไปยัง /usr/local/bin
sudo cp node_exporter-1.8.1.linux-amd64/node_exporter /usr/local/bin/
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
สร้าง systemd service file เพื่อให้ Node Exporter รันอัตโนมัติเมื่อบูต:
sudo tee /etc/systemd/system/node_exporter.service <<EOF
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable node_exporter
sudo systemctl start node_exporter
sudo systemctl status node_exporter
ทดสอบว่า Node Exporter ทำงานถูกต้อง:
curl http://localhost:9100/metrics | head -20
ขั้นที่ 3: ติดตั้ง Prometheus
Prometheus จะเป็นตัวเก็บ metric ทั้งหมด และรันบน port 9090
cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v2.52.0/prometheus-2.52.0.linux-amd64.tar.gz
tar xvf prometheus-2.52.0.linux-amd64.tar.gz
sudo mkdir /etc/prometheus /var/lib/prometheus
sudo cp prometheus-2.52.0.linux-amd64/prometheus /usr/local/bin/
sudo cp prometheus-2.52.0.linux-amd64/promtool /usr/local/bin/
sudo cp -r prometheus-2.52.0.linux-amd64/consoles /etc/prometheus
sudo cp -r prometheus-2.52.0.linux-amd64/console_libraries /etc/prometheus
sudo chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus
sudo chown prometheus:prometheus /usr/local/bin/prometheus /usr/local/bin/promtool
สร้างไฟล์ config หลักของ Prometheus:
sudo tee /etc/prometheus/prometheus.yml <<EOF
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: []
rule_files: []
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "node"
static_configs:
- targets: ["localhost:9100"]
labels:
instance: "my-vps"
env: "production"
EOF
sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml
สร้าง systemd service สำหรับ Prometheus:
sudo tee /etc/systemd/system/prometheus.service <<EOF
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries \
--storage.tsdb.retention.time=30d \
--web.listen-address=0.0.0.0:9090
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable prometheus
sudo systemctl start prometheus
sudo systemctl status prometheus
--storage.tsdb.retention.time=30d) ปรับได้ตามขนาด Disk ที่มีขั้นที่ 4: ติดตั้ง Grafana
Grafana จะรันบน port 3000 ติดตั้งผ่าน apt repository อย่างเป็นทางการ:
sudo apt install -y apt-transport-https software-properties-common wget
wget -q -O - https://apt.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install grafana -y
sudo systemctl daemon-reload
sudo systemctl enable grafana-server
sudo systemctl start grafana-server
sudo systemctl status grafana-server
เข้าใช้งาน Grafana ผ่าน browser: http://YOUR_VPS_IP:3000
Login ครั้งแรก: username admin / password admin (ระบบจะบังคับเปลี่ยน password ทันที)
ขั้นที่ 5: เชื่อมต่อ Grafana กับ Prometheus
- ไปที่เมนู Connections → Data Sources
- กด Add data source เลือก Prometheus
- ใส่ URL:
http://localhost:9090 - กด Save & Test — ควรขึ้น "Data source is working"
ขั้นที่ 6: Import Dashboard สำเร็จรูป
ไม่ต้องสร้าง dashboard เองตั้งแต่ต้น Grafana มี community dashboard ให้ใช้ฟรี:
- ไปที่ Dashboards → Import
- ใส่ ID
1860(Node Exporter Full — dashboard ยอดนิยมที่สุด) - กด Load เลือก Prometheus data source ที่เพิ่งสร้าง
- กด Import
ทันทีที่ import เสร็จ คุณจะเห็น dashboard แสดง CPU Usage, Memory Usage, Disk I/O, Network Traffic และ metric อีกกว่า 50 รายการแบบ real-time
13978 (Node Exporter for Prometheus Dashboard), 405 (Basic Node Exporter)ขั้นที่ 7: ตั้งค่า Alert Rules
Alert ช่วยให้รู้ทันทีเมื่อ server มีปัญหา เช่น CPU สูงเกิน 80% หรือ Disk เหลือน้อยกว่า 10%
สร้าง Alert Rule สำหรับ CPU สูง
- ไปที่ Alerting → Alert Rules → New alert rule
- ตั้งชื่อ:
High CPU Usage - ใส่ query ใน Expression A:
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
- ตั้ง condition:
IS ABOVE 80(แจ้งเตือนเมื่อ CPU เกิน 80%) - ตั้ง Evaluate every:
1m, For:5m(ต้องสูงติดต่อกัน 5 นาทีก่อนแจ้ง)
Alert สำหรับ Memory และ Disk
# Memory Usage เกิน 90%
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
# Disk เหลือน้อยกว่า 10%
(node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 10
ขั้นที่ 8: ตั้งค่า Notification Channel (Email/LINE)
Grafana ส่ง alert ได้หลายช่องทาง รองรับ Email, Slack, LINE Notify, Telegram, PagerDuty และอื่น ๆ
# ตั้งค่า SMTP สำหรับส่ง Email ใน /etc/grafana/grafana.ini
sudo nano /etc/grafana/grafana.ini
# หา section [smtp] แล้วแก้ไข:
[smtp]
enabled = true
host = smtp.gmail.com:587
user = [email protected]
password = your-app-password
from_address = [email protected]
from_name = Grafana Alert
sudo systemctl restart grafana-server
จากนั้นไปที่ Alerting → Contact Points → Add contact point เพิ่ม Email หรือ Webhook ตามต้องการ
ขั้นที่ 9: ความปลอดภัย — ปิด Port ที่ไม่จำเป็น
# อนุญาตเฉพาะ port 3000 (Grafana) สำหรับ public
# ปิด port 9090 และ 9100 จาก public internet
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3000/tcp
sudo ufw deny 9090/tcp
sudo ufw deny 9100/tcp
sudo ufw enable
หรือถ้าต้องการ access Prometheus จาก IP เฉพาะ:
sudo ufw allow from YOUR_HOME_IP to any port 9090
sudo ufw allow from YOUR_HOME_IP to any port 9100
ขั้นที่ 10: ตั้ง Reverse Proxy ด้วย Nginx (แนะนำ)
แทนที่จะเปิด port 3000 โดยตรง ควรวาง Nginx ไว้หน้าพร้อม SSL:
sudo apt install nginx -y
sudo tee /etc/nginx/sites-available/grafana <<EOF
server {
listen 80;
server_name grafana.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/grafana /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
จากนั้นใช้ Certbot เพิ่ม SSL:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d grafana.yourdomain.com
Checklist หลังติดตั้งเสร็จ
- Node Exporter รันอยู่และ
curl localhost:9100/metricsตอบกลับ - Prometheus scrape node job สำเร็จ (ดูใน Status → Targets)
- Grafana login ได้และ data source test ผ่าน
- Dashboard แสดงข้อมูล real-time ครบ CPU/RAM/Disk/Network
- Alert rule ตั้งค่าแล้วและ contact point ได้รับ test notification
- Port 9090 และ 9100 ปิดจาก public internet
- Nginx reverse proxy พร้อม SSL ทำงานถูกต้อง
VPS และ Hosting คุณภาพสำหรับระบบ Monitoring
ระบบ monitoring ที่ดีต้องการ VPS ที่เสถียรและ uptime สูง asiagb ให้บริการ VPS Linux ในไทยและสิงคโปร์ พร้อม SLA 99.9% และ support ภาษาไทยตลอด 24 ชั่วโมง เหมาะสำหรับทั้ง monitoring server และ production workload
ก่อนจะเพิ่ม metric endpoint ใหม่ ควรตรวจสุขภาพโดเมนก่อนด้วย dnsxray.com — ตรวจ SSL, DNS, Security Headers, และ Uptime ได้ฟรีในหน้าเดียว ช่วยให้รู้ว่า endpoint พร้อมก่อน scrape
สรุป: ระบบ Monitoring แบบ Pro ด้วย Grafana + Prometheus
เมื่อติดตั้งครบทุกขั้นตอนแล้ว คุณจะมีระบบ monitoring ระดับ production ที่:
- เก็บ metric ทุก 15 วินาที ย้อนหลังได้ 30 วัน
- แสดง dashboard แบบ real-time ผ่าน browser ทุกอุปกรณ์
- แจ้งเตือนอัตโนมัติเมื่อ CPU/RAM/Disk เกิน threshold
- รักษาความปลอดภัยด้วย firewall + SSL + reverse proxy
ขั้นตอนต่อไปที่แนะนำ ได้แก่ การเพิ่ม exporter สำหรับ MySQL, Nginx, หรือ application เฉพาะของคุณ รวมถึงการตั้ง Alertmanager เพื่อจัดการ routing alert ที่ซับซ้อนยิ่งขึ้น ระบบ Grafana + Prometheus นี้ scalable ได้ไม่จำกัด เหมาะทั้งสำหรับ VPS เครื่องเดียวไปจนถึง cluster หลายสิบเครื่อง
ตรวจสอบว่า Grafana + Prometheus ทำงานถูกต้อง
# ตรวจสอบ Node Exporter ส่ง metric ออกมาได้
curl -s http://localhost:9100/metrics | grep node_cpu_seconds_total | head -3
# ตรวจสอบ Prometheus healthy และ scrape target สำเร็จ
curl -s http://localhost:9090/-/healthy
curl -s "http://localhost:9090/api/v1/targets" | python3 -m json.tool | grep '"health"'
# ตรวจสอบ Grafana ตอบสนอง
curl -s http://localhost:3000/api/health | python3 -m json.tool
# ดู metric ของ VPS ปัจจุบันผ่าน Prometheus query
curl -s "http://localhost:9090/api/v1/query?query=100-(avg(rate(node_cpu_seconds_total{mode='idle'}[5m]))*100)" \
| python3 -m json.tool | grep value
แก้ปัญหาที่พบบ่อย
Prometheus targets แสดง "DOWN" — Node Exporter ไม่ถูก scrape
Node Exporter อาจหยุดทำงานหรือ Prometheus config ผิด
# ตรวจสอบ node_exporter service
sudo systemctl status node_exporter
# ตรวจสอบว่า port 9100 เปิดอยู่
ss -tlnp | grep 9100
# ทดสอบ curl ตรงๆ
curl http://localhost:9100/metrics | head -5
# ตรวจสอบ Prometheus config ว่า target ถูกต้อง
cat /etc/prometheus/prometheus.yml | grep -A5 "job_name"
Grafana เชื่อมต่อ Prometheus ไม่ได้ — "Data source connection error"
URL ของ Prometheus ใน Grafana data source ไม่ถูกต้อง
# ตรวจสอบว่า Prometheus รันอยู่
sudo systemctl status prometheus
# ทดสอบ endpoint ที่ Grafana จะใช้
curl http://localhost:9090/api/v1/query?query=up
# URL ที่ถูกต้องใน Grafana data source:
# http://localhost:9090 (ถ้า Grafana และ Prometheus อยู่เครื่องเดียวกัน)
Dashboard แสดง "No data" ทั้งที่ Prometheus targets UP
Time range ไม่ตรง หรือ label ใน query ไม่ match กับ instance จริง
# ตรวจสอบใน Prometheus UI ก่อน:
# ไปที่ http://VPS_IP:9090/graph แล้วพิมพ์ query นี้:
up{job="node"}
# ถ้าเห็นผล แต่ Grafana ไม่แสดง ลอง:
# 1. เปลี่ยน Time range ใน Grafana เป็น "Last 1 hour"
# 2. ตรวจสอบ variable $instance ใน dashboard ว่า filter ถูก
# 3. Refresh datasource ใน Grafana → Connections
Alert ไม่ถูกส่ง ทั้งที่ metric เกิน threshold
Alert state ต้องอยู่ใน "Firing" ต่อเนื่องตามเวลา "For" ที่กำหนดก่อน และ Contact point ต้องตั้งถูกต้อง
# ไปตรวจสอบใน Grafana:
# Alerting → Alert Rules → ดูที่ State column
# ถ้า State เป็น "Pending" แสดงว่ารอครบเวลา "For" อยู่
# ถ้า State เป็น "Normal" แสดงว่า metric ยังไม่เกิน threshold จริง
# ทดสอบ contact point โดยกด "Test" ใน:
# Alerting → Contact Points → Edit → Send test notification
Prometheus กิน RAM/Disk มากเกินไป
ข้อมูล metric สะสมตามเวลา ต้องปรับ retention หรือ scrape interval
# ดู disk usage ของ Prometheus
du -sh /var/lib/prometheus/
# ลด retention time (ตั้งค่าใน systemd service หรือ flag)
# แก้ /etc/systemd/system/prometheus.service
# เพิ่ม: --storage.tsdb.retention.time=15d
# ลด scrape interval ถ้าไม่ต้องการ resolution ละเอียด
# ใน prometheus.yml:
global:
scrape_interval: 60s # เปลี่ยนจาก 15s เป็น 60s
คำถามที่พบบ่อย
ข้อมูล Prometheus เก็บไว้นานแค่ไหน?
ค่า default คือ 15 วัน ในบทความนี้ตั้งไว้ที่ 30 วัน ปรับได้ด้วย flag --storage.tsdb.retention.time หรือจำกัดด้วยขนาด disk --storage.tsdb.retention.size=10GB สำหรับ VPS RAM 2 GB ที่เก็บ metric เครื่องเดียว 30 วันจะใช้ disk ประมาณ 1-3 GB
ต้องการ monitor VPS หลายเครื่องทำอย่างไร?
ติดตั้ง Node Exporter บนทุกเครื่องที่ต้องการ monitor แล้วเพิ่ม target ใน prometheus.yml บน Prometheus server เครื่องเดียว Prometheus จะ scrape ทุก target ทุก 15 วินาที ไม่จำเป็นต้องติดตั้ง Prometheus บนทุกเครื่อง แค่เครื่องเดียวพอ
Grafana Cloud กับ Self-hosted ต่างกันอย่างไร?
Grafana Cloud มี Free Tier ที่ใช้งานได้ฟรี (metric 10,000 series, log 50GB/เดือน) ไม่ต้องดูแล server เอง แต่ข้อมูลอยู่ใน cloud ของ Grafana Labs Self-hosted ให้ control เต็มที่, ข้อมูลอยู่ใน VPS เราเอง และไม่มี limit — เหมาะสำหรับ production ที่ต้องการ privacy หรือ data retention นานกว่า 30 วัน