☰
手动搭建Prometheus容器监控:从二进制到Grafana告警全流程
2026/10/9 6:01:18 网站建设 项目流程

用Prometheus做容器监控这话题,网上教程一抓一大把,但大多数要么是docker run一把梭,要么直接甩给你一个docker-compose.yml让你复制粘贴。真让你从解压二进制文件开始,一步步把一个监控系统跑起来,再解释每一步到底在干嘛,反而没多少人讲清楚。这套“手动搭建”流程我前后走了好几遍,从裸机部署到容器化编排,踩了不少坑,也理清了不少原理。这篇文章就按实际动手的顺序走一遍,不整虚的,目标是让你在手上没有任何自动化工具的前提下,自己把Prometheus、exporter、Grafana和Alertmanager全部搭出来,理解每个环节为什么这么连,最后再封装成容器化版本。

适合谁看?刚接触监控体系、被各种监控产品绕晕的运维新手,或者对Prometheus只有概念、没亲手部署过的开发同学都适用。你已经会用Zabbix但想切换技术栈,也可以照着这套逻辑快速上手。核心就一件事:不开任何一键脚本,纯手动搭,搭完你就能自己加监控目标、改告警、画图表。

1. 项目解构:容器化监控到底需要什么

1.1 先想清楚监控的对象和闭环

聊搭建之前,得先明确“监控”到底是监控什么。容器化环境下,角色比传统物理机时代复杂不少:底层有宿主机,上面跑着Docker容器,容器里又封装着各种服务,服务还要依赖数据库、缓存、消息队列这些中间件。任何一个环节出问题,都可能让业务表现异常。所以一套完整的容器监控体系,至少要覆盖这四类指标:

  • 宿主机层:CPU、内存、磁盘、网络IO、负载等,这决定了整个机器还能不能扛得住。
  • 容器运行层:每个容器的CPU、内存、网络收发、磁盘读写,会让你知道是哪只容器在“吃”资源。
  • 业务服务层:接口响应时间、请求量、错误率,这是最能反映用户体验的,也是开发最关心的部分。
  • 中间件层:Redis命中率、MySQL慢查询、Nginx连接数,基础组件出故障往往是大事故的前兆。

有了这些数据还不够,监控的意义在于形成闭环:采集数据、存储数据、然后通过可视化面板让人能看懂趋势,再设置告警规则在指标异常时通知到人,最后才能去定位和解决。Prometheus在这条链路上主要承担前两个环节——抓取指标并存储,可视化交给Grafana,告警则由Alertmanager负责。把这几个组件串起来,整个监控体系才算完整。

1.2 为什么选Prometheus而不是其他监控方案

选Prometheus,核心原因是它对容器和云原生环境的天然适配。传统的Zabbix是典型的推送模型,Agent把数据主动推给Server,这种方式配置相对复杂,而且在容器频繁启停的场景下,Agent的注册注销会变得很混乱。Prometheus走的是拉取模型,监控服务端主动去目标端口的/metrics路径拉数据,只要目标还在,配置里写对了地址,数据就能拿过来。容器挂了,拉取自然会失败,但这个“失败”本身也是监控信息。

另外,Prometheus的标签(Label)设计很聪明。每个样本点除了指标名和值,还能带一组标签,比如实例IP、容器名、服务名。查询的时候可以按任意维度做聚合分析,比如“按实例算总CPU”“按服务算请求总和”,这就天然适配多实例部署的微服务架构。PromQL语法虽然一开始看着怪,但一旦上手,灵活度远高于传统监控的图形化表达式。

手动搭建的意义,很多人低估了。用docker-compose一条命令拉起来确实省事,但遇到问题你会无从下手:targets down了,不知道是配置文件问题还是网络问题;数据不更新,不知道是抓取超时还是存储满了。手动走一遍,你会发现每个组件其实不神秘——不过是个读配置、抓指标、存数据的流程。

2. 环境准备与整体架构规划

2.1 基础环境与软件版本选型

手动搭建的第一步,是准备好一台干净的实验机器。我的建议是给一台Linux虚拟机,至少2核4G内存,20G磁盘。系统用CentOS 7/8、Ubuntu 20.04/22.04都行,这边命令以Ubuntu为例,CentOS把apt换成yum就好。实验阶段不需要生产配置,但Docker Engine建议提前装好,因为后半程要容器化,前面二进制跑的流程能让你知道容器里跑的进程其实是一样的。

