多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

node_exporter实战:从部署到Prometheus监控告警全流程

node_exporter实战:从部署到Prometheus监控告警全流程 1. 为什么服务器资源监控必须有个node_exporter先讲个真实场景。几年前我接管一套跑了三年的业务集群二十多台裸金属服务器监控全靠每天早上一遍top、free -h、df -h手工巡检出了问题就只能翻聊天记录找昨天是不是有人上了发布。直到有一天凌晨三点一台机器磁盘写满误报警电话打到值班手机上的时候已经是业务不可用的状态了。从那以后我下了个决心服务器资源监控这件事必须自动化必须可回溯必须能告警。后来就顺理成章接触到了Prometheus node_exporter这套组合。node_exporter是Prometheus生态里最基础也是最重要的一个exporter它干的事一句话就能说清把Linux服务器内核和系统层面的指标暴露成Prometheus能抓取的Metrics格式。CPU使用率、内存水位、磁盘空间和IO、网络流量、文件系统inode、系统负载、开机时长甚至网卡丢包、软中断分布全都能采到。你可以把它理解成一个系统体检仪的探针装在被监控的机器上默认在9100端口吐数据Prometheus定期来刮scrape一次数据就进了时序数据库。这篇文章面向的是刚接触监控平台、想把服务器资源监控真正落地的人。我会从node_exporter的部署细节、Prometheus端的抓取配置、Grafana可视化、告警规则一直讲到生产环境里我踩过的坑全程都是可以直接抄的配置和命令。不管你是运维、后端开发还是SRE照着走一遍一套能用的服务器资源监控平台就能跑起来。那为什么偏偏是Prometheus node_exporter而不是传统的Zabbix、Nagios因为Prometheus的Pull模型服务端主动拉取天然适合云原生和动态环境配置即代码告警规则用PromQL写灵活度远高于传统模板式监控。而node_exporter就是这个模型下最轻量、最成熟、社区维护最活跃的系统指标采集器。Prometheus是开源项目CNCF的毕业项目生态里Grafana、Alertmanager这些周边工具全是开源组件整套平台不需要花一分钱授权费这也是它能成为事实标准的原因。2. 装之前先想清楚版本、权限、端口和目录规划很多人装node_exporter就是下载二进制、nohup一把梭、然后配个抓取路径就完事了。本地测试没问题一上生产就各种出岔子。我建议在敲第一条命令之前先花十分钟把下面几件事定下来。2.1 版本怎么选才不给自己埋雷node_exporter的版本更新频率不算快但也不慢我见过最坑的情况是生产环境还跑着0.18版本连node_filesystem_avail_bytes这类指标的命名规范都不一样后来升级Prometheus之后直接导致旧面板全部失效。选版本就一条原则选官方GitHub Release页面上最新的稳定版同时看Release Notes里有没有breaking change。截至我写这篇文章node_exporter稳定版已经到1.8.xPrometheus则是2.53.x3.0也已经发布但生产环境我暂时不会主动升。1.x版本的指标命名和2.x之间有过一次大的变化现在的面板模板基本都按1.x命名来写的所以新装环境直接用1.8以上版本就好别回头去用0.x的老古董。Prometheus服务端的版本建议2.4x以上的长期支持版本。如果公司已经有现成的Prometheus跑着就不用重复装直接复用如果没有我建议服务端和exporter分开装服务端集中在专门的监控机器上exporter分布到各业务节点。2.2 运行用户与权限边界别用root跑exporter这是一个非常容易被忽视的点。node_exporter要读/proc、/sys这些内核文件系统来采集指标表面上看起来必须root但实际不是。官方推荐的运行方式是用一个专用的系统用户比如node_exporter用户只需要给它对/proc和/sys的读权限就够了这在对内核版本较新的系统上4.x是完全可以工作的。你可能会问很多网上的教程里都是root直接跑不也活得好好的对功能上没问题但安全上是隐患。node_exporter默认会开启--web.listen-address:9100如果你的9100端口暴露到了公网别人可以通过/metrics接口看到你机器几乎所有的系统信息用户名、内核版本、挂载点、网络配置这些信息对攻击者来说就是现成的踩点资料。用一个低权限用户跑至少把提权路径切断了一层。2.3 端口规划9100不是你想开就能开node_exporter默认监听9100端口。端口本身没什么特别但你要提前想清楚两件事第一Prometheus服务端到exporter的网络通路。如果两台机器之间有防火墙/安全组需要在防火墙上放行来源IP为Prometheus服务器IP、目标端口为9100的入站规则。这里有个血泪教训我曾经排查了一个小时为什么targets一直是down最后发现是云安全组只放行了80和4439100压根没开。第二9100端口尽量不要暴露到公网。它没有认证机制是纯明文HTTP服务。如果一定要暴露至少用防火墙限制来源IP或者用反向代理加一层Basic Auth。生产环境中更稳妥的做法是让exporter只监听内网IP比如--web.listen-address192.168.1.10:9100这样即使防火墙规则配错了外网也访问不到。2.4 目录规划二进制和数据的家要干净虽然node_exporter是无状态的服务不像Prometheus那样有数据目录但规范还是要有的。我习惯这样规划二进制目录/usr/local/bin/node_exporter配置文件目录/etc/node_exporter/textfile collector目录/var/lib/node_exporter/textfile/后面会详细讲systemd unit文件/etc/systemd/system/node_exporter.servicePrometheus服务端的目录规划也一并定了配置文件/etc/prometheus/prometheus.yml数据目录/var/lib/prometheus/规则文件放/etc/prometheus/rules/。这样无论是后面接Alertmanager还是加规则目录结构都清晰排查问题的时候不用翻半天。3. node_exporter的安装与启动每一行命令都讲清楚3.1 下载二进制并校验node_exporter是纯Go编译的静态二进制不依赖任何动态库解压就能跑这是它部署成本低的核心原因。下载方式如下# 到官方GitHub Releases页面找最新版本号 # 以1.8.2为例amd64架构 cd /tmp wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz tar xvf node_exporter-1.8.2.linux-amd64.tar.gz cd node_exporter-1.8.2.linux-amd64tar xvf解压后就是一个node_exporter可执行文件。拷贝到二进制目录并确认有执行权限sudo cp node_exporter /usr/local/bin/ sudo chmod x /usr/local/bin/node_exporter node_exporter --version看到类似node_exporter, version 1.8.2 (branch: HEAD, revision: ...)的输出就说明二进制没问题。这里一定要执行一次--version验证我遇到过下载了一上午发现是旧版本缓存文件的情况白折腾。如果是ARM架构的服务器比如鲲鹏、飞腾记得下载linux-arm64的包别下amd64的跑不起来的。提示从官网下载如果速度慢可以用国内镜像源或者让同事帮忙在能访问外网的环境下载后内网分发注意比对SHA256校验和别图省事直接拷。3.2 用systemd把exporter变成常驻服务这是最关键的一步。很多人图方便直接nohup ./node_exporter 这种跑法有几个问题开机不能自启、进程意外退出没人拉起来、日志管理混乱。正确做法是配置systemd服务。先创建运行用户sudo useradd -M -r -s /bin/false node_exporter参数说明-M不创建家目录-r创建为系统用户-s /bin/false禁止登录。这是安全基线一个不需要登录的服务账号不该有shell。然后写unit文件# /etc/systemd/system/node_exporter.service [Unit] DescriptionPrometheus Node Exporter Afternetwork.target [Service] Usernode_exporter Groupnode_exporter Typesimple Restarton-failure RestartSec5s ExecStart/usr/local/bin/node_exporter \ --web.listen-address:9100 \ --web.config.file/etc/node_exporter/web-config.yml \ --collector.textfile.directory/var/lib/node_exporter/textfile [Install] WantedBymulti-user.target启动并设置开机自启sudo systemctl daemon-reload sudo systemctl enable --now node_exporter sudo systemctl status node_exporter看到Active: active (running)就说明服务起来了再验证一下metrics接口curl http://127.0.0.1:9100/metrics | head -20正常会输出一堆以# HELP和# TYPE开头的指标文本。看到node_cpu_seconds_total、node_memory_MemTotal_bytes这些指标名说明采集已经工作了。3.3 web-config.yml给metrics接口加一层基础认证刚才提到9100端口不能裸奔其实官方从1.x就开始支持通过--web.config.file传入一个包含Basic Auth配置的文件这算是官方内置的最简单认证方案。生成密码需要用到htpasswd工具来自apache2-utils包sudo apt install apache2-utils # Debian/Ubuntu # 或者 yum install httpd-tools # CentOS/RHEL sudo htpasswd -B -c /etc/node_exporter/.credentials monitoring_admin生成/etc/node_exporter/web-config.ymlbasic_auth_users: monitoring_admin: $2y$05$省略哈希值...然后重启服务sudo systemctl restart node_exporter sudo chown node_exporter:node_exporter /etc/node_exporter/web-config.yml /etc/node_exporter/.credentials加了认证之后Prometheus服务端的scrape配置里也要对应配上用户名密码这个后面讲。注意一个细节web-config.yml和.credentials的文件权限要严格限定只允许exporter运行用户和root读取不然哈希泄露等于没设。3.4 采集器开关哪些默认开、哪些要主动关node_exporter按采集器collector组织功能每个采集器负责一类指标。看默认开启列表的方式curl -s http://127.0.0.1:9100/metrics | grep ^node_ | awk -F_ {print $2} | sort -u或者直接跑node_exporter --collector.disable-defaults --help但更直观的方式是访问http://127.0.0.1:9100/页面页面里会列出enabled collectors。默认情况下绝大多数采集器是开启的包括cpu、meminfo、diskstats、filesystem、netdev、loadavg、uname、time等等。这些对我们日常监控足够了。但有几个采集器偶尔需要按需调整systemd采集器默认关闭1.x里默认开启但要看具体版本如果你想监控目标机器上systemd服务的状态可以加--collector.systemd开启。它会暴露node_systemd_unit_state这类指标对服务健康监控很有用但要注意在高密度的机器上指标基数会比较大。textfile采集器默认开启的目录是空需要你主动指定--collector.textfile.directory然后自定义的脚本往这个目录写*.prom文件exporter会在每次抓取时读取这些文件把里面的metrics合并到输出里。这是node_exporter最灵活的扩展点后面细讲。perf、processes、selinux这些按需开启不需要就别开省一点CPU和内存开销。经验之谈采集器不是越多越好每个采集器都对应一组对/proc的读取操作开太多在高并发机器上会有些许额外开销。先默认跑几天看数据缺什么再补。3.5 textfile collector自定义指标的逃生舱实际监控中总有exporter原生不支持、但你又很想要的指标。比如某个服务的版本号、数据库连接数、昨天跑批任务的最终状态。这时候textfile collector就是你的逃生舱。原理很简单用一个shell脚本或cron任务把指标按Prometheus文本格式写入/var/lib/node_exporter/textfile/目录下的.prom文件node_exporter每次被抓取时都会扫描这个目录并把这些指标合并到输出。比如我想采集某个数据同步任务的当前状态脚本可以这样#!/bin/bash OUTPUT/var/lib/node_exporter/textfile/sync_status.prom if pgrep -f sync_job.py /dev/null; then echo sync_job_running 1 $OUTPUT else echo sync_job_running 0 $OUTPUT fi配合cron每30秒执行一次之后就能在Prometheus里用sync_job_running这个指标做告警了。这里有一个关键注意事项textfile目录的属主必须是node_exporter运行用户否则exporter没权限读文件你会在exporter日志里看到Error reading textfile然后该指标一直不存在。4. Prometheus端scrape配置让监控目标进入采集中node_exporter装好只是准备好了数据Prometheus服务端还得知道该去哪里拿、多久拿一次、拿的时候带什么参数。这一步全在prometheus.yml里完成。4.1 prometheus.yml的完整骨架一份能用的最小配置长这样# /etc/prometheus/prometheus.yml global: scrape_interval: 15s evaluation_interval: 15s external_labels: cluster: prod scrape_configs: - job_name: node_exporter static_configs: - targets: [192.168.1.10:9100, 192.168.1.11:9100] metrics_path: /metrics scheme: http basic_auth: username: monitoring_admin password: 换成你的密码 relabel_configs: - source_labels: [__address__] regex: ([^:]):9100 target_label: instance replacement: ${1}每个字段都有讲究。scrape_interval是抓取间隔15秒是社区默认值够用且不过度消耗如果监控对象是时序波动很大的指标比如连接数可以单独在job里覆盖为5s但要接受存储和查询压力的增加。static_configs是最简单的目标定义方式几台机器直接列出来。这种方式的问题在于当你新增一台机器时要手动改配置并reload Prometheus。目标多到几十台之后静态配置就会变得难以维护这时候就需要文件发现file_sd或者Consul服务发现这个后面说。basic_auth对应我们给node_exporter加的密码认证。注意密码是明文写在配置文件里的所以要确保prometheus.yml的文件权限是600只有Prometheus进程用户能读。4.2 scrape_interval与evaluation_interval怎么定这两个间隔经常被人混淆。scrape_interval决定了Prometheus多久来exporter抓一次数据影响的是数据采样频率evaluation_interval决定了Prometheus多久计算一次告警规则影响的是告警判定频率。我的建议默认都是15s但evaluation_interval可以稍微拉长到30s因为告警规则里通常带着类似for: 5m的持续时间条件判频繁了没有意义反而增加CPU开销。抓取间隔如果太小比如1snode_exporter本身倒是撑得住但Prometheus的存储和查询压力会成倍增长数据点增多后Grafana查询也会变慢磁盘占用也会涨。15s对服务器资源监控完全足够这个参数真的不用卷。4.3 静态配置与文件发现从一台到一百台机器少的时候静态配置没问题一旦规模上来每次加机器都改配置太痛苦。Prometheus提供file_sd_configs把targets列表放到一个独立的JSON或YAML文件里Prometheus会定期重新读取这个文件不需要重启。文件发现配置方式scrape_configs: - job_name: node_exporter file_sd_configs: - files: - /etc/prometheus/targets/node_exporter.yml refresh_interval: 30stargets文件内容- targets: [192.168.1.10:9100, 192.168.1.11:9100] labels: env: prod group: web这样加机器的时候只需要往这个文件里追加一行Prometheus最多30秒后就会自动pickup新目标。配合一些自动化运维工具比如Ansible批量生成targets文件加机器就可以做到全自动。如果公司已经用了Consul或者Kubernetes那更推荐consul_sd_configs或kubernetes_sd_configs服务上下线完全动态感知。不过对于纯裸机监控场景file_sd已经足够解决90%的需求先把这套跑熟再考虑更复杂的服务发现不迟。4.4 relabel给指标打标签的正确姿势relabel_configs可能是新手最绕的部分但也是Prometheus最有威力的特性之一。它的核心作用是在抓取之前改写target的标签从而控制和丰富数据的维度。我常用的一个场景是把IP地址转成更友好的instance名。默认情况下每个时序的instance标签就是target的ip:port比如192.168.1.10:9100。在Grafana上看到一堆IP很难一眼看出是哪台业务机器。所以我通常会加一条relabel把instance改写为主机名relabel_configs: - source_labels: [__address__] regex: ([^:]):.* replacement: ${1} target_label: instance更高级一点可以通过DNS反向解析或者读取一个映射文件来打标签。比如我在内网维护了一个/etc/hosts风格的映射配合正则提取主机名来给机器打上role标签这样后续的告警规则就能按这组机器都是数据库来区分策略。Relabel的调试要细心每改一次配置在Prometheus的Targets页面刷新看label是否如预期。判断一个relabel写对没写对最直接的办法是看target列表里instance标签的值和你想的是否一致。记住一句话relabel是改标签不是改数据想清楚你要在哪个维度上分组、聚合再来写relabel。4.5 配置生效与验证修改完prometheus.yml之后强烈建议先做语法校验再reloadpromtool check config /etc/prometheus/prometheus.ymlpromtool是Prometheus自带的命令行工具在二进制包解压后的目录里就能找到。校验通过后用Prometheus的reload接口优雅生效不用重启进程curl -X POST http://127.0.0.1:9090/-/reload前提是你的Prometheus启动时带了--web.enable-lifecycle参数。看了眼Targets页面Status → Targets看到node_exporter的target状态是UP就说明抓取链路已经完全打通了。5. Grafana接进来仪表盘看什么才有价值数据进了Prometheus也才是半成品。大多数人看监控的习惯是图标要全、颜色要炫但真到了故障排查的时候一屏花花绿绿里找不到有用的信息。这块我来说说怎么把Grafana和数据结合好以及哪些面板值得留。5.1 数据源与基础面板配置Grafana的安装不是本文重点简单提一句官方支持rpm/deb包安装和docker方式装好后第一次访问默认3000端口admin/admin登录。加数据源的时候选择Prometheus类型URL填Prometheus的地址比如http://localhost:9090保存并测试连通性就行。Grafana社区有大量现成的dashboard模板node_exporter最常用的模板ID是1860名字叫Node Exporter Full覆盖了CPU、内存、磁盘、网络、文件系统等几乎所有node_exporter能采集的指标面板也做了合理的分组。在Grafana里通过Import功能填入1860选择对应的Prometheus数据源一套完整的监控看板就有了。5.2 必须盯住的几个核心面板有经验的监控者不会同时盯几十个图表而是盯几个能反映全局状态的核心指标。我的习惯是至少保证下面这几个面板存在CPU使用率与负载100 - (avg by (instance) (rate(node_cpu_seconds_total{modeidle}[5m])) * 100)配合node_load1、node_load5看负载趋势。注意多核机器的load值要和核数对比看不是一个绝对值就能定论的。内存使用率(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100这个最直观MemAvailable已经把缓存算进去了比MemFree更准确。磁盘空间与inodenode_filesystem_avail_bytes{mountpoint/} / node_filesystem_size_bytes{mountpoint/}inode用node_filesystem_files_free / node_filesystem_files这一组面板能提前预警磁盘满了但现象还没爆发的情况。磁盘IOrate(node_disk_read_bytes_total[5m])和rate(node_disk_written_bytes_total[5m])适合定位慢查询、大数据同步这类IO密集问题的根因。网络流量rate(node_network_receive_bytes_total[5m])和rate(node_network_transmit_bytes_total[5m])按网卡维度区分排查流量异常时非常有帮助。5.3 面板设计的两个原则第一面板数量要克制。除非你的屏幕是电视墙不然一屏放超过12个面板基本就是灾难。故障时你需要的不是最全的仪表盘而是最快定位问题的那个。第二时间范围切换要顺手。Grafana右上角的时间选择器是排查问题的利器出问题的那一刻的数据才是真正有价值的数据。通常是先用30分钟看短期波动发现异常再逐步缩小到10分钟、5分钟直到找到突变点。所以我建议把最近15分钟固定成一个快捷选项省得到时候还手动改时间。6. 告警规则从看监控到被监控叫醒监控平台真正产生价值是从告警规则配置好的那一刻开始的。Prometheus用PromQL写告警规则天然可以表达过去5分钟CPU持续超过90%这类带窗口条件的逻辑这在传统监控里写起来非常繁琐。6.1 告警规则的语法结构规则文件通常放在/etc/prometheus/rules/目录下然后在主配置里引用# prometheus.yml 里追加 rule_files: - /etc/prometheus/rules/*.yml规则文件本身长这样groups: - name: node_exporter_alerts rules: - alert: HighCpuUsage expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{modeidle}[5m])) * 100) 85 for: 10m labels: severity: warning annotations: summary: {{ $labels.instance }} CPU使用率过高 description: CPU使用率已持续超过85%当前值{{ $value | printf \%.2f\ }}%for: 10m是关键意思是这个条件持续成立10分钟才触发告警。这个机制非常有用它过滤掉了瞬间的CPU尖峰、短时的网络抖动等噪声只有持续异常才会通知你。不要为了减少告警量而把这个时间设得太长否则真正的问题也会被过滤掉我的习惯是5~10分钟。6.2 生产环境必配的几条规则根据我实际运维的经验下面这几条规则几乎是每套监控平台都要有的覆盖了最频发的故障类型groups: - name: node_exporter_basic rules: - alert: InstanceDown expr: up 0 for: 1m labels: severity: critical annotations: summary: 监控目标 {{ $labels.instance }} 已宕机 - alert: HighMemoryUsage expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 90 for: 5m labels: severity: warning annotations: summary: {{ $labels.instance }} 内存使用率超过90% - alert: DiskWillFillIn4h expr: predict_linear(node_filesystem_avail_bytes{mountpoint/}[1h], 4 * 3600) 0 for: 10m labels: severity: critical annotations: summary: {{ $labels.instance }} 磁盘预计4小时后写满 - alert: HighDiskIo expr: rate(node_disk_io_time_seconds_total{device~sd.*}[5m]) 0.8 for: 10m labels: severity: warning annotations: summary: {{ $labels.instance }} 设备 {{ $labels.device }} IO使用率过高这里面最有用的一条我单独拿出来说DiskWillFillIn4h用的是predict_linear函数。它不是简单判断当前用了多少而是基于过去1小时的磁盘消耗趋势线性拟合预测4小时后的剩余空间是否会变成负数。这意味着你能在磁盘真正写满之前好几个小时收到预警给自己留足清理和扩容的时间。这种预测型告警才是Prometheus告警相对传统监控的高级之处。6.3 Alertmanager与通知链路规则触发后产生的是Alert但要把Alert送到钉钉、企业微信、邮件或电话还需要Alertmanager组件。部署Alertmanager不在本文展开但它的通知链路要清楚Prometheus根据规则计算 → Alert状态变为pending → 持续满足for条件后变为firing → Prometheus把firing状态的Alert推给Alertmanager → Alertmanager按路由规则分发到对应的receiver钉钉机器人、邮件组、webhook等。Alertmanager的价值除了分发还有告警去重、分组、抑制和静默。比如同一台机器同时触发了磁盘告警和IO告警Alertmanager可以把它们合并成一条通知而不是瞬间给你轰炸十几条。对于刚上手的人先把通知发到钉钉/微信群就够了后面再逐步完善值班路由和静默策略。7. 踩坑实录从采集空白到告警轰炸的排查全过程配置看起来都照着文档做了但生产环境总会有各种文档没写的问题。这一节我挑了四个我真实踩过、而且非常有代表性的问题完整还原排查链路希望你能少走弯路。7.1 问题一Targets里UP了但查询却拿不到数据现象Prometheus的Targets页面显示node_exporter是UP但到Graph页面输入node_cpu_seconds_total结果却是No data。排查过程UP说明网络通、抓取成功那问题大概率在数据本身。我先检查了抓取时间是否已经是历史很久之前发现不对然后我手动curl了exporter的metrics接口发现指标名明明存在。接着我去看了Prometheus的日志发现一条关键信息查询超时或者样本被丢弃out of order。根因我们的Prometheus实例上运行了多个job其中有一个job的抓取间隔设置成了1s样本量太大导致本地TSDB写入压力剧增部分样本写入失败。然后Grafana查询时用的大窗口正好命中那些丢失样本的时间段。解决把那个高频抓取job的间隔改回15s同时清理了TSDB的旧数据恢复了写入。经验UP只是抓取成功不代表数据完整可靠。如果发现查询结果经常有空洞先考虑样本量是否过大、是否有高频抓取job再考虑磁盘IO和Prometheus本身资源是否瓶颈。7.2 问题二node_exporter端口被扫描爆破现象上线一周后安全团队发来告警说有台机器9100端口流量异常来源IP遍布全球。排查过程这类情况在公网机器上很常见9100端口没有认证任何人都可以拉取metrics信息。我们第一反应是看exporter进程是否异常确认没有再查操作系统日志发现大量来自外部IP的TCP连接请求。根因9100端口暴露在公网既没有云安全组限制也没有Basic Auth等于是把系统信息透明地放在公网上。解决马上在云安全组和系统防火墙两层做了限制只允许Prometheus服务器的IP访问9100同时给exporter加上了web-config.yml的Basic Auth配置。经验凡是没有认证的服务一律不要暴露公网。即便是内网也建议加认证或者至少用防火墙约束来源IP别赌内网很安全。7.3 问题三textfile collector目录权限不对指标一直不出现现象我写了一堆自定义脚本往/var/lib/node_exporter/textfile/写.prom文件但Prometheus里就是查不到对应指标。排查过程我先在exporter所在机器上执行curl http://127.0.0.1:9100/metrics | grep xxx发现自定义指标确实不在输出里。再查看systemd服务的日志journalctl -u node_exporter -f看到了Error reading textfile: open /var/lib/node_exporter/textfile/xxx.prom: permission denied。根因创建目录时用的是root用户而exporter进程是以node_exporter用户运行的没有读权限。解决sudo chown -R node_exporter:node_exporter /var/lib/node_exporter/textfile/重启exporter后指标正常出现。经验所有和exporter运行用户相关的目录权限问题在node_exporter的日志里都会明确报出来第一件事就是journalctl -u node_exporter看日志比瞎猜快得多。7.4 问题四高基数标签把Prometheus内存吃光现象监控平台跑了一个多月后Prometheus的内存占用持续上涨最终把监控服务器搞到OOM反复重启。排查过程内存上涨通常是时序基数爆炸导致的。我进入Prometheus的TSDB状态页发现序列数量远超预期。再一查发现是另一个团队在node_exporter的relabel配置里加了__meta_*标签到最终指标导致时间序列维度激增。根因高基数标签比如把进程的某个随机ID当作标签会让每个时间序列变成独立的序列几万甚至几十万个序列直接把内存吃满。这是Prometheus最典型的隐性事故。解决删掉那个高基数relabel同时在设计标签时立了一条规矩标签的取值规模必须可控枚举值超过100个的字段不建议做标签。经验Prometheus的性能问题九成出在高基数标签上。监控平台稳定运行后定期检查TSDB的序列总数量一旦出现异常上涨先查标签设计再查relabel最后再考虑扩容。8. 最后沉淀监控平台维护的几点体会踩了这么多坑说点我个人的经验沉淀。第一监控平台本身也是系统需要带着管理的思路去维护。node_exporter和Prometheus的版本升级要留出回归窗口Grafana面板的改要有记录告警规则的变更要有评审总之不要让监控平台变成无人维护的孤儿系统。第二数据准确性比面板美观重要得多。我见过很多团队花大力气调Grafana主题色、配大屏却连node_time_seconds这种时钟同步指标都不看。服务器时间漂移会导致所有时序数据的对齐出问题这个指标虽然不起眼但我会专门配一条告警规则时差超过5秒就告警。数据准确了面板再朴素都有价值。第三监控是一个持续演进的过程先跑通基础链路再逐步加告警、加自动发现、加对接CMDB这个过程本身就是对整个基础设施认知的深化。node_exporter只是这套平台的起点但它是每一台服务器都值得配置的底线。最后再分享一个小技巧每次配置完告警规则用promtool check rules /etc/prometheus/rules/*.yml做语法校验再顺手用Prometheus console页面输入告警表达式确认有数据返回这样能避免很多规则写错了但没人发现的尴尬。一次配好长期受益。
返回列表