一套完整的 Metrics 管线通常由三个角色组成:负责暴露指标 exporter、负责抓取和存储指标的时序数据库,以及负责可视化展示和告警的前端。Prometheus 天生就是为这套链路设计的,它采用拉取模式定时从各个目标采集数据,配合 Grafana 的面板能力,几乎成了云原生监控的标配。用 Docker 来搭建这套管线,可以避免手工安装带来的版本冲突和环境残留问题,整个过程十几分钟就能跑通,非常适合中小团队快速落地。

一、规划目录结构与编排文件
先确定一个清晰的项目目录。建议把所有配置文件和持久化数据集中放在一个根目录下,比如 monitoring,内部再分出 prometheus、grafana 两个子目录。这样做的好处是,后期迁移环境时只需打包整个目录,配置和数据都能一并带走。
目录结构可以参考下面这种布局:
monitoring/
├── docker-compose.yml
├── prometheus/
│ ├── prometheus.yml
│ └── data/
└── grafana/
└── data/核心是 docker-compose.yml 文件。这里定义三个服务:prometheus 负责抓取和存储指标,grafana 负责展示,node_exporter 负责采集宿主机的 CPU、内存、磁盘等系统指标。注意 Prometheus 的配置文件要用只读方式挂载进容器,数据目录则用命名卷持久化,防止容器重建后历史数据丢失。
version: "3.8"
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prom_data:/prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.retention.time=15d"
networks:
- monitor_net
node_exporter:
image: prom/node-exporter:latest
container_name: node_exporter
pid: host
ports:
- "9100:9100"
networks:
- monitor_net
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
volumes:
- grafana_data:/var/lib/grafana
networks:
- monitor_net
volumes:
prom_data:
grafana_data:
networks:
monitor_net:
driver: bridge有两个细节值得注意。第一,node_exporter 加上 pid: host 并挂载宿主机文件系统相关路径后,采集到的才是宿主机真实的系统指标,而不是容器自身的。第二,通过 --storage.tsdb.retention.time=15d 可以控制数据保留天数,默认只保留 15 天,磁盘紧张的团队可以按需调整。
二、编写 Prometheus 抓取配置
Prometheus 本身不主动推送数据,而是按照配置文件里定义的抓取任务,周期性地访问目标的 /metrics 接口。新建 prometheus/prometheus.yml,内容如下:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "node_exporter"
static_configs:
- targets: ["node_exporter:9100"]这里的关键点在于 targets 的写法。因为在同一个 Docker 网络里,容器之间可以通过服务名互相访问,所以抓取地址写的是 node_exporter:9100 而不是 IP。如果你要监控的是宿主机上直接运行的进程,比如一个 Spring Boot 应用暴露在 8080 端口,那么目标地址要写成 host.docker.internal:8080,让容器内能够回连宿主机。
配置写好后执行 docker compose up -d,然后浏览器访问 http://127.0.0.1:9090/targets,如果所有 target 的状态都是 UP,说明抓取链路已经打通。此时可以在 Prometheus 的查询界面执行一条 PromQL 试试,比如 rate(node_cpu_seconds_total{mode="idle"}[1m]),能返回数值曲线就代表数据在正常写入。
三、Grafana 对接数据源与面板搭建
Grafana 启动后访问 http://127.0.0.1:3000,默认账号 admin,密码是编排文件里设置的 admin123。进入后台后第一步是添加数据源,类型选择 Prometheus,地址填写 http://prometheus:9090,同样利用了 Docker 网络内的服务名解析,点 Save and Test 出现绿色提示即成功。
面板方面不建议从零画起。Grafana 社区有大量现成的仪表盘模板,比如 node_exporter 官方推荐的模板编号 1860,导入后即可获得 CPU、内存、磁盘 IO、网络流量的完整视图。操作路径是左侧菜单依次选择 Dashboards、New、Import,输入模板编号并选择刚才创建的数据源即可。
如果是监控自己的业务服务,面板就需要围绕业务指标来设计。常见的思路是三层结构:最上层放服务的可用性和 QPS 等核心健康指标,中间层放接口延迟的 P95、P99 分位数,底层放 JVM 或连接池等资源类指标。这样从上往下排查时,能快速判断问题出在哪一层。
四、加上告警规则让管线主动说话
只有看板没有告警的监控体系是被动的。Prometheus 支持在配置中声明告警规则,比如下面这条规则会在实例持续离线一分钟后触发告警:
groups:
- name: instance_alerts
rules:
- alert: InstanceDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "实例 {{ $labels.instance }} 已经离线"
description: "该目标已经超过 1 分钟无法抓取,请及时排查。"要启用规则,需要在 Prometheus 的启动参数中追加 --web.enable-lifecycle,并在 prometheus.yml 里加上 rule_files 指向规则文件。规则触发后,真正把消息推给运维人员还需要配置 Alertmanager,它负责告警的去重、分组和路由,可以对接邮件、钉钉、企业微信等通知渠道。作为练习,可以在 compose 文件里追加一个 Alertmanager 服务,把告警链路也串起来。
另外提醒一点,容器化部署时要注意宿主机时间与容器时间保持一致,时间偏差会导致监控曲线错位、告警判断异常,部署前用 date 命令确认两边时间同步是个好习惯。
五、几个生产环境的进阶建议
单机 Docker 部署适合起步,但如果监控目标多、数据量大,有几个方向可以演进。一是镜像版本要固定,不要长期使用 latest 标签,升级前先在测试环境验证配置兼容性,避免 Prometheus 配置格式变更导致服务起不来。二是数据保留策略要结合磁盘容量规划,指标基数大的团队可以考虑引入远端存储方案来延长保存周期。
三是抓取配置建议从静态列表逐步过渡到基于服务发现的模式。如果被监控对象本身跑在 Kubernetes 或者注册中心里,Prometheus 可以自动感知目标上下线,省去手工维护 targets 的麻烦。四是注意容器资源的隔离,给 Prometheus 容器设置内存限制,防止查询高峰期把宿主机内存吃满。
总的来说,用 Docker Compose 搭建 Metrics 管线的关键在于理解数据的流向:exporter 暴露指标、Prometheus 定时拉取存储、Grafana 读取展示、Alertmanager 负责通知。这条链路跑通之后,再接入业务自定义指标、调整面板和告警阈值,都是顺水推舟的事了。
DockerPrometheusGrafana修改时间:2026-09-10 04:18:38