版本选择上,直接用官方最新的稳定版和长期支持版就好。我这里用的组合是:Prometheus 2.47.x,node_exporter 1.7.0,cAdvisor v0.47.0,Grafana 10.x,Alertmanager 0.27.0。没有追求最新,但都是当前正常维护的版本,后面你复制操作时大概率能直接用。注意不要盲目用beta版,监控这种基础设施,稳定压倒一切。

安装目录我习惯统一规划在/opt/prometheus下,每个组件一个目录,方便回滚和排查:

sudo mkdir -p /opt/prometheus/{server,exporter,grafana,alertmanager}

这只是一种习惯,等会儿所有配置文件和二进制都会按这个目录放。

2.2 整体组件架构与数据链路

架构图不用画太复杂,核心就是一条链子:底层的exporter(node_exporter收集机器指标,cAdvisor收集容器指标)负责暴露指标,Prometheus Server通过HTTP周期性拉取这些端口上的/metrics,把时序数据存进本地TSDB,同时根据规则文件计算告警条件。Grafana作为数据可视化前端,通过PromQL查询Prometheus数据并画图。Alertmanager收到Prometheus推送过来的告警,再按路由规则发送到邮件、钉钉或Webhook。

端口规划集中在下面这些,提前记好,免得互相冲突:

  • Prometheus Server:9090(web UI)
  • node_exporter:9100(机器指标)
  • cAdvisor:8080(容器指标)
  • Grafana:3000(可视化界面)
  • Alertmanager:9093(告警管理)

配置上有一个容易忽略的点:Prometheus拉取exporter指标时,默认是直接访问exporter的IP加端口。但如果两者都跑在同一个主机上,直接用 localhost 就行。后面容器化之后,我们不能再用localhost,而要换成容器网络中的服务名或IP,这是很多人配置了老半天发现targets down掉的常见原因之一。

3. 从零手动部署Prometheus Server

3.1 下载解压,用最小配置跑起来

开始动手。先下载Prometheus二进制包:

cd /opt/prometheus wget https://github.com/prometheus/prometheus/releases/download/v2.47.2/prometheus-2.47.2.linux-amd64.tar.gz tar -xzf prometheus-2.47.2.linux-amd64.tar.gz mv prometheus-2.47.2.linux-amd64 server cd server

解压后关键的文件就两个,prometheus是主程序,prometheus.yml是默认配置模板。先把默认配置备份,然后写一个最小可用的:

global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090']

这个配置的意思是:每15秒抓取一次自身暴露出来的指标。Prometheus自带的web服务除了UI,本来就会在/metrics暴露自身运行状态的指标,所以先拿自己当第一个监控目标是练手的入门常规操作。global里两个interval的含义先记住,scrape_interval控制数据采集频率,evaluation_interval控制告警规则计算的频率,后面排错会用到。

然后启动:

./prometheus --config.file=prometheus.yml --storage.tsdb.path=/opt/prometheus/data

启动后浏览器打开http://服务器IP:9090,就能看到Prometheus自带的简洁Web界面。切换到Status -> Targets页面,你会看到一个叫prometheus的目标,State是UP,这就是抓取成功的标志。如果只看默认页面右上角的Metrics,里面已经有大量go_开头、prometheus_开头的指标了,监听器、缓存、内存回收这些运行状态全在里面。

这就是“监控自身”跑通的过程。此时你再去看scrape_configs里的配置,很容易理解:每个job_name对应一组需要抓取的目标,每个target就是实际要访问的地址。一个Prometheus可以配置多个job,每种类型的监控目标一个job,便于管理和标签区分。

3.2 node_exporter手动接入Linux机器指标

光监控Prometheus本身没多大意义,第一件正经事是把宿主机的CPU、内存、磁盘这些基础指标采集进来。使命交给node_exporter,它本身也是个独立进程,监听9100端口,不需要你写太多配置,解压就能跑。

cd /opt/prometheus/exporter wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz tar -xzf node_exporter-1.7.0.linux-amd64.tar.gz mv node_exporter-1.7.0.linux-amd64 node_exporter nohup ./node_exporter --web.listen-address=:9100 &

跑起来后先自己验证一下:curl http://localhost:9100/metrics,如果能吐出一堆指标,说明exporter正常工作。node_exporter默认已经开启了几乎所有需要的采集器,包括cpu、memory、diskstats、filesystem、loadavg、netdev等,启动参数里都有开关,不需要动它。

