Sau khi đã có SSH hardening, Fail2ban và backup chiến lược, VPS của bạn đã an toàn hơn rất nhiều so với một server mới thuê. Nhưng vẫn còn một khoảng trống rất lớn: làm sao biết server đang khỏe hay sắp gặp vấn đề?
Một VPS có thể hết disk, tăng RAM bất thường, CPU load cao, network spike, service restart liên tục, backup fail, database chậm hoặc Nginx trả 502 trước khi bạn kịp nhận ra. Nếu chỉ đợi người dùng báo lỗi rồi mới SSH vào xem top, df -h hoặc journalctl, bạn đang vận hành trong trạng thái bị động.
Bài Monitoring VPS Ubuntu 24.04 với Prometheus, node_exporter và Grafana 2026 sẽ hướng dẫn cách dựng một hệ thống monitoring tối thiểu cho VPS Ubuntu 24.04 LTS. Mục tiêu là cài Prometheus để thu thập metrics, cài node_exporter để xuất metrics hệ thống, cài Grafana để xem dashboard, kiểm tra CPU/RAM/disk/network, và giữ toàn bộ giao diện monitoring ở chế độ local-only để không mở thêm bề mặt tấn công ra internet.
Đây chưa phải một hệ observability đầy đủ với logs, traces, alert routing, incident management hay on-call workflow. Nhưng đây là nền rất quan trọng: trước khi tối ưu hiệu năng hoặc troubleshooting chuyên sâu, bạn cần có số liệu.
1. Hiểu đúng về monitoring VPS Ubuntu 24.04
1.1. Monitoring không phải chỉ để vẽ dashboard đẹp
Grafana dashboard đẹp rất dễ gây ấn tượng, nhưng mục tiêu thật của monitoring không phải là nhìn biểu đồ cho vui. Monitoring giúp trả lời các câu hỏi vận hành rất cụ thể:
- CPU có đang bị dùng quá cao không?
- RAM còn đủ hay server đang swap?
- Disk còn bao nhiêu phần trăm?
- Disk có đang bị đọc/ghi bất thường không?
- Network có spike lạ không?
- Server vừa reboot lúc nào?
- Service có restart liên tục không?
- Backup có chạy đều không?
- Website chậm do tài nguyên hệ thống hay do app/database?
Nếu không có monitoring, bạn thường chỉ thấy hậu quả: website sập, SSH chậm, database không ghi được, Certbot renew fail, backup fail hoặc người dùng báo lỗi. Nếu có monitoring, bạn có cơ hội phát hiện sớm hơn.
1.2. Metrics khác gì logs?
Metrics là số liệu theo thời gian, ví dụ CPU usage, RAM used, disk free, network bytes, load average, số process, số file descriptor. Metrics phù hợp để vẽ biểu đồ, đặt ngưỡng cảnh báo và nhìn xu hướng.
Logs là sự kiện dạng dòng chữ, ví dụ Nginx access log, PHP-FPM error, MariaDB journal, Fail2ban ban IP, Certbot renew log. Logs phù hợp để điều tra chi tiết khi đã biết có vấn đề.
Bài này tập trung vào metrics bằng Prometheus, node_exporter và Grafana. Bài sau đó sẽ đi sâu hơn vào logging và rotation.
1.3. Vì sao chọn Prometheus, node_exporter và Grafana?
Prometheus là hệ thống monitoring và time series database rất phổ biến trong DevOps. Nó hoạt động theo mô hình scrape: Prometheus định kỳ kéo metrics từ các target như node_exporter, app exporter hoặc database exporter.
node_exporter là exporter của Prometheus dùng để xuất metrics hệ thống Linux: CPU, memory, filesystem, disk I/O, network, load, systemd, process và nhiều collector khác.
Grafana là công cụ visualization. Nó không thay Prometheus lưu metrics, mà kết nối đến Prometheus để truy vấn và hiển thị dashboard. Với combo này, một VPS nhỏ đã có thể có monitoring nền khá tốt.
1.4. Không nên mở Grafana, Prometheus, node_exporter public
Người mới rất dễ cài xong rồi mở port 3000, 9090, 9100 ra internet để truy cập cho tiện. Đây là thói quen không tốt.
Với VPS cá nhân hoặc server nhỏ, cấu hình an toàn hơn là:
- Prometheus chỉ listen trên
127.0.0.1:9090. - node_exporter chỉ listen trên
127.0.0.1:9100. - Grafana chỉ listen trên
127.0.0.1:3000. - Truy cập dashboard qua SSH tunnel.
- Chỉ mở public khi đã có HTTPS, authentication, allowlist IP, reverse proxy hoặc Zero Trust.
Monitoring chứa rất nhiều thông tin nhạy cảm về hạ tầng. Không nên public nó chỉ vì muốn mở dashboard nhanh.
2. Kiến trúc monitoring tối thiểu cho một VPS
2.1. Mô hình single VPS
Trong bài này, toàn bộ stack monitoring chạy trên cùng VPS:
+-------------------------------+
| VPS Ubuntu 24.04 |
| |
| node_exporter : 127.0.0.1:9100|
| Prometheus : 127.0.0.1:9090|
| Grafana : 127.0.0.1:3000|
| |
| Access via SSH tunnel |
+-------------------------------+
Prometheus sẽ scrape chính nó và node_exporter. Grafana sẽ kết nối đến Prometheus bằng URL local:
http://127.0.0.1:9090
Người quản trị sẽ mở dashboard từ máy cá nhân thông qua SSH tunnel:
ssh -L 3000:127.0.0.1:3000 admin@SERVER_IP
Sau đó truy cập Grafana ở máy cá nhân:
http://127.0.0.1:3000
2.2. Khi nào cần tách monitoring sang server riêng?
Mô hình single VPS đủ tốt cho học tập, blog cá nhân, website nhỏ và self-host cơ bản. Tuy nhiên, nếu VPS chính chết hoàn toàn, monitoring nằm trên cùng VPS cũng chết theo. Vì vậy, với production quan trọng hơn, bạn nên tách monitoring ra server khác hoặc dùng dịch vụ monitoring bên ngoài.
Quy tắc thực tế:
- Một VPS nhỏ: chạy Prometheus + Grafana local để học và quan sát nền.
- Nhiều VPS: dùng một monitoring server riêng scrape nhiều node_exporter.
- Production quan trọng: thêm external uptime monitor và alert channel.
- Hạ tầng lớn: cân nhắc Grafana Cloud, Mimir, Thanos, VictoriaMetrics hoặc kiến trúc remote write.
Bài này cố tình giữ phạm vi nhỏ để dễ triển khai và dễ hiểu trước.
2.3. Những gì sẽ được theo dõi trong bài này
- CPU usage và load average.
- RAM available, swap usage.
- Disk free, disk usage theo filesystem.
- Disk read/write.
- Network receive/transmit.
- Uptime của server.
- Trạng thái scrape target trong Prometheus.
- Một số alert rule cơ bản cho disk, RAM, load và instance down.
Các phần nâng cao như Nginx exporter, PHP-FPM exporter, mysqld_exporter, Blackbox exporter, Alertmanager và notification qua Telegram/Slack sẽ phù hợp để mở rộng sau khi nền đã ổn.
3. Chuẩn bị trước khi cài Prometheus và Grafana
3.1. Kiểm tra hệ điều hành và quyền sudo
lsb_release -a || cat /etc/os-release
whoami
id
sudo -v
Bài này giả định VPS đang chạy Ubuntu 24.04 LTS và user hiện tại có quyền sudo.
3.2. Kiểm tra tài nguyên VPS
Prometheus và Grafana không quá nặng cho cấu hình nhỏ, nhưng vẫn cần tài nguyên. Kiểm tra nhanh:
free -h
df -h
nproc
uptime
Với VPS RAM 1GB, bạn vẫn có thể chạy stack monitoring tối thiểu, nhưng cần giữ retention vừa phải và không scrape quá nhiều target. Với VPS 2GB RAM trở lên, trải nghiệm sẽ dễ chịu hơn.
3.3. Kiểm tra firewall
sudo ufw status verbose
Trong bài này, Prometheus, node_exporter và Grafana sẽ bind vào 127.0.0.1, nên không cần mở thêm port public. Không chạy các lệnh kiểu sau nếu chưa có thiết kế bảo mật rõ:
sudo ufw allow 3000/tcp
sudo ufw allow 9090/tcp
sudo ufw allow 9100/tcp
Dashboard monitoring public là một bề mặt tấn công không cần thiết cho VPS nhỏ.
3.4. Tạo thư mục làm việc tạm
mkdir -p "$HOME/monitoring-install"
cd "$HOME/monitoring-install"
Các file tải về sẽ nằm tạm trong thư mục này. Sau khi cài xong có thể xóa.
4. Cài node_exporter trên Ubuntu 24.04
4.1. Tạo user riêng cho node_exporter
Không nên chạy node_exporter bằng root nếu không cần. Tạo system user riêng:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin node_exporter || true
Kiểm tra:
getent passwd node_exporter
4.2. Tải node_exporter binary
Tại thời điểm viết, node_exporter bản mới nhất trên trang download chính thức là 1.11.1. Nếu sau này có bản mới hơn, bạn có thể cập nhật biến NODE_EXPORTER_VERSION theo trang download chính thức.
cd "$HOME/monitoring-install"
export NODE_EXPORTER_VERSION="1.11.1"
export NODE_EXPORTER_ARCH="linux-amd64"
curl -LO "https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.${NODE_EXPORTER_ARCH}.tar.gz"
tar xzf "node_exporter-${NODE_EXPORTER_VERSION}.${NODE_EXPORTER_ARCH}.tar.gz"
sudo install -o root -g root -m 0755 \
"node_exporter-${NODE_EXPORTER_VERSION}.${NODE_EXPORTER_ARCH}/node_exporter" \
/usr/local/bin/node_exporter
Kiểm tra binary:
/usr/local/bin/node_exporter --version
4.3. Tạo systemd service cho node_exporter
Tạo file:
sudo nano /etc/systemd/system/node_exporter.service
Nội dung:
[Unit]
Description=Prometheus 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 \
--web.listen-address=127.0.0.1:9100 \
--collector.systemd \
--collector.processes \
--collector.filesystem.mount-points-exclude=^/(dev|proc|sys|run/credentials/.+|var/lib/docker/.+|var/lib/containers/storage/.+)($|/)
NoNewPrivileges=true
ProtectSystem=full
ProtectHome=true
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
Ở đây, node_exporter chỉ listen trên 127.0.0.1:9100, nghĩa là Prometheus trên cùng VPS có thể scrape, nhưng internet bên ngoài không truy cập trực tiếp được.
4.4. Bật và kiểm tra node_exporter
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
sudo systemctl status node_exporter --no-pager
Kiểm tra port:
sudo ss -ltnp | grep 9100 || true
Kết quả mong đợi là node_exporter listen trên:
127.0.0.1:9100
Kiểm tra metrics:
curl -s http://127.0.0.1:9100/metrics | head -n 30
Nếu thấy nhiều dòng metrics bắt đầu bằng # HELP, # TYPE và các metric như node_cpu_seconds_total, node_exporter đã hoạt động.
5. Cài Prometheus trên Ubuntu 24.04
5.1. Tạo user và thư mục cho Prometheus
sudo useradd --system --no-create-home --shell /usr/sbin/nologin prometheus || true
sudo mkdir -p /etc/prometheus
sudo mkdir -p /var/lib/prometheus
sudo chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus
Kiểm tra:
getent passwd prometheus
ls -ld /etc/prometheus /var/lib/prometheus
5.2. Tải Prometheus binary
Tại thời điểm viết, Prometheus bản mới nhất trên trang download chính thức là 3.11.3. Nếu sau này có bản mới hơn, bạn có thể cập nhật biến PROMETHEUS_VERSION theo trang download chính thức.
cd "$HOME/monitoring-install"
export PROMETHEUS_VERSION="3.11.3"
export PROMETHEUS_ARCH="linux-amd64"
curl -LO "https://github.com/prometheus/prometheus/releases/download/v${PROMETHEUS_VERSION}/prometheus-${PROMETHEUS_VERSION}.${PROMETHEUS_ARCH}.tar.gz"
tar xzf "prometheus-${PROMETHEUS_VERSION}.${PROMETHEUS_ARCH}.tar.gz"
sudo install -o root -g root -m 0755 \
"prometheus-${PROMETHEUS_VERSION}.${PROMETHEUS_ARCH}/prometheus" \
/usr/local/bin/prometheus
sudo install -o root -g root -m 0755 \
"prometheus-${PROMETHEUS_VERSION}.${PROMETHEUS_ARCH}/promtool" \
/usr/local/bin/promtool
sudo cp -r "prometheus-${PROMETHEUS_VERSION}.${PROMETHEUS_ARCH}/consoles" /etc/prometheus/
sudo cp -r "prometheus-${PROMETHEUS_VERSION}.${PROMETHEUS_ARCH}/console_libraries" /etc/prometheus/
sudo chown -R prometheus:prometheus /etc/prometheus
Kiểm tra version:
prometheus --version
promtool --version
5.3. Tạo file cấu hình Prometheus
Tạo file:
sudo nano /etc/prometheus/prometheus.yml
Nội dung:
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- /etc/prometheus/rules/*.yml
scrape_configs:
- job_name: prometheus
static_configs:
- targets:
- 127.0.0.1:9090
labels:
instance: vps-local
- job_name: node
static_configs:
- targets:
- 127.0.0.1:9100
labels:
instance: vps-local
Tạo thư mục rules:
sudo mkdir -p /etc/prometheus/rules
sudo chown -R prometheus:prometheus /etc/prometheus
Kiểm tra cú pháp:
promtool check config /etc/prometheus/prometheus.yml
5.4. Tạo systemd service cho Prometheus
Tạo file:
sudo nano /etc/systemd/system/prometheus.service
Nội dung:
[Unit]
Description=Prometheus Monitoring System
Wants=network-online.target
After=network-online.target node_exporter.service
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/var/lib/prometheus \
--storage.tsdb.retention.time=15d \
--storage.tsdb.retention.size=5GB \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries \
--web.listen-address=127.0.0.1:9090
NoNewPrivileges=true
ProtectHome=true
ProtectSystem=full
ReadWritePaths=/var/lib/prometheus
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
Hai tham số retention đáng chú ý:
--storage.tsdb.retention.time=15d: giữ dữ liệu 15 ngày.--storage.tsdb.retention.size=5GB: giới hạn dung lượng metrics khoảng 5GB.
Với VPS nhỏ, không nên giữ retention quá dài ngay từ đầu. Hãy theo dõi disk usage rồi tăng dần nếu cần.
5.5. Bật và kiểm tra Prometheus
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
sudo systemctl status prometheus --no-pager
Kiểm tra port:
sudo ss -ltnp | grep 9090 || true
Kết quả mong đợi:
127.0.0.1:9090
Kiểm tra API local:
curl -s http://127.0.0.1:9090/-/ready
curl -s http://127.0.0.1:9090/api/v1/targets | head
Nếu /-/ready trả về Prometheus Server is Ready., Prometheus đã chạy.
6. Kiểm tra metrics bằng PromQL cơ bản
6.1. Kiểm tra target up
curl -s 'http://127.0.0.1:9090/api/v1/query?query=up' | python3 -m json.tool
Kết quả nên có prometheus và node với value 1. Nếu target node là 0, Prometheus không scrape được node_exporter.
6.2. Một số PromQL hữu ích
CPU usage gần đúng:
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
RAM available:
node_memory_MemAvailable_bytes
RAM usage theo phần trăm:
100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))
Disk free phần trăm cho root filesystem:
100 * (node_filesystem_avail_bytes{mountpoint="/",fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{mountpoint="/",fstype!~"tmpfs|overlay"})
Load average 1 phút:
node_load1
Network receive:
rate(node_network_receive_bytes_total{device!~"lo"}[5m])
Network transmit:
rate(node_network_transmit_bytes_total{device!~"lo"}[5m])
6.3. Truy cập Prometheus UI bằng SSH tunnel
Từ máy cá nhân, mở tunnel:
ssh -L 9090:127.0.0.1:9090 admin@SERVER_IP
Sau đó mở trình duyệt trên máy cá nhân:
http://127.0.0.1:9090
Vào menu Status → Targets để kiểm tra target prometheus và node có trạng thái UP hay không.
Không mở port 9090 public nếu chưa có lớp bảo vệ phù hợp.
7. Cài Grafana trên Ubuntu 24.04
7.1. Cài Grafana bằng APT repository chính thức
Cài package phụ thuộc:
sudo apt-get install -y apt-transport-https wget gnupg
Thêm key và repository Grafana:
sudo mkdir -p /etc/apt/keyrings
sudo wget -O /etc/apt/keyrings/grafana.asc https://apt.grafana.com/gpg-full.key
sudo chmod 644 /etc/apt/keyrings/grafana.asc
echo "deb [signed-by=/etc/apt/keyrings/grafana.asc] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
Cài Grafana OSS:
sudo apt-get update
sudo apt-get install -y grafana
Bật service:
sudo systemctl enable --now grafana-server
sudo systemctl status grafana-server --no-pager
7.2. Bind Grafana vào localhost
Mặc định Grafana thường listen trên port 3000. Với VPS nhỏ, nên bind vào 127.0.0.1 để không public dashboard.
Mở file cấu hình:
sudo nano /etc/grafana/grafana.ini
Tìm hoặc thêm các dòng sau trong block [server]:
[server]
http_addr = 127.0.0.1
http_port = 3000
Trong block [analytics], có thể tắt reporting nếu muốn:
[analytics]
reporting_enabled = false
Restart Grafana:
sudo systemctl restart grafana-server
sudo systemctl status grafana-server --no-pager
Kiểm tra port:
sudo ss -ltnp | grep 3000 || true
Kết quả mong đợi:
127.0.0.1:3000
7.3. Truy cập Grafana bằng SSH tunnel
Từ máy cá nhân:
ssh -L 3000:127.0.0.1:3000 admin@SERVER_IP
Sau đó mở trình duyệt:
http://127.0.0.1:3000
Đăng nhập lần đầu, đổi mật khẩu admin ngay nếu Grafana yêu cầu. Không dùng mật khẩu yếu cho dashboard monitoring.
7.4. Thêm Prometheus data source trong Grafana
Trong Grafana UI:
- Vào Connections hoặc Data sources.
- Chọn Add data source.
- Chọn Prometheus.
- URL nhập:
http://127.0.0.1:9090. - Bấm Save & Test.
Nếu test thành công, Grafana đã kết nối được Prometheus.
8. Tạo dashboard monitoring VPS
8.1. Dùng dashboard có sẵn hay tự tạo?
Với người mới, có thể import dashboard node_exporter có sẵn để xem nhanh. Nhưng vẫn nên tự tạo vài panel cơ bản để hiểu PromQL và hiểu số liệu đang nhìn.
Dashboard tối thiểu nên có:
- CPU usage.
- Load average.
- RAM usage.
- Swap usage.
- Disk free.
- Disk read/write.
- Network receive/transmit.
- Uptime.
- Target up/down.
8.2. Panel CPU usage
PromQL:
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
Gợi ý visualization: Time series, unit percent.
Cách đọc: nếu CPU usage thường xuyên cao hơn 80-90% trong thời gian dài, cần kiểm tra process, PHP-FPM, database, bot traffic hoặc job nền.
8.3. Panel RAM usage
PromQL:
100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))
Gợi ý visualization: Gauge hoặc Time series, unit percent.
Không nên chỉ nhìn RAM used theo kiểu free -h rồi hoảng vì Linux dùng RAM cho cache. Chỉ số MemAvailable thường hữu ích hơn để biết hệ thống còn bao nhiêu RAM có thể dùng.
8.4. Panel swap usage
PromQL:
100 * (1 - (node_memory_SwapFree_bytes / node_memory_SwapTotal_bytes))
Nếu VPS không có swap, panel có thể không có dữ liệu hoặc cần xử lý thêm. Swap tăng bất thường thường là dấu hiệu RAM thiếu hoặc process bị rò bộ nhớ.
8.5. Panel disk free
PromQL:
100 * (node_filesystem_avail_bytes{mountpoint="/",fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{mountpoint="/",fstype!~"tmpfs|overlay"})
Gợi ý visualization: Gauge, unit percent.
Disk là chỉ số phải theo dõi nghiêm túc. Khi disk đầy 100%, database có thể lỗi, log không ghi được, backup fail, Certbot renew fail và app có thể sập.
8.6. Panel network receive/transmit
Receive:
rate(node_network_receive_bytes_total{device!~"lo"}[5m])
Transmit:
rate(node_network_transmit_bytes_total{device!~"lo"}[5m])
Gợi ý visualization: Time series, unit bytes/sec.
Network spike có thể đến từ traffic thật, bot scan, backup chạy, upload/download lớn hoặc bị lạm dụng tài nguyên.
8.7. Panel uptime
PromQL:
time() - node_boot_time_seconds
Gợi ý visualization: Stat, unit seconds hoặc duration.
Uptime giúp phát hiện server vừa reboot. Nếu VPS reboot mà bạn không biết lý do, hãy kiểm tra journal, provider event, kernel update hoặc OOM.
8.8. Panel target up/down
PromQL:
up
Target 1 nghĩa là scrape thành công. Target 0 nghĩa là Prometheus không scrape được exporter hoặc endpoint tương ứng.
9. Tạo alert rules cơ bản trong Prometheus
9.1. Alert rule không đồng nghĩa với gửi thông báo
Prometheus có thể đánh giá alert rules và hiển thị trạng thái alert trong UI. Để gửi thông báo qua email, Telegram, Slack hoặc webhook, bạn cần cấu hình thêm Alertmanager hoặc dùng Grafana Alerting.
Trong bài này, alert rules được tạo để giúp bạn học cách định nghĩa điều kiện cảnh báo. Phần notification đầy đủ nên triển khai sau khi bạn hiểu rõ metric và tránh alert noise.
9.2. Tạo file alert rules
Tạo file:
sudo nano /etc/prometheus/rules/node-basic.yml
Nội dung:
groups:
- name: node-basic
rules:
- alert: InstanceDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Target is down"
description: "Prometheus target {{ $labels.job }} on {{ $labels.instance }} is down."
- alert: DiskLowRoot
expr: 100 * (node_filesystem_avail_bytes{mountpoint="/",fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{mountpoint="/",fstype!~"tmpfs|overlay"}) < 15
for: 10m
labels:
severity: warning
annotations:
summary: "Root filesystem is low"
description: "Root filesystem on {{ $labels.instance }} has less than 15% available."
- alert: MemoryHigh
expr: 100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) > 90
for: 10m
labels:
severity: warning
annotations:
summary: "Memory usage is high"
description: "Memory usage on {{ $labels.instance }} is above 90% for 10 minutes."
- alert: LoadHigh
expr: node_load1 / count without (cpu, mode) (node_cpu_seconds_total{mode="idle"}) > 2
for: 10m
labels:
severity: warning
annotations:
summary: "Load average is high"
description: "Load average on {{ $labels.instance }} is high compared to CPU count."
Kiểm tra:
sudo chown -R prometheus:prometheus /etc/prometheus/rules
promtool check rules /etc/prometheus/rules/node-basic.yml
promtool check config /etc/prometheus/prometheus.yml
Reload Prometheus:
sudo systemctl reload prometheus || sudo systemctl restart prometheus
Kiểm tra log:
sudo journalctl -u prometheus --since "10 minutes ago" --no-pager
9.3. Xem alert trong Prometheus UI
Mở SSH tunnel đến Prometheus:
ssh -L 9090:127.0.0.1:9090 admin@SERVER_IP
Truy cập:
http://127.0.0.1:9090/alerts
Nếu rule hợp lệ, bạn sẽ thấy danh sách alert. Có thể trạng thái là inactive nếu server đang khỏe.
9.4. Tránh alert noise
Alert quá nhạy sẽ làm bạn bỏ qua cảnh báo thật. Một vài nguyên tắc nên nhớ:
- Không alert mọi spike ngắn vài giây.
- Dùng
forđể yêu cầu điều kiện kéo dài một thời gian. - Alert theo triệu chứng người dùng quan tâm, không alert mọi chỉ số nội bộ.
- Disk thấp, instance down, backup fail thường quan trọng hơn CPU spike ngắn.
- Dashboard để quan sát; alert để hành động.
10. Bảo mật Prometheus và Grafana
10.1. Kiểm tra không public port monitoring
sudo ss -ltnp | grep -E '3000|9090|9100' || true
Kết quả mong đợi:
127.0.0.1:3000
127.0.0.1:9090
127.0.0.1:9100
Nếu thấy 0.0.0.0:3000, 0.0.0.0:9090 hoặc 0.0.0.0:9100, nghĩa là service đang listen trên mọi interface. Hãy sửa lại cấu hình trước khi đưa server ra production.
10.2. Không mở UFW cho monitoring khi chưa cần
sudo ufw status verbose
Không nên có rule public cho:
3000/tcpnếu Grafana chưa được bảo vệ đúng.9090/tcpnếu Prometheus chưa có authentication/reverse proxy.9100/tcpvì node_exporter không nên public.
10.3. Khi nào mới nên public Grafana?
Chỉ nên public Grafana nếu bạn có một thiết kế bảo mật rõ ràng:
- HTTPS bằng Let’s Encrypt.
- Nginx reverse proxy.
- Mật khẩu mạnh và đổi mật khẩu admin mặc định.
- Allowlist IP hoặc VPN nếu có thể.
- Không public Prometheus/node_exporter trực tiếp.
- Backup cấu hình Grafana.
Với VPS cá nhân, SSH tunnel vẫn là cách đơn giản và an toàn hơn nhiều.
10.4. Backup cấu hình monitoring
Sau khi cấu hình xong, hãy đảm bảo backup ở bài C3 có bao gồm:
/etc/prometheus/
/etc/systemd/system/prometheus.service
/etc/systemd/system/node_exporter.service
/etc/grafana/
/var/lib/grafana/
Prometheus metrics có thể không cần backup dài hạn với VPS nhỏ, nhưng dashboard Grafana, data source và cấu hình monitoring nên được giữ lại.
11. Vận hành monitoring hằng ngày
11.1. Kiểm tra service
sudo systemctl status node_exporter --no-pager
sudo systemctl status prometheus --no-pager
sudo systemctl status grafana-server --no-pager
Nếu service restart liên tục, đọc journal:
sudo journalctl -u node_exporter --since "1 hour ago" --no-pager
sudo journalctl -u prometheus --since "1 hour ago" --no-pager
sudo journalctl -u grafana-server --since "1 hour ago" --no-pager
11.2. Kiểm tra target Prometheus
curl -s http://127.0.0.1:9090/api/v1/targets | python3 -m json.tool | head -n 80
Hoặc dùng UI:
http://127.0.0.1:9090/targets
Target phải ở trạng thái UP. Nếu DOWN, kiểm tra exporter, port, config và log.
11.3. Kiểm tra dung lượng Prometheus
sudo du -sh /var/lib/prometheus
df -h
Nếu Prometheus dùng quá nhiều disk, giảm retention hoặc kiểm tra số target/scrape interval. Với VPS nhỏ, giữ 15 ngày là mức hợp lý để bắt đầu.
11.4. Tạo script kiểm tra monitoring nhanh
Tạo file:
sudo nano /usr/local/sbin/monitoring-quick-status.sh
Nội dung:
#!/usr/bin/env bash
set -euo pipefail
echo "== Services =="
systemctl --no-pager --full status node_exporter prometheus grafana-server || true
echo
echo "== Listening ports =="
ss -ltnp | grep -E '3000|9090|9100' || true
echo
echo "== Prometheus ready =="
curl -fsS http://127.0.0.1:9090/-/ready || true
echo
echo
echo "== Prometheus targets =="
curl -fsS 'http://127.0.0.1:9090/api/v1/query?query=up' | python3 -m json.tool || true
echo
echo "== Prometheus disk usage =="
du -sh /var/lib/prometheus 2>/dev/null || true
Cấp quyền:
sudo chmod +x /usr/local/sbin/monitoring-quick-status.sh
Chạy:
sudo monitoring-quick-status.sh
12. Mở rộng monitoring sau khi nền đã ổn
12.1. Thêm Blackbox exporter để kiểm tra website từ góc nhìn HTTP
node_exporter cho biết server khỏe hay không, nhưng không trả lời đầy đủ câu hỏi website có truy cập được từ HTTP/HTTPS hay không. Sau này, bạn có thể thêm Blackbox exporter để kiểm tra:
- Website trả HTTP 200 hay không.
- HTTPS certificate có hợp lệ không.
- DNS resolve có ổn không.
- Endpoint
/healthzcó hoạt động không.
Đây là phần rất hợp sau bài B5 và B6, nơi bạn đã có app demo và HTTPS.
12.2. Thêm mysqld_exporter cho MariaDB/MySQL
node_exporter chỉ nhìn hệ thống Linux, không nhìn sâu vào database. Nếu website phụ thuộc nhiều vào MariaDB/MySQL, bạn có thể thêm mysqld_exporter để theo dõi:
- Connections.
- Queries.
- Slow queries.
- InnoDB metrics.
- Replication nếu có.
Không nên thêm quá nhiều exporter ngay ngày đầu. Hãy để node_exporter chạy ổn trước, rồi mở rộng từng lớp.
12.3. Thêm Nginx metrics
Nginx có thể expose basic status hoặc dùng exporter để đưa metrics vào Prometheus. Những chỉ số hữu ích gồm request rate, active connections, status code, upstream time nếu có log-based exporter.
Tuy nhiên, nếu bạn chưa chuẩn hóa log format ở bài B7, nên làm phần log trước khi đi sâu vào Nginx monitoring.
12.4. Thêm notification bằng Alertmanager hoặc Grafana Alerting
Prometheus alert rule chỉ thật sự hữu ích khi có notification. Có hai hướng phổ biến:
- Dùng Alertmanager trong hệ Prometheus.
- Dùng Grafana Alerting nếu bạn muốn quản lý cảnh báo trong Grafana.
Với người mới, hãy bắt đầu bằng vài alert ít noise: instance down, disk thấp, backup fail, certificate gần hết hạn. Đừng tạo quá nhiều cảnh báo ngay từ đầu.
13. Lỗi thường gặp khi cài Prometheus, node_exporter và Grafana
13.1. Prometheus không scrape được node_exporter
Kiểm tra node_exporter:
sudo systemctl status node_exporter --no-pager
curl -I http://127.0.0.1:9100/metrics
Kiểm tra Prometheus config:
promtool check config /etc/prometheus/prometheus.yml
sudo journalctl -u prometheus --since "30 minutes ago" --no-pager
Nguyên nhân thường gặp:
- node_exporter chưa chạy.
- Sai port trong
prometheus.yml. - Prometheus chưa reload config.
- YAML sai indent.
13.2. Grafana không kết nối được Prometheus
Kiểm tra Prometheus local:
curl -s http://127.0.0.1:9090/-/ready
Trong Grafana data source, URL nên là:
http://127.0.0.1:9090
Vì Grafana và Prometheus cùng chạy trên VPS, URL này được Grafana server dùng từ phía backend, không phải URL từ trình duyệt người dùng.
13.3. Không truy cập được Grafana từ trình duyệt
Kiểm tra Grafana listen local:
sudo ss -ltnp | grep 3000
sudo systemctl status grafana-server --no-pager
Mở SSH tunnel từ máy cá nhân:
ssh -L 3000:127.0.0.1:3000 admin@SERVER_IP
Sau đó truy cập:
http://127.0.0.1:3000
Nếu vẫn không được, kiểm tra firewall local trên máy cá nhân, SSH config và log Grafana.
13.4. Prometheus dùng disk quá nhanh
Kiểm tra:
sudo du -sh /var/lib/prometheus
df -h
Giảm retention trong systemd service:
--storage.tsdb.retention.time=7d
--storage.tsdb.retention.size=2GB
Sau đó reload systemd và restart Prometheus:
sudo systemctl daemon-reload
sudo systemctl restart prometheus
Nếu vẫn tăng nhanh, kiểm tra số target, scrape interval và exporter có tạo quá nhiều time series không.
13.5. YAML Prometheus bị lỗi indent
YAML rất nhạy với khoảng trắng. Luôn kiểm tra:
promtool check config /etc/prometheus/prometheus.yml
promtool check rules /etc/prometheus/rules/node-basic.yml
Không restart Prometheus nếu promtool đang báo lỗi.
13.6. node_exporter public ra internet
Kiểm tra:
sudo ss -ltnp | grep 9100
Nếu thấy:
0.0.0.0:9100
hãy sửa lại systemd unit:
--web.listen-address=127.0.0.1:9100
Rồi restart:
sudo systemctl daemon-reload
sudo systemctl restart node_exporter
13.7. Dashboard đẹp nhưng không có hành động
Đây là lỗi vận hành phổ biến. Dashboard nhiều panel nhưng không có checklist phản ứng thì vẫn chưa đủ.
Ví dụ:
- Disk dưới 15% thì làm gì?
- Memory trên 90% thì kiểm tra process nào?
- Load cao thì xem Nginx, PHP-FPM hay database trước?
- Target down thì restart service hay kiểm tra config?
Monitoring tốt phải nối với playbook xử lý sự cố. Bài C7 sẽ đi sâu hơn phần này.
14. Checklist monitoring nền
14.1. Checklist cài đặt
- node_exporter đã chạy bằng user riêng.
- node_exporter chỉ listen trên
127.0.0.1:9100. - Prometheus đã chạy bằng user riêng.
- Prometheus chỉ listen trên
127.0.0.1:9090. - Grafana đã chạy và chỉ listen trên
127.0.0.1:3000. - Không mở public các port
3000,9090,9100.
14.2. Checklist Prometheus
promtool check configthành công.- Target
prometheusUP. - Target
nodeUP. - Retention time/size phù hợp với dung lượng VPS.
- Alert rules cơ bản không lỗi cú pháp.
/var/lib/prometheuskhông tăng dung lượng bất thường.
14.3. Checklist Grafana
- Truy cập Grafana qua SSH tunnel thành công.
- Đã đổi mật khẩu admin nếu cần.
- Prometheus data source
Save & Testthành công. - Dashboard có CPU, RAM, disk, network, uptime.
- Dashboard không chỉ đẹp mà có chỉ số phục vụ vận hành.
14.4. Checklist vận hành
- Biết kiểm tra service bằng
systemctl status. - Biết xem log bằng
journalctl. - Biết kiểm tra target trong Prometheus.
- Biết kiểm tra disk usage của Prometheus.
- Biết mở SSH tunnel khi cần xem dashboard.
- Biết các ngưỡng cơ bản: disk thấp, RAM cao, load cao, target down.
15. FAQ
15.1. Có cần monitoring nếu chỉ có một VPS nhỏ không?
Có. Một VPS nhỏ càng dễ bị ảnh hưởng bởi disk đầy, RAM thiếu, bot traffic hoặc backup fail. Monitoring không cần quá phức tạp, nhưng nên có ít nhất CPU, RAM, disk, network và uptime.
15.2. Có nên mở Grafana public không?
Không nên mở public ngay từ đầu. Với VPS cá nhân, SSH tunnel là cách đơn giản và an toàn hơn. Chỉ public Grafana khi bạn đã có HTTPS, authentication mạnh, allowlist IP hoặc VPN/Zero Trust.
15.3. Prometheus có thay thế log không?
Không. Prometheus lưu metrics, không thay thế log chi tiết. Khi thấy CPU cao hoặc target down trong Prometheus, bạn vẫn cần đọc Nginx log, PHP-FPM log, MariaDB log hoặc journal để điều tra nguyên nhân.
15.4. node_exporter có làm server chậm không?
Với cấu hình mặc định hợp lý, node_exporter rất nhẹ. Prometheus và Grafana mới là phần cần theo dõi dung lượng và RAM nhiều hơn. Với VPS nhỏ, hãy giữ scrape interval và retention vừa phải.
15.5. Nên giữ Prometheus metrics bao lâu?
Với VPS nhỏ, bắt đầu với 7-15 ngày là hợp lý. Nếu disk dư và cần xem xu hướng dài hơn, có thể tăng retention. Nếu cần lưu dài hạn nghiêm túc, nên dùng remote storage hoặc giải pháp chuyên biệt.
15.6. Có nên dùng Grafana Cloud thay vì tự host Grafana?
Có thể. Grafana Cloud hoặc dịch vụ monitoring bên ngoài giúp tách monitoring khỏi VPS chính và dễ nhận alert hơn. Tuy nhiên, tự host Prometheus + Grafana là cách rất tốt để học nền tảng và hiểu metrics trước.
15.7. Sau bài này nên học gì tiếp?
Sau khi có monitoring nền, bước tiếp theo nên là logging và rotation. Metrics cho bạn biết vấn đề đang xảy ra ở đâu và khi nào; logs giúp bạn điều tra vì sao nó xảy ra.
16. Kết luận
Monitoring VPS Ubuntu 24.04 là bước chuyển từ vận hành bị động sang vận hành có số liệu. Khi có Prometheus, node_exporter và Grafana, bạn không cần đoán server đang thiếu RAM, đầy disk hay CPU cao nữa. Bạn có thể nhìn biểu đồ, truy vấn PromQL, kiểm tra target và phát hiện xu hướng trước khi sự cố lớn hơn xảy ra.
Trong bài này, bạn đã dựng một monitoring stack tối thiểu nhưng thực dụng: node_exporter xuất metrics hệ thống, Prometheus scrape và lưu time series, Grafana hiển thị dashboard, tất cả đều bind vào localhost để tránh public bề mặt tấn công. Bạn cũng đã có alert rules cơ bản, checklist vận hành và các lệnh kiểm tra khi service hoặc target gặp lỗi.
Từ đây, VPS của bạn đã có nền tốt hơn để đi tiếp sang logging, tuning hiệu năng và troubleshooting playbook. Backup giúp bạn có đường lui, monitoring giúp bạn thấy vấn đề sớm, còn logging sẽ giúp bạn đào sâu nguyên nhân khi sự cố thật sự xảy ra.

