资讯动态

Prometheus部署避坑指南:架构、配置与告警实战

发布时间:2026/10/5 11:33:58 来源:尧图企业网站定制
部署Prometheus这事儿看着网上教程一大堆真正上手总会碰到几个文档里没写的隐形坑。我第一次在生产环境搭的时候以为就是把tar包解压、跑起来就完事结果第二天就遇到target全部down、Grafana面板不出图、告警邮件收不到三个问题连着一起来折腾了一整晚。后来把整个链路——采集、存储、告警、展示——拆开一个个排查才发现全是些不起眼的小细节权限不对、配置没重载、数据源URL多写了前缀。这篇我不打算只贴一遍安装命令而是把从零开始部署Prometheus的完整过程、每个关键配置为什么要这么写、以及装完之后最容易出问题的几个场景一并整理出来希望对正要上手或者已经在部署中卡住的你有实际帮助。1. 装之前先弄明白Prometheus这套体系到底由什么组成很多人以为装了Prometheus就等于有了监控其实等真正用起来才发现Prometheus只是一个指标采集和存储的核心完整的可观测链路还包含exporter采集器、Alertmanager告警分发和Grafana可视化。我建议你在动手下载安装包之前先花二十分钟把整个架构在纸上画一遍否则后面配置会一头雾水。1.1 为什么是Prometheus而不是其他监控方案先讲个背景。Prometheus 是一款开源的系统监控和告警工具最开始由SoundCloud开发2016年加入CNCF现在是云原生监控的事实标准。它最核心的设计特点是拉取Pull模式Prometheus Server主动去各个目标抓取指标而不是等客户端推上来。这个设计带来几个实际好处被监控节点不需要装Agent只要暴露一个HTTP端口就行对业务入侵小。哪些目标存活、哪些目标挂了是一目了然的拉不到就是挂了天然具备探活能力。配置改动集中在服务端扩容和调整监控范围时只需要改Prometheus配置不需要动被监控端。当然Pull模式也有代价比如监控对象必须能被网络访问到跨网段抓取时需要在防火墙上开端口好在实际使用中这对我们内部系统影响不大。整个体系里你会频繁接触几个组件我把它们的关系和用途整理成一张对照表组件作用默认端口什么时候需要Prometheus Server指标拉取、存储、规则计算9090必然需要Node Exporter采集Linux主机CPU、内存、磁盘等指标9100被监控的每台Linux机器snmp_exporter采集网络设备、打印机等SNMP指标9116监控交换机、路由器、无线AP时使用mysqld_exporter / postgres_exporter采集数据库指标9104 / 9187监控数据库时使用Alertmanager接收告警并做路由、去重、发送通知9093需要告警通知时使用Grafana指标数据可视化展示3000需要出图表时使用如果你只是临时验证只装Prometheus Server和Node Exporter就够了但正常生产环境我建议一次把这套全部规划进去免得后面监控需求一变又要来回补装。1.2 完整的部署链条长什么样我的经验是一套能真正用起来的Prometheus部署至少包含下面五步部署Prometheus Server跑通抓取链路。在被监控机器上部署exporter比如Linux机器部署node_exporter网络设备用snmp_exporter。在Prometheus配置里增加抓取任务让target状态变成UP。部署Alertmanager并配置告警规则、通知渠道。部署Grafana接入Prometheus数据源把指标做成可视化面板。这五步有明确的依赖关系——先有数据才能谈告警和展示。我见过很多人第一步都没验证target就急着配告警结果规则写了一大堆一个告警都没触发过根本不知道规则有没有生效。2. 二进制安装与systemd托管最不容易出错的部署方式Prometheus的安装方式有好几种二进制包、Docker容器、Kubernetes Operator、包管理器。如果是在Linux服务器上部署我最推荐二进制包加systemd托管原因很直接二进制包不依赖容器运行时故障排查简单systemd能保证开机自启和异常重启而且资源占用非常低。2.1 下载、解压与基础配置先到Prometheus官网下载对应架构的安装包。以Linux amd64为例我通常按下面的步骤操作# 下载版本号按需替换我这里用2.53.0举例 wget https://github.com/prometheus/prometheus/releases/download/v2.53.0/prometheus-2.53.0.linux-amd64.tar.gz # 解压 tar -xvf prometheus-2.53.0.linux-amd64.tar.gz # 移动到统一目录 mv prometheus-2.53.0.linux-amd64 /opt/prometheus # 创建数据目录 mkdir -p /opt/prometheus/data这里有一个比较容易忽略的点Prometheus官方下载包默认不携带systemd配置文件也默认以当前用户运行。直接root跑也不是不行但不符合安全习惯而且如果后面你加了很多采集任务Prometheus的WAL、快照文件权限没规划好可能在重启时出现“permission denied”。我的做法是单独建一个系统用户# 创建prometheus用户不允许登录 useradd --no-create-home --shell /bin/false prometheus # 修改目录属主 chown -R prometheus:prometheus /opt/prometheus然后看看默认配置文件初次启动其实只需要一个最小的prometheus.ymlglobal: scrape_interval: 15s # 采集间隔默认1分钟我习惯改成15秒 evaluation_interval: 15s # 告警规则评估间隔 scrape_configs: - job_name: prometheus static_configs: - targets: [localhost:9090]上面这段先自监控自己确认服务能正常起来。等基础链路通了再逐步增加其他抓取任务这样出问题时排查范围小不会一上来几十个target全部失败根本不知道从哪看起。2.2 systemd服务管理细节配置文件准备好了接下来把它注册成systemd服务。这一步非常关键很多人直接nohup跑服务器一重启Prometheus就没了这种部署方式在生产环境说不过去。在/etc/systemd/system/prometheus.service里写入下面的内容[Unit] DescriptionPrometheus Server Documentationhttps://prometheus.io/docs/introduction/overview/ Afternetwork.target [Service] Userprometheus Groupprometheus Restartalways ExecStart/opt/prometheus/prometheus \ --config.file/opt/prometheus/prometheus.yml \ --storage.tsdb.path/opt/prometheus/data \ --storage.tsdb.retention.time30d \ --web.listen-address0.0.0.0:9090 [Install] WantedBymulti-user.target启动并设置开机自启systemctl daemon-reload systemctl start prometheus systemctl enable prometheus systemctl status prometheus如果服务启动失败用journalctl -u prometheus -n 50看日志。我碰到过一个很典型的错误是启动时提示“open /opt/prometheus/data: permission denied”原因就是忘了chown数据目录。关于参数我再补一句使用经验--storage.tsdb.retention.time控制数据保留时间我这里设置30天。对于大部分内部监控场景30天足够看趋势和排查问题又不会占用太多磁盘。如果你机器磁盘小可以按实际改成15d或7d。--storage.tsdb.path指定数据目录务必放在有独立磁盘或分区足够大的路径下。TSDB的数据增长比很多人想象的要快尤其采集目标多、采集频率高的时候。启动成功后浏览器访问http://服务器IP:9090能看到Prometheus自带的简单查询页面说明Server本身已经OK了。这个页面在后续排查时特别有用可以直接在“Status - Targets”里看到所有采集目标的状态。3. prometheus.yml配置实战抓取目标、采集频率与标签体系Prometheus的连接配置核心都在prometheus.yml里这一节我把三类最常见的抓取场景分别讲清楚本机指标、远程Linux主机指标、交换机等网络设备指标。每个场景都会涉及一些容易犯错的地方我先把配置文件的结构和原理说明白。3.1 全局配置和抓取任务先看一段在真实生产环境用得很多的配置骨架global: scrape_interval: 15s evaluation_interval: 15s external_labels: env: production scrape_configs: - job_name: linux-node static_configs: - targets: - 192.168.1.10:9100 - 192.168.1.11:9100 labels: group: web-serversglobal里面的scrape_interval控制默认抓取频率evaluation_interval控制Prometheus多久评估一次告警规则。注意这是全局默认值单个scrape_config里可以用scrape_interval覆盖。比如数据库的指标采集频率可能不需要那么高设成30s就可以而业务关键指标可能需要5s一次。external_labels是外部标签当Prometheus把数据发给Alertmanager或者其他系统时会随数据附带上这些标签常用于区分多套环境。比如测试环境和生产环境使用同一个Alertmanager靠env标签就能区别告警来源。scrape_configs里每个job_name代表一个监控任务。targets列表里写被监控对象的IP:端口。static_configs是最简单的静态目标配置方式——目标固定不变时很合适。如果服务器数量经常动态变化后面我会讲到用文件发现或Consul发现这里先不展开。一个非常容易踩坑的地方targets里的地址不要在目标地址前面加http://。Prometheus抓取时默认使用http协议你要是写成http://192.168.1.10:9100它会解析成http://http:/...这种畸形地址最终Targets页面会显示“parse target URL failed”。同理如果被监控端点启用了HTTPS需要在该job下单独配置scheme: https。3.2 用snmp_exporter监控交换机配置逻辑与实操示例“Prometheus监控交换机”是很多人会遇到的需求。交换机这类网络设备不暴露HTTP接口不能直接用node_exporter通常的做法是通过snmp_exporter把SNMP协议转换成Prometheus能抓取的指标格式。snmp_exporter的部署方式和Prometheus类似二进制解压、systemd托管即可。它的配置分两步第一步在snmp_exporter目录下准备一个snmp.yml这个文件定义了每种SNMP OID对应什么Prometheus指标。不用手写大部分常见设备型号在官方仓库都有现成的下载即可wget -O /opt/snmp_exporter/snmp.yml https://raw.githubusercontent.com/prometheus/snmp_exporter/main/snmp.yml第二步在Prometheus的scrape_configs里添加一个任务让Prometheus去抓snmp_exporter而不是直接去抓交换机scrape_configs: - job_name: network-devices static_configs: - targets: - 192.168.100.1 # 交换机的IP注意这里不是snmp_exporter的地址 - 192.168.100.2 metrics_path: /snmp params: auth: [public_v2] module: [if_mib] relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: 127.0.0.1:9116这段配置看起来有点绕我拆开解释一下targets里写的是设备地址但Prometheus实际上要访问的是snmp_exporter的127.0.0.1:9116。Prometheus会先读取__address__此刻是设备IP通过relabel_configs把这个IP赋给__param_target再添加为instance标签。最后把__address__替换成snmp_exporter的地址。这样Prometheus发请求时URL会变成http://127.0.0.1:9116/snmp?target192.168.100.1authpublic_v2moduleif_mibsnmp_exporter收到后去轮询交换机。relabel_configs是Prometheus里非常灵活但也比较难懂的功能初次接触时可以先照着抄后面再深入研究。配置完成后在Targets页面应该能看到两个UP状态分别对应两台交换机。if_mib模块采集的是接口流量、状态等基础指标用于监控网络设备的常见需求足够了。4. 告警规则配置详解从一条rule到一套可用的告警系统采集到指标是第一步真正让监控有价值的是告警。Prometheus的告警规则文件负责“什么时候触发”Alertmanager负责“触发之后怎么办”。两者配合才能形成完整的告警链路。4.1 规则文件的结构与分组在prometheus.yml中通过rule_files引入规则文件rule_files: - /opt/prometheus/rules/*.yml规则文件按“组group”组织每组有一个名字和一组规则。相同组里的规则按顺序评估默认间隔由全局的evaluation_interval控制。一个最常用的规则文件示例groups: - name: host_alerts rules: - alert: CpuHighUsage expr: 100 - (avg(rate(node_cpu_seconds_total{modeidle}[5m])) * 100) 85 for: 10m labels: severity: warning annotations: summary: CPU使用率超过85% description: 实例 {{ $labels.instance }} 的CPU使用率已达 {{ $value | humanizePercentage }}持续超过10分钟。 - alert: DiskHighUsage expr: (1 - (node_filesystem_avail_bytes{fstype!~tmpfs|overlay} / node_filesystem_size_bytes{fstype!~tmpfs|overlay})) * 100 90 for: 5m labels: severity: critical annotations: summary: 磁盘使用率超过90% description: 实例 {{ $labels.instance }} 的挂载点 {{ $labels.mountpoint }} 使用率已超过90%。几个关键点我单独强调一下expr是PromQL表达式它的计算结果决定告警是否触发。注意node_cpu_seconds_total这类counter指标一定要搭配rate()函数使用直接查原始值没有意义。for字段非常有用它表示指标满足条件后需要持续多久才触发告警用来过滤瞬时抖动。例如CPU飙高10分钟才告警能避免很多“假告警”。labels和annotations的区别labels是告警的标签可以用于Alertmanager路由匹配annotations是告警的描述说明最终会在通知内容里展示。模板变量**{{ $labels.instance }}会替换成触发告警的实例标签值{{ $value }}**是当前指标值。多实例共用一条规则时每个实例触发都会在通知里带出自己的信息非常好用。写完规则文件后可以用promtool做静态检查这个工具在解压包里就有/opt/prometheus/promtool check rules /opt/prometheus/rules/host_alerts.yml有语法错误它会直接报错没错误再重载配置。4.2 接入Alertmanager才能让告警真正通知到人Prometheus本身只负责“评估规则并生成告警”它不会直接发邮件或钉钉需要把告警发给Alertmanager。在prometheus.yml里配置alerting: alertmanagers: - static_configs: - targets: - 127.0.0.1:9093Alertmanager同样用二进制方式部署。它的核心配置文件alertmanager.yml解决的是“告警发给谁、怎么发、要不要聚合”的问题一个常见的配置global: smtp_smarthost: smtp.example.com:465 smtp_from: alertexample.com smtp_auth_username: alertexample.com smtp_auth_password: your-password route: group_by: [alertname] group_wait: 30s group_interval: 5m repeat_interval: 4h receiver: default-email receivers: - name: default-email email_configs: - to: opsexample.com路由规则是Alertmanager里最核心的部分。上面配置的含义是所有告警先按alertname分组30秒内到达的同类告警合并成一条如果同一组告警5分钟内没有新变化就不再重复发送真正重复发送间隔是4小时默认发给ops邮箱。如果要多级路由比如“严重告警发短信、一般告警发邮件”就要用routes做到route: group_by: [alertname] receiver: default-email routes: - match: severity: critical receiver: page-phone - match_re: severity: ^warning$ receiver: default-emailmatch是按标签值精确匹配match_re是正则匹配。根据我个人经验建议一开始不要设计太复杂的路由树先按severity分两条就够用等告警量真的大了再逐步细化。修改完Alertmanager配置需要重启或发送SIGHUP信号生效systemctl reload alertmanager一个特别容易忽略的告警链路问题是Prometheus的告警评估和Alertmanager的通知是两套独立系统。就算Prometheus的Targets全部UP、规则文件也没问题只要Alertmanager的接收渠道比如邮箱、Webhook配置有误告警就会卡在Alertmanager里发不出去。在调试阶段我建议先在Alertmanager页面打开“Status”看是否能看到活跃告警如果Prometheus告警能到达但你没收到邮件再去查Alertmanager日志journalctl -u alertmanager -n 1005. Grafana可视化把指标变成能让人看懂的图表Prometheus自带的查询页面适合临时验证做正式的监控大屏还是要用Grafana。Grafana是开源的可视化工具支持Prometheus、MySQL、Elasticsearch等多种数据源部署时间不会超过五分钟但要把面板配得好还是有讲究的。5.1 Grafana安装与数据源接入安装Grafana最省事的方式是直接用官方yum仓库或apt仓库以CentOS/RHEL为例sudo yum install -y https://dl.grafana.com/enterprise/release/grafana-enterprise-11.2.0-1.x86_64.rpm我这里用了企业版安装包其实核心功能在开源版里都有企业版只多了部分企业特性。装完启动systemctl start grafana-server systemctl enable grafana-server浏览器访问http://服务器IP:3000默认用户名和密码都是admin首次登录会提示修改密码。接下来添加Prometheus数据源左侧菜单选择“Connections - Data sources - Add data source”类型选PrometheusURL填写http://127.0.0.1:9090这里有个非常典型的问题如果Grafana和Prometheus不在同一台机器上这个URL要填成Prometheus所在服务器的实际IP端口如果填写时漏掉了端口或写成了https://测试数据源时会报“HTTP status 400 Bad Request”或“Bad Gateway”之类的错误。另外从Grafana 9.x以后录入数据源后右侧会有“Save test”按钮它能帮你直接验证连通性这个测试一定要点一下别嫌麻烦。5.2 仪表板导入与关键面板推荐自己从零拖一个面板也不是不行但更高效的做法是导入社区现成的Dashboard。Grafana官网有大量模板导入方式左侧“Dashboards - New - Import”输入Dashboard ID后点击Load。我经常用的几个模板Dashboard ID用途1860Node Exporter主机监控模板CPU、内存、磁盘、网络覆盖很全8919另一个不错的Node Exporter模板界面更现代化变量分组清晰11074网络设备SNMP监控模板适合配合snmp_exporter使用7362黑盒探针HTTP监控模板导入后可能会出现部分图表没有数据通常是变量或查询表达式不匹配。我的处理思路是先看面板右下角的“Data source”是否切换成你自己的数据源再看查询语句里的job名称是否和你Prometheus里的job_name一致。比如模板里写的是jobnode_exporter而你配置的任务名是joblinux-node所有图表都会是空的把查询里的job名替换掉即可。说到面板我再分享一下个人的习惯正式给客户或领导展示的监控大屏别贪多、别把所有指标堆一屏通常选四个角落主机CPU/内存/磁盘的使用率、网络进出口流量、关键服务的存活状态、资源告警数。人眼在短时间内只能处理有限信息一张干净的大屏远比几十个小图更实用。6. 部署之后的高频问题我的踩坑记录和排障思路前面讲了很多“怎么做”这一节我把部署和使用中真正让人头疼的几个问题集中说一下。这些问题在官网文档里很少被特别强调但几乎每次部署都会遇到。6.1 数据异常类问题时间戳、指标延迟与重启丢失问题一监控曲线整体延迟或数据出现断点。排查思路是先看node_time_seconds这个指标它暴露的是被监控机器的当前时间戳。如果Prometheus服务器和被监控机器的时间偏差超过几十秒采集到的指标会落在一个“未来”或“过去”的时间点Grafana里就会看到错位或空白。解决办法很简单所有相关服务器配置NTP时钟同步这是监控系统稳定性的前提。问题二Prometheus重启后部分历史数据查询不到。Prometheus默认写数据有一定延迟重启时WAL预写日志可能在落盘前丢失少量数据。要降低损失可以在启动参数里加上--storage.tsdb.wal-compression开启WAL压缩减少I/O压力。另外如果数据目录所在磁盘空间不够TSDB写操作会异常最明显的现象是日志里大量“chunk not found”或“mmap: Out of memory”需要检查磁盘剩余空间。问题三node_exporter采集到了指标但表达式查不到。这通常是因为抓取任务只在特定目标的labels上有差异而你PromQL里筛选条件过严。比如查询node_memory_MemTotal_bytes{instance192.168.1.10:9100}时如果instance标签实际是192.168.1.10端口缺失就查不到。排查时直接到Prometheus页面的“Status - Targets”里看具体target的Labels确认标签的真实内容。6.2 告警不触发、重复轰炸与配置重载问题问题一规则文件改了Prometheus不生效。修改/opt/prometheus/prometheus.yml或rules/*.yml后不需要重启Prometheus进程用下面的方式重载配置# 方式一发送SIGHUP信号 kill -HUP $(pgrep -f prometheus --config.file) # 方式二调用API需要开启--web.enable-lifecycle参数 curl -X POST http://127.0.0.1:9090/-/reload如果使用systemd管理也可以直接systemctl reload prometheus。需要注意的是使用curl方式必须要在启动参数中加--web.enable-lifecycle否则会提示API不可用。问题二告警重复轰炸同一个故障收到几十条通知。这种情况多半是Alertmanager的repeat_interval设得太短。这个参数的含义是“同一个告警组在多少时间后再次发送”默认是4小时。有些人为了尽快通知把repeat_interval设成10分钟结果一晚上手机响个不停。我个人的建议是首次通知靠group_wait尽快发出15~30秒纠错和通知靠repeat_interval拉长到3~4小时不要轻易调短。问题三告警明明在Alertmanager里但通知没发出去。按我的排查顺序走一遍第一看Alertmanager页面的“Status”里有没有活跃告警第二看Alertmanager日志确认是否正在调用通知接口第三确认接收渠道配置正确比如企业微信Webhook的URL和密钥是否填错。多数情况下问题出在接收渠道的认证信息上而不是规则本身。6.3 资源占用Prometheus到底需要多少内存和磁盘这个问题经常被问。需要说明的是Prometheus的资源消耗和目标数量、指标数量、抓取频率、告警规则复杂度强相关没有一个固定数字。我给一个粗略的经验值一台抓取100~200个节点、每节点约1000条时间序列的Prometheus内存大概在2~4GB之间磁盘每天新增约1~2GB。如果你机器配置紧张可以从这几个方向优化调大scrape_interval从15s改为30s指标数据量几乎减半。减少不必要的exporter指标比如node_exporter可以用--collector.disable-defaults配合--collector.enabled只开启需要的采集器。缩短retention.time只保留14天或7天数据。在抓取阶段用metric_relabel_configs丢弃不需要的高基数指标。对于中小规模部署这些优化足够让Prometheus跑得很轻松。如果优化后内存依然居高不下再考虑横向联邦或远程存储方案。我的收尾经验部署Prometheus不是“装完一个服务”就结束了它是一个需要持续运营的体系。在我自己维护过的几套监控系统里最值得投入时间的其实是初始配置阶段——把目标分类、标签规范、告警分级这些底子打好后面维护成本会低很多。比如说job_name的命名尽量用“业务含义组件”标签值统一用小写这样无论是查PromQL还是维护告警规则都省很多力气。另外提醒一句Grafana的面板尽量导出JSON备份Prometheus的配置文件定期归档到Git一旦误操作删了或者改坏几分钟就能恢复不用从零再来。希望这次的梳理能让你在部署的时候少熬夜、少踩坑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