接下来要让Prometheus去抓它。回到/opt/prometheus/server/prometheus.yml,把配置改成这样:

scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'node_exporter' static_configs: - targets: ['localhost:9100']

改完配置不会自动生效,两种方式:一种是重启Prometheus进程,另一种是给Prometheus发送热加载信号:

kill -HUP $(pidof prometheus)

热加载虽然方便,但注意如果新配置有语法错误,Prometheus会拒绝加载并继续用旧配置,此时日志会报错。所以我习惯先运行./promtool check config prometheus.yml检查语法,没问题再kill -HUP。回到Web UI的Targets页面,你应该能看到两个UP的目标。点开node_exporter那一行的Endpoint链接,能在Prometheus查询框里输入node_cpu_seconds_total,然后按下Execute,就能看到一堆带cpu、mode标签的时序数据。这一刻,监控体系就真正开始有业务价值了。

4. 容器化改造:用Docker把整套监控栈封装起来

4.1 把Prometheus容器化并持久化数据

二进制部署跑通后,接下来做容器化。为什么还要容器化?因为后续要监控的目标本身就是容器,而且生产环境里总不能一直用nohup起进程,一大堆exporter需要统一管理、版本升级、迁移环境,手工方式根本维护不过来。容器化不是目的,是把之前手工的部署流程固化下来,让任何人拿到配置就能复原整套环境。

先把Prometheus容器跑起来,这里有个关键点:因为Prometheus要保留历史数据,容器内的写入路径必须挂载到宿主机磁盘。

docker run -d \ --name prometheus \ -p 9090:9090 \ -v /opt/prometheus/server/prometheus.yml:/etc/prometheus/prometheus.yml \ -v /opt/prometheus/data:/prometheus \ prom/prometheus:v2.47.2

这条命令做了几件事:把宿主机的配置文件覆盖容器内的默认配置,把数据目录挂载成宿主机目录。但立刻会遇到一个问题:配置里写的target是localhost:9100,容器里的localhost指向容器的回环地址,宿主机上跑的node_exporter根本访问不到。此时你有两个选择:一是把node_exporter也容器化,让它们在同一个Docker网络里用别名互相访问;二是配置里改成宿主机在Docker网桥上的IP,通常是172.17.0.1。更通用的是第一种,既然都容器化了,就把所有目标一起容器化,用服务的名字通信。

4.2 用Docker Compose编排整套监控栈

手工docker run管理三四个容器已经够呛,如果再加Grafana和Alertmanager,就要写一大堆命令了。所以这里引入Docker Compose,它并不算“一键脚本”,而是把之前手动执行的每条docker run命令结构化声明到一个yml文件里,属于配置文件的升级版,依然保持了每一步的透明性。

在/opt/prometheus下新建docker-compose.yml,内容如下:

version: '3.8' services: prometheus: image: prom/prometheus:v2.47.2 container_name: prometheus restart: always volumes: - /opt/prometheus/server/prometheus.yml:/etc/prometheus/prometheus.yml - /opt/prometheus/server/rules.yml:/etc/prometheus/rules.yml - prometheus_data:/prometheus ports: - "9090:9090" node_exporter: image: prom/node-exporter:v1.7.0 container_name: node_exporter restart: always ports: - "9100:9100" cadvisor: image: gcr.io/cadvisor/cadvisor:v0.47.0 container_name: cadvisor restart: always ports: - "8080:8080" volumes: - /:/rootfs:ro - /var/run:/var/run:ro - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro grafana: image: grafana/grafana:10.2.3 container_name: grafana restart: always environment: - GF_SECURITY_ADMIN_PASSWORD=admin123 volumes: - grafana_data:/var/lib/grafana ports: - "3000:3000" volumes: prometheus_data: grafana_data:

用docker compose up -d就能全部拉起来。注意这里的prometheus.yml里,targets要对应改一下了:

scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['prometheus:9090'] - job_name: 'node_exporter' static_configs: - targets: ['node_exporter:9100'] - job_name: 'cadvisor' static_configs: - targets: ['cadvisor:8080']

你可能会疑惑,为什么配置里可以用prometheus、node_exporter这样的主机名?因为Compose会为所有服务创建同一个默认网络,服务名就是网络内的DNS名称,容器之间通过服务名互通。这也是容器化部署中最常见的一个知识盲区——换到容器环境,之前用IP直连的习惯要改成“用服务名解析”。

