Prometheus + Grafana 搭建 VPS 监控仪表盘:CPU、内存、带宽一目了然,异常自动告警


服务器挂了才发现?磁盘满了网站打不开?带宽跑爆被服务商限速?这些问题其实都能提前预防。今天教你用 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 仪表盘配置

  1. 添加 Prometheus 数据源

登录 Grafana → Configuration → Data Sources → Add data source

  • Type: Prometheus
  • URL: http://prometheus:9090
  • Save & Test
  1. 导入 Node Exporter 仪表盘

Grafana 官方提供了精美的仪表盘模板,无需从零搭建:

Create → Import → 输入 Dashboard ID 1860 → Load → 选择 Prometheus 数据源 → Import

  1. 自定义仪表盘

常用监控面板:

面板 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 网络里,管理更方便。



MySQL 性能优化实战:从 3 秒查询到 30 毫秒,WordPress 数据库提速 10 倍

VPS 服务器被入侵后的紧急排查与加固:一次真实入侵事件的复盘

评 论
更换验证码