环境搭建与基础配置:Docker Compose部署Prometheus Stack
好,咱们直接进入正题。这一章,我带你亲手把Prometheus监控栈搭起来。说实话,很多新手在这一步就卡住了——不是配置文件写错,就是端口冲突,折腾半天连个数据都看不到。别急,跟着我的节奏来,保证一次跑通。
为什么选Docker Compose?
我个人习惯用Docker Compose来部署Prometheus Stack。原因很简单:可复现、易管理、好迁移。你想想看,如果每台机器都手动装一遍Prometheus、Grafana、Alertmanager,那运维成本得多高?
我在项目中遇到过最典型的情况:开发环境搭好了,测试环境又得重来一遍。有了Compose文件,一条命令搞定所有服务。说白了,这就是运维的「一次编写,到处运行」。
网络规划与端口映射
先别急着写代码,咱们得把网络想清楚。我见过太多人上来就写ports: "9090:9090",结果跟宿主机上已有的服务冲突了。
这里我建议的规划方案:
| 服务 | 内部端口 | 映射端口 | 说明 |
|---|---|---|---|
| Prometheus | 9090 | 19090 | 避开常见端口 |
| Grafana | 3000 | 13000 | 防止跟开发环境冲突 |
| Alertmanager | 9093 | 19093 | 告警管理专用 |
| Node Exporter | 9100 | 19100 | 主机指标采集 |
为什么要用19090而不是9090?嗯,这里要注意:很多团队会在宿主机上跑一些Java应用,它们默认就占用了8080、9090这些端口。我曾经因为端口冲突排查了整整一个下午,最后发现是Jenkins占用了9090。从那以后,我所有映射端口都加了个1前缀。
数据持久化配置
容器一重启数据就丢了?这绝对是新手最容易踩的坑。Prometheus默认把数据写在容器内部,一旦容器被删除,所有历史指标全部消失。
解决方案很简单:挂载宿主机目录。我习惯在宿主机上创建这样一个目录结构:
/data/prometheus/
├── prometheus/
│ └── data/
├── grafana/
│ └── data/
└── alertmanager/
└── data/
然后在Compose文件里用volumes挂载。这样即使容器挂了,数据还在宿主机上。我建议你养成习惯:所有有状态的服务,必须做数据持久化。
完整的Docker Compose文件
好了,理论说完了,直接上代码。这是我经过多次迭代后沉淀下来的版本:
version: '3.8'
networks:
monitor-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
services:
prometheus:
image: prom/prometheus:v2.45.0
container_name: prometheus
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- /data/prometheus/prometheus/data:/prometheus
ports:
- "19090:9090"
networks:
monitor-net:
ipv4_address: 172.20.0.10
restart: unless-stopped
grafana:
image: grafana/grafana:10.0.3
container_name: grafana
volumes:
- /data/prometheus/grafana/data:/var/lib/grafana
ports:
- "13000:3000"
networks:
monitor-net:
ipv4_address: 172.20.0.11
restart: unless-stopped
alertmanager:
image: prom/alertmanager:v0.25.0
container_name: alertmanager
volumes:
- ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml
- /data/prometheus/alertmanager/data:/alertmanager
ports:
- "19093:9093"
networks:
monitor-net:
ipv4_address: 172.20.0.12
restart: unless-stopped
node-exporter:
image: prom/node-exporter:v1.6.0
container_name: node-exporter
ports:
- "19100:9100"
networks:
monitor-net:
ipv4_address: 172.20.0.13
restart: unless-stopped
关键点说明:
- 使用
networks指定了子网172.20.0.0/16,避免跟Docker默认网段冲突 - 每个服务都分配了固定IP,方便后续配置中直接引用
restart: unless-stopped保证服务异常退出后自动重启
Prometheus配置文件
有了Compose文件还不够,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: ['172.20.0.13:9100']
- job_name: 'alertmanager'
static_configs:
- targets: ['172.20.0.12:9093']
这里有个小技巧:scrape_interval我设成了15秒。为什么不是默认的1分钟?因为监控系统需要快速发现异常。但也不能设得太短,否则会对目标机器造成压力。15秒是我在项目中验证过的平衡点。
启动与验证
所有文件准备好后,执行一条命令:
docker-compose up -d
然后检查服务状态:
docker-compose ps
你应该看到四个服务都是Up状态。接着打开浏览器:
- Prometheus UI:
http://宿主机IP:19090 - Grafana:
http://宿主机IP:13000(默认账号admin/admin) - Alertmanager:
http://宿主机IP:19093
避坑指南:我曾经在部署时发现Grafana一直报Permission denied。排查了半天,原来是宿主机上/data/prometheus/grafana/data目录的权限不对。Grafana容器内的用户是472,所以需要执行:
chown -R 472:472 /data/prometheus/grafana/data
记住这个教训:挂载目录的权限一定要跟容器内用户匹配。
核心架构图
为了让你更直观地理解整个架构,我画了一张图:
这张图清晰地展示了四个服务之间的协作关系。Node Exporter负责采集主机指标,Prometheus负责存储和查询,Grafana负责可视化,Alertmanager负责告警。它们通过monitor-net网络相互通信。
验证是否成功
部署完成后,我习惯做三件事来验证:
- 检查Prometheus Targets:访问
http://宿主机IP:19090/targets,看所有目标是否都是UP状态 - 检查Grafana数据源:登录Grafana,添加Prometheus数据源,URL填
http://172.20.0.10:9090,点击「Save & Test」 - 检查Alertmanager状态:访问
http://宿主机IP:19093/#/status,确认服务正常运行
重要提醒:如果Grafana连接Prometheus失败,八成是网络问题。检查一下:
- 两个服务是否在同一个Docker网络里
- Prometheus的IP地址是否写对了(是容器IP,不是宿主机IP)
- 防火墙有没有拦截19090端口
好了,环境搭建就到这里。这套配置我用了两年多,在十几个项目里验证过,稳定性没得说。你照着做,应该半小时内就能跑起来。
公众号:蓝海资料掘金营,微信deep3321