来看cadvisor的挂载参数,它要能读到宿主机真实的CPU、内存信息以及容器运行时状态,所以必须挂载宿主机根目录、sysfs、docker目录,否则没办法统计容器指标。这些挂载路径是cadvisor正常工作的前提,少一个就可能导致启动报错或指标缺失。Grafana的数据目录也做了持久化,因为之后你配置的数据源、导入的DashBoard、改过的Panel都是要保存的,容器删了数据不能跟着没。

这套Compose完成后,整套监控栈就全部容器化运行了。用docker compose ps查看状态,Prometheus、node_exporter、cadvisor、Grafana四个容器都应该处于Up状态。此时你可以cadvisor所在容器里执行curl localhost:8080/metrics,会看到大量container开头的指标,这些就是容器运行状态的数据来源。

5. 扩展监控维度:从宿主机到容器再到中间件

5.1 cAdvisor接入容器运行指标

为什么需要cadvisor?node_exporter只能看到宿主机视角的资源使用率,但宿主机上跑了十个容器,每个容器各消耗多少CPU内存?node_exporter的回答是把所有容器加在一起的宿主机总量,而cadvisor能看到每个容器独立的使用情况,因为Docker的cgroup体系本身为每个容器记录了资源使用数据,cadvisor就是把这些数据读出来并暴露成Prometheus格式。

cadvisor提供的主要指标包括:container_cpu_usage_seconds_total(容器CPU累计使用秒数)、container_memory_usage_bytes(容器内存使用字节)、container_network_receive_bytes_total(容器网络接收累计字节)、container_fs_usage_bytes(容器磁盘使用字节)。这些指标上通常带着container_label_com_docker_compose_service之类的标签,能直接按服务名分组,特别适合配合PromQL做聚合。

比如要查“每个容器的CPU使用率”,PromQL可以这么写:

rate(container_cpu_usage_seconds_total{container_label_com_docker_compose_service!=""}[5m])

rate()函数计算的是每秒增量,也就是瞬时速率,这是CPU使用率类指标最常用的计算方式。后面的5m是时间窗口,表示取最近5分钟的平均速率。窗口太短会显得抖动剧烈,太长会掩盖瞬时峰值,15s采集频率配5m窗口是我比较常用的组合。

5.2 常用exporter的接入模式

整个监控体系里的高价值扩展方向,就是接入各种中间件的exporter。每种exporter都是类似的套路:下载解压/容器化启动,暴露某个端口,把中间件的运行指标以Prometheus格式吐出来,然后你在Prometheus里加一个job,填上targets就行。学会这一个模式,后面接什么Redis、MySQL、Elasticsearch都通畅了。

举个例子,如果监控Redis,官方推荐用redis_exporter:

redis_exporter: image: oliver006/redis_exporter:v0.64.0 container_name: redis_exporter restart: always command: - '--redis.addr=redis://你的Redis地址:6379' - '--redis.password=你的密码' ports: - "9121:9121"

启动后访问9121端口,里面就有redis_up、redis_connected_clients、redis_memory_used_bytes等指标。加一行targets指向redis_exporter:9121,Prometheus立刻开始采集。注意redis_exporter的容器网络需要能连到Redis服务,如果在同一个Docker网络上,直接把地址写成服务名即可。

如果想要更细的链路状态,blackbox_exporter是必上的。它用来做“探活”,通过HTTP、TCP、ICMP等协议检测目标是否可访问,对站点返回码、响应耗时、证书过期时间等都能监控。它的配置方式跟常规的exporter不太一样,不是直接配target地址,而是让Prometheus在抓取它的同时带上module和target参数。不过这属于进阶玩法,初级先把核心监控跑起来,后面再慢慢加。

5.3 理解服务发现:从静态配置到自动发现

目前我们用的static_configs属于最简单的方式,写死IP或服务名。但容器环境下,容器实例会频繁新建、销毁,IP也不固定,单靠静态配置迟早会遗漏目标。Prometheus的解法是支持多种服务发现机制,比如基于Kubernetes的kubernetes_sd_configs,基于Consul的consul_sd_configs,甚至基于Docker的docker_sd_configs。

这里先不展开写一堆具体配置,但可以提前建立一个认知:服务发现的核心是让Prometheus能够动态获取监控目标的列表,而不需要每次容器变更后手动改配置文件。只要指定了服务发现方式和对应的查询标签,Prometheus会自动发现新容器、移除已消失的容器,并自动为每个目标加上相应的标签。手动搭建本质上是在为理解动态服务发现打基础——如果你连静态采集的链路都理不清,直接上服务发现很容易被各种标签搞得云里雾里。

