Prometheus + Grafana 監控系統搭建實戰 2026

📊 為什麼需要監控? 你花幾小時搭好的代理服務、博客、數據庫,一旦半夜掛掉,沒有監控你根本不知道。等到第二天用戶來反饋,黃金恢復時間早就錯過了。Prometheus + Grafana 是業界標準的開源監控組合——一個負責採集存儲指標,一個負責可視化告警,配合起來幾乎零成本就能擁有企業級監控能力。
本文將帶你從零搭建一套完整的 VPS 監控系統:
- ✅ 監控 vs 告警:為什麼兩者缺一不可
- ✅ Prometheus 核心原理(時序數據庫 / Pull 模型 / Exporter)
- ✅ Node Exporter 採集 CPU/內存/磁盤/網絡
- ✅ Docker Compose 一鍵部署整套監控棧
- ✅ Grafana 看板導入與自定義
- ✅ Alertmanager 郵件 / Telegram 告警
- ✅ Nginx、SSL 證書、網站可用性進階監控
- ✅ 多 VPS 集中管控與常見問題
一、為什麼需要 VPS 監控
1.1 典型痛點
| 痛點 | 沒有監控 | 有監控 |
|---|---|---|
| 服務宕機 | 用戶反饋才知道 | 告警秒級推送 |
| 磁盤寫滿 | 數據庫崩潰才發現 | 80% 容量就預警 |
| 流量異常 | 月底才發現被刷 | 實時流量曲線可見 |
| 性能劣化 | 憑感覺優化 | 數據驅動定位瓶頸 |
| 安全入侵 | 事後溯源困難 | 異常進程/連接立即可見 |
1.2 監控 vs 告警
很多人把監控等同於「看個圖表」,這是片面的。兩者職責不同:
- 監控(Monitoring):持續採集指標、可視化展示,讓你「看得見」系統狀態。
- 告警(Alerting):當指標突破閾值時主動通知你,讓你「被提醒」。
💡 只有看板沒有告警,等於裝了攝像頭卻沒人看;只有告警沒有看板,出問題了卻沒法分析原因。兩者必須配套。
1.3 開源方案對比
| 方案 | 組成 | 優點 | 缺點 | 適用 |
|---|---|---|---|---|
| Prometheus + Grafana | 採集+可視化 | 生態最完善、查詢強大、免費 | 組件稍多 | 通用首選 |
| Zabbix | 一體化 | 開箱即用、Agent 豐富 | 配置偏重、UI 老舊 | 傳統企業 |
| Netdata | 一體化 | 安裝極簡、實時性強 | 長期存儲弱、定製差 | 單機快速看 |
| Nagios | 告警為主 | 告警邏輯成熟 | 可視化弱、配置繁瑣 | 純告警場景 |
| VictoriaMetrics | 替代 Prometheus | 性能更高、存儲更省 | 生態較新 | 超大規模 |
結論: 個人 VPS / 中小團隊首選 Prometheus + Grafana,生態成熟、資料多、遷移成本低。
二、Prometheus 核心原理
2.1 時序數據庫(TSDB)
Prometheus 存儲的是時序數據——帶時間戳的指標序列:
<指標名>{<標籤1>=<值1>, <標籤2>=<值2>} <數值> <時間戳>
node_memory_MemAvailable_bytes{instance="server-1:9100", job="node"} 3.2e+09 1750000000- 指標名:如
node_cpu_seconds_total - 標籤(Label):區分維度,如
instance、job、mode - 數值:浮點數
- 時間戳:毫秒級
2.2 Pull 模型
Prometheus 採用主動拉取(Pull)模式:服務端定時去各 Exporter 的 HTTP 接口抓取指標。
Prometheus Server
│ (每 15s 拉取 /metrics)
├──> Node Exporter :9100/metrics
├──> Nginx Exporter :9113/metrics
└──> Blackbox Exporter :9115/metricsPull vs Push 對比:
| 維度 | Pull(Prometheus) | Push(如 StatsD) |
|---|---|---|
| 服務發現 | 天然支持 | 需額外註冊 |
| 故障定位 | 誰掛了一目瞭然 | 推送失敗難排查 |
| 防火牆 | 服務端主動出 | 客戶端主動出 |
| 短任務 | 需 Pushgateway 中轉 | 天然支持 |
2.3 Exporter 生態
Exporter 是「指標翻譯器」,把各系統的內部狀態暴露成 Prometheus 格式:
| Exporter | 監控對象 |
|---|---|
| Node Exporter | 主機 CPU/內存/磁盤/網絡 |
| cAdvisor | Docker 容器 |
| Nginx Exporter | Nginx 連接/請求 |
| MySQL Exporter | 數據庫狀態 |
| Blackbox Exporter | HTTP/DNS/TCP 探測 |
| Redis Exporter | 緩存狀態 |
| Process Exporter | 指定進程 |
三、Node Exporter 部署
3.1 Docker 方式
docker run -d \
--name node-exporter \
--restart=always \
--network host \
--pid host \
-v "/proc:/host/proc:ro" \
-v "/sys:/host/sys:ro" \
-v "/:/rootfs:ro" \
prom/node-exporter:latest \
--path.procfs=/host/proc \
--path.sysfs=/host/sys \
--path.rootfs=/rootfs3.2 二進制方式(Systemd)
# 下載
cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xzf node_exporter-1.8.2.linux-amd64.tar.gz
sudo cp node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/
# 創建 systemd 服務
sudo tee /etc/systemd/system/node-exporter.service > /dev/null <<'EOF'
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=node_exporter
ExecStart=/usr/local/bin/node_exporter
Restart=always
[Install]
WantedBy=multi-user.target
EOF
# 創建專用用戶並啟動
sudo useradd -rs /bin/false node_exporter
sudo systemctl daemon-reload
sudo systemctl enable --now node-exporter3.3 驗證指標
curl http://localhost:9100/metrics | head -20
# 應看到 node_cpu_seconds_total、node_memory_MemAvailable_bytes 等指標3.4 安全加固(重要)
Node Exporter 默認無認證,切勿直接暴露公網。推薦用 Nginx 反向代理 + Basic Auth 或僅監聽內網:
# /etc/nginx/conf.d/node-exporter.conf
location /metrics {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://127.0.0.1:9100;
}四、Prometheus 服務端部署
4.1 Docker Compose 完整配置
創建 docker-compose.yml:
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: always
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=30d'
- '--web.enable-lifecycle'
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: always
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=your_strong_password
volumes:
- grafana_data:/var/lib/grafana
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
restart: always
network_mode: host
pid: host
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
volumes:
prometheus_data:
grafana_data:4.2 Prometheus 配置文件
prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
# 監控 Prometheus 自己
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# 監控本機
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
labels:
instance: 'server-main'
# 監控另一臺 VPS(通過內網/隧道 IP)
- job_name: 'node-remote'
static_configs:
- targets: ['10.0.0.2:9100']
labels:
instance: 'server-edge'4.3 數據保留與性能
| 參數 | 說明 | 建議 |
|---|---|---|
retention.time | 數據保留時長 | 15~30d(個人) |
retention.size | 數據體積上限 | 如 2GB 防止寫滿磁盤 |
wal-compression | WAL 壓縮 | 開啟節省空間 |
磁盤佔用估算:
每目標 ≈ 1~2 MB/天(默認採集頻率)
30 天 × 5 目標 ≈ 150~300 MB4.4 啟動與驗證
docker compose up -d
# 訪問 http://你的IP:9090
# 在 Graph 頁面執行: up → 應看到所有 target 的 up=1五、Grafana 可視化
5.1 首次登錄
地址: http://你的IP:3000
默認賬號: admin / admin(首次登錄強制改密碼)5.2 添加 Prometheus 數據源
- 左側菜單 Connections → Data sources → Add data source
- 選擇 Prometheus
- URL 填
http://prometheus:9090(同一 Docker 網絡用服務名) - 點擊 Save & test,顯示綠色對勾即成功
5.3 導入 Node Exporter 看板
Grafana 社區有成熟的現成看板,無需從零畫:
- 左側 Dashboards → New → Import
- 輸入官方 Dashboard ID:1860(Node Exporter Full)或 8919(新版)
- 選擇剛才添加的 Prometheus 數據源
- 點擊 Import
💡 推薦常用 Dashboard ID:
- 1860 — Node Exporter Full(主機監控經典)
- 11074 — Node Exporter 輕量版
- 893 — 主機硬件溫度(需額外 exporter)
5.4 核心指標 PromQL 查詢
如果你想自己畫面板,以下是常用查詢:
# CPU 使用率(非 idle)
100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 內存使用率
100 * (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)
# 磁盤使用率(根分區)
100 * (1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})
# 網絡流入速率(Mbps)
rate(node_network_receive_bytes_total{device="eth0"}[5m]) * 8 / 1024 / 1024
# 1 分鐘負載
node_load1 / count by(instance)(node_cpu_seconds_total{mode="idle"})六、核心 Dashboard 構建
6.1 推薦面板佈局
| 行 | 面板 | 指標 |
|---|---|---|
| 概覽 | 系統狀態總覽 | up |
| CPU | 使用率 / 核心分佈 | node_cpu_seconds_total |
| 內存 | 已用 / 可用 / Swap | node_memory_* |
| 磁盤 | 分區使用率 / IO 速率 | node_filesystem_* / node_disk_* |
| 網絡 | 入站 / 出站流量 | node_network_* |
| 進程 | 運行進程數 / 負載 | node_procs_running / node_load* |
6.2 示例面板 JSON 片段
Grafana 面板是 JSON 結構,以下是一個「CPU 使用率」面板核心字段:
{
"title": "CPU 使用率",
"type": "timeseries",
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
"targets": [
{
"expr": "100 - (avg by(instance)(rate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100)",
"legendFormat": "{{instance}}"
}
],
"fieldConfig": {
"defaults": {
"unit": "percent",
"max": 100
}
}
}6.3 閾值與單位
Grafana 支持在面板中設置閾值變色:
| 指標 | 單位 | 警告閾值 | 嚴重閾值 |
|---|---|---|---|
| CPU 使用率 | % | 70 | 90 |
| 內存使用率 | % | 80 | 95 |
| 磁盤使用率 | % | 80 | 90 |
| 網絡流量 | MB/s | 按帶寬定 | — |
七、告警規則配置
7.1 告警規則文件
alerts.yml:
groups:
- name: node-alerts
rules:
- alert: 實例宕機
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }} 已離線"
description: "實例 {{ $labels.instance }} 持續 1 分鐘無法抓取"
- alert: 高CPU使用率
expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
for: 5m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} CPU 過高"
description: "CPU 使用率持續 5 分鐘超過 85%"
- alert: 磁盤即將寫滿
expr: 100 * (1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) > 85
for: 5m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} 磁盤空間不足"
description: "根分區使用率超過 85%"
- alert: 內存不足
expr: 100 * (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) > 90
for: 5m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} 內存緊張"
description: "內存使用率超過 90%"在 prometheus.yml 中引用:
rule_files:
- /etc/prometheus/alerts.yml7.2 Alertmanager 部署
# 在 docker-compose.yml 中追加
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
restart: always
ports:
- "9093:9093"
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
command:
- '--config.file=/etc/alertmanager/alertmanager.yml'prometheus.yml 添加告警路由:
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']7.3 郵件告警通道
alertmanager.yml:
global:
smtp_smarthost: 'smtp.gmail.com:587'
smtp_from: 'monitor@gmail.com'
smtp_auth_username: 'monitor@gmail.com'
smtp_auth_password: '應用專用密碼'
smtp_require_tls: true
route:
receiver: 'email-alert'
group_by: ['alertname', 'instance']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receivers:
- name: 'email-alert'
email_configs:
- to: 'admin@example.com'
subject: '[監控告警] {{ .CommonAnnotations.summary }}'
body: |
告警: {{ .CommonAnnotations.summary }}
詳情: {{ .CommonAnnotations.description }}
時間: {{ .StartsAt }}7.4 Telegram 告警通道
Telegram 更適合移動端即時推送。先找 @BotFather 創建 Bot 獲取 Token,再找 @userinfobot 獲取 Chat ID。
receivers:
- name: 'telegram-alert'
telegram_configs:
- bot_token: '你的BOT_TOKEN'
chat_id: '你的CHAT_ID'
message: |
🔥 *{{ .CommonAnnotations.summary }}*
{{ .CommonAnnotations.description }}
🖥 實例: {{ .CommonLabels.instance }}八、進階監控
8.1 Nginx 訪問統計
啟用 Nginx stub_status,再用 nginx-prometheus-exporter 採集:
# nginx.conf
location /nginx_status {
stub_status on;
allow 127.0.0.1;
deny all;
}docker run -d --name nginx-exporter \
-p 9113:9113 \
nginx/nginx-prometheus-exporter:latest \
-nginx.scrape-uri=http://你的IP/nginx_statusPrometheus 添加 job:
- job_name: 'nginx'
static_configs:
- targets: ['nginx-exporter:9113']看板 ID:11199(Nginx 請求/連接/狀態碼)。
8.2 SSL 證書過期監控
用 Blackbox Exporter 探測 HTTPS 並解析證書剩餘天數:
# blackbox.yml
modules:
https:
prober: http
http:
preferred_ip_protocol: ip4
tls: truePrometheus 添加探測 job:
- job_name: 'ssl-check'
metrics_path: /probe
params:
module: [https]
static_configs:
- targets:
- https://y-m.top
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox-exporter:9115證書剩餘天數告警:
- alert: SSL證書即將過期
expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 14
for: 1h
labels:
severity: warning
annotations:
summary: "SSL 證書將在 14 天內過期"
description: "域名 {{ $labels.instance }} 證書剩餘不足 14 天"8.3 網站可用性探測
Blackbox Exporter 還能探測網站是否可訪問、響應時間:
- alert: 網站不可達
expr: probe_success{job="blackbox-http"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }} 訪問失敗"
description: "HTTP 探測連續失敗超過 2 分鐘" - alert: 響應過慢
expr: probe_duration_seconds{job="blackbox-http"} > 3
for: 5m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} 響應緩慢"
description: "HTTP 響應時間持續超過 3 秒"九、常見問題
Q1:Prometheus 內存佔用過高怎麼辦?
- 調低採集頻率:
scrape_interval從 15s 調到 30s 或 60s - 減少目標數量:只為關鍵服務建 job
- 限制數據保留:
--storage.tsdb.retention.time=15d - 設置數據體積上限:
--storage.tsdb.retention.size=2GB - 給容器限制內存:
deploy.resources.limits.memory: 1g
Q2:數據存哪裡?會不會寫滿磁盤?
默認存在 Docker 卷 prometheus_data(映射在 /var/lib/docker/volumes/)。務必設置 retention.size 上限,並監控宿主機磁盤。建議單獨掛一塊盤或定期備份:
# 手動備份(停止容器後)
docker run --rm -v prometheus_data:/data -v $(pwd):/backup alpine \
tar czf /backup/prometheus-backup.tar.gz -C /data .Q3:多臺 VPS 如何集中監控?
三種方案:
| 方案 | 做法 | 適合 |
|---|---|---|
| 中心拉取 | 監控服務器直接拉各 VPS 的 Exporter(需網絡可達) | 同內網/有隧道 |
| 反向代理 | 各 VPS 用 Nginx 暴露 Exporter,中心統一拉 | 有公網 IP |
| Pushgateway | 邊緣節點定時推送(適合 NAT/動態 IP) | 無公網 IP |
最常用是中心拉取:監控服務器 Prometheus 配置多個 static_configs,targets 填各 VPS 內網 IP + 端口(通過 WireGuard 組網可互通)。
Q4:Grafana 進不去 / 密碼忘了?
# 重置 admin 密碼
docker exec -it grafana grafana-cli admin reset-admin-password newpasswordQ5:告警不觸發?如何排查?
- 訪問
http://IP:9090/alerts看規則是否PENDING/FIRING - 檢查
alertmanager.yml語法:amtool check-config alertmanager.yml - 確認 Prometheus
alerting段指向正確的 Alertmanager 地址 - 用
amtool alert query查看當前告警 - Telegram 確認 Bot Token 和 Chat ID 正確(Chat ID 是負數需帶負號)
Q6:能監控 Docker 容器嗎?
能。部署 cAdvisor 採集容器指標:
docker run -d --name cadvisor \
-p 8080:8080 \
-v /:/rootfs:ro -v /var/run:/var/run:ro \
-v /sys:/sys:ro -v /var/lib/docker/:/var/lib/docker:ro \
gcr.io/cadvisor/cadvisor:latestPrometheus 添加 job 指向 cadvisor:8080,看板 ID:893(Docker 監控)。
Q7:生產環境如何保護監控面板?
- Grafana/Prometheus 不要直接暴露公網,套一層 Nginx + Basic Auth 或反向代理
- Grafana 配置
GF_AUTH_ANONYMOUS_ENABLED=false禁用匿名訪問 - 修改默認端口(9090/3000 眾所周知易被掃描)
- 啟用 HTTPS(參考站內 VPS 安全加固實戰指南)
- 定期更新鏡像版本
Q8:和 VPS 供應商自帶的監控(如阿里云云監控)有什麼區別?
| 維度 | 廠商監控 | Prometheus+Grafana |
|---|---|---|
| 數據歸屬 | 廠商掌握 | 自己掌握 |
| 自定義 | 受限 | 完全自由 |
| 跨廠商 | 各看各的 | 統一看板 |
| 成本 | 高級功能收費 | 免費 |
| 告警渠道 | 廠商 App | 郵件/Telegram/釘釘/Slack |
自建監控的最大價值是跨廠商統一和數據自主。
總結
Prometheus + Grafana 是 VPS 監控的黃金組合。回顧核心要點:
- 架構清晰:Prometheus 拉取指標存儲,Grafana 可視化,Alertmanager 管告警
- 部署簡單:Docker Compose 一份配置拉起整套棧
- 看板現成:導入社區 Dashboard ID(1860/11199)即可用
- 告警靈活:郵件 + Telegram 雙通道,PromQL 精準定義閾值
- 可擴展:Nginx / SSL / 網站可用性 / 多節點一站式覆蓋
搭建順序建議:
1. Node Exporter(採集主機指標)
2. Prometheus(存儲 + 查詢)
3. Grafana(可視化看板)
4. 導入 Dashboard 1860
5. Alertmanager(郵件/Telegram 告警)
6. 進階:Blackbox + Nginx Exporter延伸閱讀:
- VPS 安全加固實戰指南 — 監控面板同樣需要安全保護
- WireGuard 自建 VPN 完整教程 — 多 VPS 監控的組網方案
- VPS 供應商橫向對比 — 選一臺穩定的 VPS 跑監控
- Docker 多階段構建優化 — 理解容器化部署
- VitePress SEO 優化指南 — 本站同款技術棧
🚀 監控不是錦上添花,而是系統穩定運行的底線。花一晚上搭好這套監控,未來無數個安穩的夜晚都是它換來的。
相關命令速查:
# 啟動整套監控
docker compose up -d
# 查看狀態
docker compose ps
# 重啟單個服務
docker compose restart prometheus
# 熱加載 Prometheus 配置(無需重啟)
curl -X POST http://localhost:9090/-/reload
# 查看告警
docker logs alertmanager