引言
在微服务和云原生时代,系统复杂度指数级上升,传统的监控工具已难以满足多维度的可观测性需求。Prometheus 作为 CNCF 毕业项目,凭借其强大的多维数据模型、灵活的 PromQL 查询语言以及完善的生态,已成为云原生监控的事实标准。再结合 Grafana 强大的可视化能力,我们可以快速构建出一套覆盖基础设施、应用、中间件的统一监控平台。本文将从核心原理出发,通过一套完整的 Docker Compose 编排,带你实战搭建生产级 Prometheus + Grafana 监控体系,并分享常见避坑经验。
一、核心概念速览
1. Prometheus 架构与数据模型
Prometheus Server 通过拉取(Pull)方式定时从各类 Exporter 或应用中抓取指标数据,存储在本地的时序数据库(TSDB)中,并提供 HTTP API 供查询和展示。其核心组件包括:
-
Prometheus Server :负责抓取、存储、提供查询接口
-
Exporters :将第三方系统的指标暴露为 Prometheus 格式(如 node_exporter 采集主机指标)
-
Alertmanager :处理告警,支持分组、抑制、静默、路由
-
Pushgateway:用于短期任务的指标中转
数据模型以 指标名 + 键值对标签 唯一标识一条时间序列,例如:
node_cpu_seconds_total{cpu="0",mode="idle",instance="192.168.1.10:9100"}
2. PromQL 与 Grafana
PromQL 是 Prometheus 的查询语言,支持过滤、聚合、运算等。例如计算 CPU 使用率:
promql
(1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)) * 100
Grafana 作为可视化层,可以对接 Prometheus 数据源,将 PromQL 结果以图表、表格、热力图等形式展示。社区有大量现成的 Dashboard 模板(如 Node Exporter Full 的 ID 1860),直接导入即可。
二、实战:Docker Compose 一键搭建完整监控栈
我们将通过 Docker Compose 部署以下服务:
-
Prometheus
-
Node Exporter(采集 Docker 宿主机指标)
-
Grafana
-
Alertmanager
所有配置文件完整可运行,生产环境可直接参考。
1. 项目目录结构
monitoring/
├── docker-compose.yml
├── prometheus/
│ ├── prometheus.yml
│ └── alert_rules.yml
├── alertmanager/
│ └── alertmanager.yml
└── grafana/
└── dashboards/ # 可选,提前放 dashboard JSON
2. 编写 docker-compose.yml
yaml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- ./prometheus/alert_rules.yml:/etc/prometheus/alert_rules.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.enable-lifecycle' # 允许热加载配置
ports:
- "9090:9090"
restart: unless-stopped
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
ports:
- "9100:9100"
restart: unless-stopped
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards # 可选
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin # 生产环境务必修改
restart: unless-stopped
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
volumes:
- ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml
ports:
- "9093:9093"
restart: unless-stopped
volumes:
prometheus_data:
grafana_data:
3. Prometheus 配置文件
prometheus/prometheus.yml:
yaml
global:
scrape_interval: 15s # 抓取间隔
evaluation_interval: 15s # 规则评估间隔
external_labels:
monitor: 'codelab'
# 告警规则文件路径
rule_files:
- "alert_rules.yml"
# Alertmanager 地址
alerting:
alertmanagers:
- static_configs:
- targets:
- 'alertmanager:9093'
# 抓取任务配置
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
告警规则 prometheus/alert_rules.yml:
yaml
groups:
- name: node_alerts
rules:
- alert: HighCPUUsage
expr: (100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "CPU 使用率过高 (实例 {{ $labels.instance }})"
description: "CPU 使用率已超过 80%,当前值: {{ $value }}%"
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 85
for: 5m
labels:
severity: critical
annotations:
summary: "内存使用率过高 (实例 {{ $labels.instance }})"
4. Alertmanager 配置
alertmanager/alertmanager.yml(简单示例,仅控制台输出):
yaml
global:
resolve_timeout: 5m
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receiver: 'console-receiver'
receivers:
- name: 'console-receiver'
# 可配置 email、webhook、Slack 等,这里仅为演示
5. 启动与验证
在项目根目录执行:
bash
docker-compose up -d
检查各服务状态:
-
Prometheus UI: http://localhost:9090
-
Grafana: http://localhost:3000 (admin/admin)
-
Alertmanager: http://localhost:9093
-
Node Exporter metrics: http://localhost:9100/metrics
6. Grafana 配置数据源与导入 Dashboard
- 登录 Grafana,点击
Configuration>Data Sources>Add data source。 - 选择
Prometheus,URL 填写http://prometheus:9090(容器内网络),点击Save & Test。 - 导入社区 Dashboard:点击
+>Import,输入 ID1860(Node Exporter Full),选择刚刚创建的数据源,点击 Import。
此时应能看到漂亮的节点监控大盘,包含 CPU、内存、磁盘、网络等实时图表。
三、常用 PromQL 查询示例
- 查看所有节点 CPU 空闲率:
promql avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100 - 内存使用率:
promql (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 - 磁盘使用率:
promql (1 - (node_filesystem_avail_bytes{fstype!="tmpfs"} / node_filesystem_size_bytes{fstype!="tmpfs"})) * 100 - 网络接收速率(MB/s):
promql rate(node_network_receive_bytes_total[5m]) / 1024 / 1024
四、常见问题与注意事项
1. 数据存储与性能
Prometheus 默认每 2 小时进行一次数据块压缩,本地存储不建议用于长期归档。生产环境可考虑远程存储适配器(如 Thanos、VictoriaMetrics)实现长期存储和高可用。
2. 标签(Label)管理
警惕标签基数爆炸:不要将用户 ID、请求 ID 等高基数数据放入标签,会导致时间序列数量激增,严重影响性能。可通过
relabel_configs在抓取时丢弃不需要的标签。
示例:丢弃 node_network_info 中的某些标签:
yaml
- job_name: 'node'
static_configs:
- targets: ['...']
metric_relabel_configs:
- source_labels: [__name__]
regex: 'node_network_info'
action: drop
3. 抓取间隔与超时
scrape_interval 不宜过短,默认 15s 适合多数场景。目标响应超时由 scrape_timeout 控制,应小于抓取间隔。若目标响应慢,需酌情上调,避免频繁超时导致数据缺失。
4. 告警收敛
合理使用 group_by、group_wait、repeat_interval 避免告警风暴。在 Alertmanager 中配置不同接收器,将 warning 和 critical 告警路由到不同渠道(如邮件、钉钉、PagerDuty)。
5. 安全加固
默认启动没有认证,生产环境应配置反向代理(如 Nginx + TLS)并开启 Prometheus 的认证(--web.config.file)。Grafana 密码务必修改,并配置 SMTP 告警通道。
6. 监控 Exporter 自身
不要忘记监控 Prometheus 自身,可通过 Prometheus 自监控指标 prometheus_tsdb_* 和 up 指标来监控抓取目标的健康状况。
五、总结
通过本文的 Docker Compose 方案,你可以在 5 分钟内启动一套功能完备的 Prometheus + Grafana 监控栈。但这只是起点,要构建真正的企业级可观测平台,还需要持续扩展:
-
集成应用指标:基于 Micrometer、Prometheus Client 暴露业务指标
-
日志与链路:结合 Loki、Tempo 实现全栈可观测性
-
自动发现:利用 Kubernetes SD、Consul 等完成动态抓取配置
-
长期存储:借助 Thanos 或 Cortex 实现全局视图和无限保留期
监控是稳定性的基石,只有看得见,才能治得了。希望本文能帮助你迈出坚实的第一步。