6. 搭建可视化与告警体系

6.1 Grafana连接Prometheus并导入DashBoard

数据已经进了Prometheus,但9340个指标偶尔看一眼控制台还行,真要让团队日常使用,必须有个像样的可视化界面。Grafana就是干这个的。容器化启动很简单,前面Compose里已经带上了,默认账号密码是admin/admin,第一次登录会要求改密码。我起开发环境时往往直接通过环境变量设为GF_SECURITY_ADMIN_PASSWORD=admin123,跳过初次修改。

登录后第一步是配置数据源,左侧菜单 -> Connections -> Data sources -> Add data source,选Prometheus,URL填http://prometheus:9090(注意是容器网络内部地址,不要填localhost),点击保存。然后要验证联通性,Grafana会在页面底部显示“Data source is working”。

光配数据源还不够,还得有面板。最省力的办法是导入现成的DashBoard模板。Common里搜Node Exporter Full,ID是1860,也可以搜8919这种经典ID,但在新版Grafana里面,部分旧模板会有些小报错,问题不大。导入后选择数据源,就能立刻看到一整套漂亮的机器监控面板,包括CPU、内存、磁盘IO、网络流量等图表。这是很有成就感的时刻——之前手动采集的数据,瞬间变成了带趋势线、阈值线、单位换算的专业大屏。

如果想要容器监控面板,可以搜Docker Monitoring,有很多社区模板可用。导入之后你自然会发现,模板里的每条Panel其实就是一句PromQL查询加上一些图表配置。比如CPU使用率面板,背后可能就是100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)。看得多了,自己也就能写查询了。

6.2 Alertmanager的告警链路搭建与规则配置

监控不能只靠人肉盯着屏幕,告警才是真正让系统变得可运营的关键环节。Prometheus自带告警规则计算能力,但它不负责发送通知,推送的动作交给Alertmanager完成。

先准备规则文件,保存在/opt/prometheus/server/rules.yml,举个例子:

groups: - name: node_alerts rules: - alert: NodeHighCPU expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85 for: 5m labels: severity: warning annotations: summary: "Instance {{ $labels.instance }} CPU high" description: "Instance {{ $labels.instance }} CPU usage is above 85% for more than 5 minutes"

这个规则的含义是:CPU使用率大于85%,持续时间超过5分钟,就触发告警。for字段很关键,能防止瞬时抖动导致告警风暴,毕竟CPU跑到90%持续10秒和持续10分钟的处理优先级完全不一样。Prometheus会以evaluation_interval为周期计算这些规则,PromQL里检测到的结果为true时,告警进入Pending状态,等到满足for的时长后变成Firing,一系列状态变化在Prometheus UI的Alerts页面都能看到。

Alertmanager的配置主要是路由和接收器,最简化的配置长这样:

route: group_by: ['alertname'] repeat_interval: 4h receiver: 'webhook' receivers: - name: 'webhook' webhook_configs: - url: 'http://你的应用地址/webhook'

意一点:Prometheus本身不会向Alertmanager推送告警,它只负责定期计算规则,把满足条件的告警写入内存,然后持续告诉Alertmanager“我现在有哪些告警是Firing状态”。所以需要在Prometheus.yml里额外加一块配置:

alerting: alertmanagers: - static_configs: - targets: ['alertmanager:9093']

加完这部分,Prometheus才会主动建立与Alertmanager的连接,推送告警。把rules.yml和alertmanager配置都挂载到对应容器里,重启服务,链路就通了。之后,把webhook替换成钉钉、企业微信或者邮件的真实接收端,告警发出来一点问题没有。

6.3 告警速查与告警收敛:分组合并的实践意义

很多初学者实现了一个告警就觉得任务完成,结果没多久就收到几百条刷屏消息。原因是没有配置合理的分组和重复策略。Alertmanager的group_by参数定义了告警共享同一个通知的条件,比如按alertname分组时,同一时刻同一个指标名产生的所有实例告警会被合并成一条通知,而不是每个实例都发一封。

