Prometheus + Grafana 服务器监控栈实战指南
Prometheus + Grafana 服务器监控栈实战指南
一、引言
服务器监控是运维体系的”眼睛”。没有监控,你就像在黑暗中驾驶——直到用户报故障才知道系统出了问题。2026 年,Prometheus + Grafana 组合已成为开源监控领域的事实标准,被从个人 Homelab 到大型企业的广泛采用。
本文从零开始,搭建一套完整的监控栈:Prometheus 负责指标采集与存储,Grafana 负责可视化与告警,Node Exporter 负责主机指标暴露。所有组件通过 Docker Compose 一键部署,适合单台服务器到中小规模集群。
二、架构概览
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ┌─────────────────────────────────────────────────┐ │ Grafana │ │ 仪表盘 · 告警规则 · 数据源配置 │ └────────────┬───────────────────────┬────────────┘ │ HTTP :3000 │ HTTP :9090 ▼ ▼ ┌──────────────────────┐ ┌──────────────────────┐ │ Prometheus │ │ Alertmanager │ │ 指标存储 · 查询 │ │ 告警路由 · 通知 │ │ :9090 │ │ :9093 │ └────┬──────┬──────┬────┘ └──────────────────────┘ │ │ │ ▼ ▼ ▼ ┌──────┐┌──────┐┌──────┐ │Node ││Node ││... │ Node Exporter 采集主机指标 │Exp. ││Exp. ││ │ (CPU/内存/磁盘/网络) └──────┘└──────┘└──────┘
|
三、前置要求
- Linux 服务器(本文基于 Ubuntu 22.04/24.04)
- 已安装 Docker 和 Docker Compose(v2+)
- 基本的命令行操作能力
- 了解端口、HTTP 协议等基本概念
四、Docker Compose 部署监控栈
4.1 目录结构
1 2
| mkdir -p /opt/monitoring/{prometheus,grafana,alertmanager} cd /opt/monitoring
|
4.2 docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| version: "3.8"
networks: monitoring: driver: bridge
volumes: prometheus_data: grafana_data:
services: prometheus: image: prom/prometheus:v2.53.0 container_name: prometheus restart: always volumes: - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - ./prometheus/rules:/etc/prometheus/rules - 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
grafana: image: grafana/grafana:11.1.0 container_name: grafana restart: always volumes: - ./grafana/datasources:/etc/grafana/provisioning/datasources - ./grafana/dashboards:/etc/grafana/provisioning/dashboards - grafana_data:/var/lib/grafana environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=admin123 - GF_INSTALL_PLUGINS= - GF_SERVER_ROOT_URL=http://your-server-ip:3000 ports: - "3000:3000" networks: - monitoring depends_on: - prometheus
alertmanager: image: prom/alertmanager:v0.27.0 container_name: alertmanager restart: always volumes: - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml ports: - "9093:9093" networks: - monitoring
node_exporter: image: prom/node-exporter:v1.8.0 container_name: node_exporter restart: always command: - "--path.rootfs=/host" - "--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)" pid: host volumes: - /:/host:ro,rslave ports: - "9100:9100" networks: - monitoring
|
⚠️ 安全提示:生产环境请修改 GF_SECURITY_ADMIN_PASSWORD,并使用环境变量文件(.env)管理敏感信息。
4.3 Prometheus 配置
prometheus/prometheus.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| global: scrape_interval: 15s evaluation_interval: 15s scrape_timeout: 10s
alerting: alertmanagers: - static_configs: - targets: - alertmanager:9093
rule_files: - "rules/*.yml"
scrape_configs: - job_name: "prometheus" static_configs: - targets: ["localhost:9090"]
- job_name: "node" static_configs: - targets: - "node_exporter:9100" relabel_configs: - source_labels: [__address__] regex: "(.*):9100" target_label: instance replacement: "server-01"
|
4.4 告警规则
prometheus/rules/node_alerts.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| groups: - name: node_alerts interval: 30s rules: - alert: HighCpuUsage expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80 for: 5m labels: severity: warning annotations: summary: "{{ $labels.instance }} CPU 使用率过高" description: "CPU 使用率已超过 80%(当前值:{{ $value }}%)"
- alert: HighMemoryUsage expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 85 for: 5m labels: severity: warning annotations: summary: "{{ $labels.instance }} 内存使用率过高" description: "内存使用率已超过 85%(当前值:{{ $value }}%)"
- alert: DiskSpaceLow expr: (node_filesystem_avail_bytes{mountpoint="/",fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{mountpoint="/",fstype!~"tmpfs|overlay"}) * 100 < 10 for: 5m labels: severity: critical annotations: summary: "{{ $labels.instance }} 磁盘空间不足" description: "磁盘可用空间低于 10%(当前值:{{ $value | humanizePercentage }})"
- alert: NodeDown expr: up{job="node"} == 0 for: 1m labels: severity: critical annotations: summary: "{{ $labels.instance }} 已离线" description: "节点 {{ $labels.instance }} 已离线超过 1 分钟"
- alert: HighDiskIO expr: rate(node_disk_io_time_seconds_total[5m]) > 0.5 for: 5m labels: severity: warning annotations: summary: "{{ $labels.instance }} 磁盘 IO 过高" description: "磁盘 IO 时间占比超过 50%(当前值:{{ $value | humanizePercentage }})"
|
4.5 Alertmanager 配置
alertmanager/alertmanager.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| global: resolve_timeout: 5m smtp_smarthost: "smtp.example.com:587" smtp_from: "alert@example.com" smtp_auth_username: "alert@example.com" smtp_auth_password: "your-password"
route: receiver: "default" group_wait: 30s group_interval: 5m repeat_interval: 4h routes: - match: severity: critical receiver: "critical" repeat_interval: 1h
receivers: - name: "default" email_configs: - to: "admin@example.com"
- name: "critical" email_configs: - to: "oncall@example.com" webhook_configs: - url: "https://hooks.example.com/alert"
|
4.6 Grafana 自动配置数据源
grafana/datasources/datasource.yml:
1 2 3 4 5 6 7 8 9
| apiVersion: 1
datasources: - name: Prometheus type: prometheus access: proxy url: http://prometheus:9090 isDefault: true editable: false
|
4.7 启动监控栈
1 2 3 4 5 6 7 8
| cd /opt/monitoring docker compose up -d
docker compose ps
docker compose logs -f
|
验证各组件:
1 2 3 4 5 6 7 8 9 10 11
| curl http://localhost:9090/targets
curl http://localhost:9100/metrics | head -20
curl -I http://localhost:3000
curl http://localhost:9093/
|
五、Grafana 仪表盘配置
5.1 导入官方仪表盘
Grafana 启动后,访问 http://your-server-ip:3000,使用 admin / admin123 登录。
推荐导入的 Node Exporter 仪表盘:
| 仪表盘 ID |
名称 |
说明 |
| 1860 |
Node Exporter Full |
最全面的主机监控仪表盘 |
| 11074 |
Node Exporter Server Metrics |
轻量级主机监控 |
| 16098 |
1 Node Exporter for Prometheus Dashboard |
现代化设计 |
导入方法:
- 左侧菜单 → Dashboards → New → Import
- 输入 Dashboard ID → Load
- 选择 Prometheus 数据源 → Import
5.2 自动预配仪表盘(进阶)
grafana/dashboards/node_exporter.json 可以从 Grafana Dashboards 下载 JSON 文件后放入此目录,Grafana 启动时会自动加载。
六、关键指标解读
6.1 CPU 指标
1 2 3 4 5 6 7 8
| # CPU 使用率(排除 idle) 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 按 CPU 核心查看使用率 100 - (avg by(instance, cpu) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# CPU 负载(1/5/15 分钟) node_load1 / node_load5 / node_load15
|
6.2 内存指标
1 2 3 4 5 6 7 8
| # 内存使用率 (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
# 实际使用内存(不含缓存/缓冲区) node_memory_MemTotal_bytes - node_memory_MemFree_bytes - node_memory_Buffers_bytes - node_memory_Cached_bytes
# Swap 使用率 (node_memory_SwapTotal_bytes - node_memory_SwapFree_bytes) / node_memory_SwapTotal_bytes * 100
|
6.3 磁盘指标
1 2 3 4 5 6 7 8 9
| # 磁盘使用率(按挂载点) (node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"}) / node_filesystem_size_bytes{mountpoint="/"} * 100
# 磁盘 IO 读写速率 rate(node_disk_read_bytes_total[5m]) rate(node_disk_written_bytes_total[5m])
# 磁盘 IO 等待时间 rate(node_disk_io_time_seconds_total[5m])
|
6.4 网络指标
1 2 3 4 5 6 7 8
| # 网络入站流量 rate(node_network_receive_bytes_total{device!="lo"}[5m])
# 网络出站流量 rate(node_network_transmit_bytes_total{device!="lo"}[5m])
# TCP 连接数 node_netstat_Tcp_CurrEstab
|
七、告警通知配置
7.1 邮件通知
在 alertmanager.yml 中配置 SMTP 后,重启 Alertmanager:
1
| docker compose restart alertmanager
|
7.2 Webhook 通知(企业微信/钉钉/Slack)
1 2 3 4 5 6
| receivers: - name: "wechat" webhook_configs: - url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY" send_resolved: true
|
7.3 Grafana 内置告警(替代方案)
Grafana 11.x 内置了告警引擎,可以直接在 UI 中配置告警规则:
- 左侧菜单 → Alerting → Alert rules → New alert rule
- 选择 Prometheus 数据源,编写 PromQL 查询
- 设置评估间隔和条件阈值
- 配置通知渠道(邮件、Webhook、Telegram 等)
八、生产环境最佳实践
8.1 安全加固
1 2 3 4 5 6 7
|
basic_auth_users: admin: $2y$10$...
|
1 2 3 4 5
| volumes: - ./prometheus/web.yml:/etc/prometheus/web.yml command: - "--web.config.file=/etc/prometheus/web.yml"
|
8.2 数据保留策略
1 2 3 4
| command: - "--storage.tsdb.retention.time=30d" - "--storage.tsdb.retention.size=50GB"
|
8.3 资源限制
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| services: prometheus: deploy: resources: limits: memory: 2G cpus: "1.0" grafana: deploy: resources: limits: memory: 512M cpus: "0.5"
|
8.4 备份策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #!/bin/bash
BACKUP_DIR="/backup/monitoring" DATE=$(date +%Y%m%d)
docker run --rm -v prometheus_data:/data -v $BACKUP_DIR:/backup alpine \ tar czf /backup/prometheus-$DATE.tar.gz -C /data .
docker run --rm -v grafana_data:/data -v $BACKUP_DIR:/backup alpine \ tar czf /backup/grafana-$DATE.tar.gz -C /data .
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
|
九、常见问题
Q1:Prometheus 启动后 target 显示 DOWN
原因:通常是网络不通或端口未暴露。
排查:
1 2 3 4 5 6 7 8
| docker compose ps
docker exec prometheus wget -qO- http://node_exporter:9100/metrics
sudo ufw status
|
Q2:Grafana 无法连接 Prometheus 数据源
原因:Grafana 容器内使用 http://prometheus:9090 而非 localhost:9090。
解决:确认 datasource.yml 中的 URL 使用 Docker 服务名 http://prometheus:9090。
Q3:磁盘空间被 Prometheus 数据占满
原因:默认无数据保留限制。
解决:设置 --storage.tsdb.retention.time=15d 或 --storage.tsdb.retention.size=20GB。
Q4:告警没有触发
原因:告警规则文件未正确加载。
排查:
1 2 3 4 5
| curl http://localhost:9090/api/v1/rules
curl http://localhost:9093/api/v2/status
|
Q5:Node Exporter 指标不完整
原因:容器内无法访问宿主机文件系统。
解决:确保挂载了 pid: host 和卷 /:host:ro,rslave。
Q6:如何监控多台服务器?
方案:在每台服务器上运行 Node Exporter(Docker 或直接安装),然后在 Prometheus 配置中添加 target:
1 2 3 4 5 6 7
| scrape_configs: - job_name: "node" static_configs: - targets: - "192.168.1.10:9100" - "192.168.1.11:9100" - "192.168.1.12:9100"
|
十、总结
通过本文,你已搭建了一套完整的 Prometheus + Grafana 监控栈:
| 组件 |
端口 |
用途 |
| Prometheus |
9090 |
指标采集与存储 |
| Grafana |
3000 |
可视化仪表盘 |
| Alertmanager |
9093 |
告警路由与通知 |
| Node Exporter |
9100 |
主机指标暴露 |
这套方案的优势在于:Docker Compose 一键部署、组件解耦可独立扩展、告警规则可编程、仪表盘可共享。对于中小规模基础设施,它已经足够胜任生产环境监控需求。
参考资源