服务器挂了才发现?磁盘满了网站打不开?带宽跑爆被服务商限速?这些问题其实都能提前预防。今天教你用 Prometheus + Grafana + Node Exporter 搭建一套免费的服务器监控告警系统,5 分钟部署,实时监控 CPU、内存、磁盘、网络,异常自动发邮件/钉钉告警。
一、架构简介
组件 作用
Node Exporter 采集服务器指标(CPU、内存、磁盘、网络)
Prometheus 时序数据库,存储和查询指标数据
Grafana 可视化仪表盘,图表展示
Alertmanager 告警管理,发送通知
数据流向:
Node Exporter → Prometheus → Grafana(可视化)/ Alertmanager(告警)
二、Docker Compose 一键部署
创建监控目录:
mkdir -p ~/monitoring/{prometheus,grafana,alertmanager}
cd ~/monitoring
docker-compose.yml:
version: '3.8'
services:
node-exporter:
image: prom/node-exporter:latest
container_name: node_exporter
restart: unless-stopped
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|run|var/lib/docker|var/lib/containers)($$|/)'
ports:
- "9100:9100"
networks:
- monitoring
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./prometheus/data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=30d'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.enable-lifecycle'
ports:
- "9090:9090"
networks:
- monitoring
depends_on:
- node-exporter
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
volumes:
- ./grafana/data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=YourGrafanaPass123!
- GF_USERS_ALLOW_SIGN_UP=false
- GF_SERVER_ROOT_URL=https://monitor.yourdomain.com
ports:
- "3000:3000"
networks:
- monitoring
depends_on:
- prometheus
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
restart: unless-stopped
volumes:
- ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
command:
- '--config.file=/etc/alertmanager/alertmanager.yml'
- '--storage.path=/alertmanager'
ports:
- "9093:9093"
networks:
- monitoring
networks:
monitoring:
driver: bridge
三、配置文件
prometheus/prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
rule_files:
- /etc/prometheus/rules/*.yml
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'remote-server'
static_configs:
- targets: ['remote-ip:9100']
# 监控多台服务器时添加更多 targets
prometheus/rules/node_alerts.yml(告警规则):
groups:
- name: node_alerts
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "CPU 使用率过高"
description: "实例 {{ $labels.instance }} CPU 使用率超过 80%,当前值: {{ $value }}%"
- alert: HighMemoryUsage
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 85
for: 5m
labels:
severity: warning
annotations:
summary: "内存使用率过高"
description: "实例 {{ $labels.instance }} 内存使用率超过 85%,当前值: {{ $value }}%"
- alert: DiskSpaceLow
expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 10
for: 5m
labels:
severity: critical
annotations:
summary: "磁盘空间不足"
description: "实例 {{ $labels.instance }} 根分区剩余空间低于 10%,当前值: {{ $value }}%"
- alert: NetworkHighUsage
expr: rate(node_network_receive_bytes_total[5m]) > 104857600
for: 10m
labels:
severity: warning
annotations:
summary: "网络流量异常"
description: "实例 {{ $labels.instance }} 入站流量超过 100MB/s"
- alert: InstanceDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "实例宕机"
description: "实例 {{ $labels.instance }} 已宕机超过 1 分钟"
alertmanager/alertmanager.yml(邮件告警):
global:
smtp_smarthost: 'smtp.qq.com:587'
smtp_from: 'your-email@qq.com'
smtp_auth_username: 'your-email@qq.com'
smtp_auth_password: 'your-smtp-password'
smtp_require_tls: true
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'email-notifications'
receivers:
- name: 'email-notifications'
email_configs:
- to: 'admin@yourdomain.com'
headers:
Subject: 'VPS 监控告警'
html: |
<h2>告警通知</h2>
<p><strong>告警名称:</strong> {{ .GroupLabels.alertname }}</p>
<p><strong>实例:</strong> {{ .CommonLabels.instance }}</p>
<p><strong>严重程度:</strong> {{ .CommonLabels.severity }}</p>
<hr>
{{ range .Alerts }}
<p><strong>详情:</strong> {{ .Annotations.description }}</p>
<p><strong>时间:</strong> {{ .StartsAt.Format "2006-01-02 15:04:05" }}</p>
{{ end }}
四、启动监控栈
docker-compose up -d
检查状态:
docker-compose ps
访问各组件:
- Prometheus:
http://your-server-ip:9090 - Grafana:
http://your-server-ip:3000(默认账号 admin/YourGrafanaPass123!) - Alertmanager:
http://your-server-ip:9093
五、Grafana 仪表盘配置
- 添加 Prometheus 数据源
登录 Grafana → Configuration → Data Sources → Add data source
- Type: Prometheus
- URL:
http://prometheus:9090 - Save & Test
- 导入 Node Exporter 仪表盘
Grafana 官方提供了精美的仪表盘模板,无需从零搭建:
Create → Import → 输入 Dashboard ID 1860 → Load → 选择 Prometheus 数据源 → Import
- 自定义仪表盘
常用监控面板:
面板 PromQL 查询
CPU 使用率 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
内存使用率 (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100
磁盘使用率 100 - ((node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100)
网络入站 rate(node_network_receive_bytes_total[5m])
网络出站 rate(node_network_transmit_bytes_total[5m])
磁盘 I/O rate(node_disk_io_time_seconds_total[5m])
负载均衡 node_load1
六、监控多台服务器
在每台被监控服务器上安装 Node Exporter:
docker run -d \
--name node_exporter \
--restart unless-stopped \
-p 9100:9100 \
-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
然后在 Prometheus 的 prometheus.yml 中添加:
scrape_configs:
- job_name: 'all-servers'
static_configs:
- targets:
- 'server1-ip:9100'
- 'server2-ip:9100'
- 'server3-ip:9100'
重启 Prometheus:
docker-compose exec prometheus kill -HUP 1
七、钉钉/企业微信告警(进阶)
修改 alertmanager.yml,添加 webhook 接收器:
receivers:
- name: 'dingtalk'
webhook_configs:
- url: 'https://oapi.dingtalk.com/robot/send?access_token=your-token'
send_resolved: true
http_config:
headers:
Content-Type: application/json
title: 'VPS 监控告警'
message: |
{{ range .Alerts }}
**告警名称**: {{ .Labels.alertname }}
**实例**: {{ .Labels.instance }}
**级别**: {{ .Labels.severity }}
**详情**: {{ .Annotations.description }}
**时间**: {{ .StartsAt.Format "2006-01-02 15:04:05" }}
{{ end }}
八、资源占用实测
组件 内存占用 CPU 占用
Node Exporter 15MB 几乎为零
Prometheus 200MB 低(视数据量)
Grafana 100MB 低
Alertmanager 30MB 几乎为零
总计 350MB 极低
1GB 内存的服务器跑这套监控绰绰有余,还能同时跑 WordPress。
九、与商业监控对比
功能 自建 Prometheus 阿里云监控 腾讯云监控
成本 免费 基础免费,高级收费 基础免费,高级收费
数据保留 自定义(30天+) 15-30天 15-30天
告警渠道 邮件/钉钉/微信/Slack 短信/邮件/钉钉 短信/邮件/微信
自定义指标 完全自由 有限 有限
多服务器 无限 按量收费 按量收费
学习成本 中等 低 低
十、备份与恢复
备份 Prometheus 数据:
# 停止容器
docker-compose stop prometheus
# 备份数据目录
tar czvf prometheus-backup-$(date +%Y%m%d).tar.gz ~/monitoring/prometheus/data
# 重启
docker-compose start prometheus
备份 Grafana 仪表盘:
Dashboards → Manage → 选择仪表盘 → Share → Export → Save to file
总结
Prometheus + Grafana 是云原生监控的黄金组合,部署一次,长期受益。对于只有 1-3 台服务器的个人站长,这套方案完全够用,而且数据完全掌握在自己手里。建议配合之前的 Docker WordPress 部署一起使用,把监控容器和网站容器放在同一个 Docker Compose 网络里,管理更方便。