项目中我一般会加这样几个维度:业务线标签、服务的环境(生产/预发)、告警级别。这样能让一份通知邮件里包含相同业务线下的多个异常实例,而不是一条条轰炸。然后repeat_interval控制同一告警在依然存在时,隔多久重新发送一次,避免渠道被持续刷屏。这个值不宜太短,生产环境一般设置成4小时或更长,配合for字段基本能过滤掉一大部分无效打扰。

7. 实操中绕不开的坑与我的排查心得

7.1 常见问题速查表

这一节直接用一张表来总结,都是自己手动部署和排错时反复遇到过的典型问题,按症状、原因、解决办法列出,方便你以后对照:

症状常见原因解决方式
Targets页面看到目标State为DOWN目标服务没启动、端口不一致或防火墙拦截先在该目标宿主机上curl端口,确认能返回指标,再查Prometheus容器到目标的网络连通性
Prometheus容器启动后日志报错,界面无法访问配置文件格式错误,promtool检查失败执行docker compose config或promtool check config定位语法问题,注意缩进和引号
能访问Grafana但图表全部无数据数据源配置的URL写成了localhost把数据源地址改成http://prometheus:9090,或直接填宿主机IP
容器内时间显示正常,但监控数据出现时间间隔问题容器时区与宿主机不一致,影响告警时间戳展示在docker-compose里给各服务加TZ=Asia/Shanghai环境变量,并确保宿主机时区正确
磁盘占用快速增长,Prometheus数据目录越来越大没有配置数据保留策略,默认保留15天启动参数加--storage.tsdb.retention.time=7d或更短
总CPU使用率查询结果超过100或低于0PromQL表达式缺少适合的聚合,或误用rate与irate先确认指标单位,CPU使用率统一用rate(node_cpu_seconds_total[5m])后再做百分比运算
cAdvisor容器启动报权限错误或看不到容器指标缺少挂载/sys、/var/run等系统目录检查docker-compose里的volumes是否完整,cadvisor需要只读访问这些路径
告警规则一直不触发for时间设置太长、evaluation_interval太小、或规则文件没挂载以rule.yml文件挂载进容器内,参照Prometheus容器内的路径一致,用UI的Alerts页面看规则是否正常加载
改了配置后热加载成功但数据没变化可能Prometheus正在抓取周期内,或配置里的targets解析到了缓存IP检查容器网络,重启相关服务,确认生效区间

7.2 手动搭建后才看得透的三个关键点

第一,所有exporter本质上都是HTTP服务,都在提供一个89行左右的 metrics 接口。把它们塞进容器,或者让它们裸奔,都不影响Prometheus这个“拉取者”的工作方式。所以排查问题时不一定要跑到Prometheus容器里看,直接访问目标端口,看是否返回指标是最快的定位手段。

第二,配置文件和挂载路径要极度小心。容器化的挂载如果目标路径写错了,Prometheus会直接用镜像里配置的默认文件启动,而默认文件里没有你的targets,结果就是一切看起来正常但什么都没采集。所以每次挂载配置后,一定要用docker compose exec prometheus cat /etc/prometheus/prometheus.yml去验证容器里实际看到的配置是不是你写的。

第三,高基数问题要提前防范。标签的取值组合一旦爆炸,比如把请求ID、用户ID这种高价值变量放进标签,Prometheus的存储会被迅速撑爆。手动搭建阶段,你会接触到很多指标和标签,但给业务上自定义指标时,要记住标签是维度,不是日志正文。高基数标签必须规避,这是集群规模扩大后最凶险的一个坑。

7.3 两条后续扩展建议

这套手动搭建跑通后,我强烈建议你把它完整删掉重装一遍,并且不翻笔记。第二次搭建你会发现脑子里对配置文件的每个空格都有了概念,这才是真的掌握了,不是文件下载下来复制粘贴的那种“会了”。

如果接下来上生产,建议优先补两块:一是给Prometheus server加TLS和认证,最简单的做法是在前面挂一层Nginx,用basic auth限制访问9090端口,因为Grafana和Prometheus的web UI不推荐直接裸奔在公网。二是把配置文件纳入git仓库,rules、alertmanager、dashboard的json都统一管理,用CI校验配置再发布。手动搭建只是起点,工具化平台化是后面的事,但有了这份底层认知,后面做什么都稳。

最后分享一个小习惯:每次改动监控配置后,养成先promtool check config后热加载的习惯,这个命令能省掉你大量重启容器并在日志里找错的时间。自己搭一次,搭完再回头用docker-compose一把梭,你会发现一切都是那么清晰。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询