☰
Prometheus + Node Exporter 监控 Linux:从部署到告警实践
2026/10/17 1:34:04 网站建设 项目流程

监控Linux系统状态,从最原始的时候登录服务器敲top、df -h、free -m,到后来写脚本定时采集数据,再到折腾各种监控面板,这条路我基本都走过。如果你手里也有一批CentOS服务器,肯定遇到过这样的场景:业务方反馈系统卡了,等你登录上去负载又降下来了,什么证据都没留下;又或者是磁盘空间早就悄悄满了,直到告警电话打过来才发现。Prometheus搭配Node Exporter这套组合拳,解决的就是这类后知后觉的问题。这篇文章我会从方案选型、部署步骤、指标解读到告警配置完整梳理一遍,适合正在搭建基础监控、准备把Linux运行状态收进Prometheus的运维和开发同学参考。

1. 监控方案设计与核心思路

1.1 为什么选择Prometheus + Node Exporter

很多人在选监控方案的时候会纠结:用传统的Agent模式还是Prometheus这种拉取模式?我的结论很简单:如果你已经决定用Prometheus,那就别再犹豫,Node Exporter就是采集Linux系统指标最标准、最省心的选择。

Prometheus的监控模型是“服务端主动拉取”。被监控的机器上跑一个Exporter,它把系统状态变成HTTP接口上的指标数据,Prometheus按你配置的间隔定时去抓取。和传统的推模式相比,拉模式的最大好处是你随时能在监控端查看某台机器“当前还活着没有”,如果拉不到数据,那本身就是一条非常有用的告警信号。

Node Exporter是Prometheus官方维护的系统指标采集器,它通过读取/proc、/sys下的内核统计文件,把CPU、内存、磁盘、网络、文件系统、负载等几百项指标全部暴露出来。你不需要在被监控机器上安装额外的数据库或复杂的Agent服务,一个二进制文件加一个systemd服务就搞定,资源占用可以忽略不计。

1.2 监控拓扑与采集流程

整套系统的数据流是这样的:每台CentOS服务器上运行Node Exporter,监听9100端口,通过/metrics接口暴露指标;Prometheus服务器定期从这些目标抓取数据,按时间序列存储下来;Web UI和Grafana通过PromQL查询语句把数据变成面板和图表;告警规则一旦触发,就交给Alertmanager去通知。

刚开始搭环境的时候,你只需要一台机器同时跑Prometheus和Grafana做展示端,被监控的服务器单独跑Node Exporter,整个结构非常清晰。等机器数量多起来,再考虑把Prometheus单独放到一台机器上,或者增加一套监控高可用方案。

1.3 版本选型与前期准备

版本这块建议直接用官方最新的稳定版。我写这篇内容时,Prometheus稳定版在2.53左右,Node Exporter在1.8左右,Grafana在11.x。下载时认准Linux amd64的压缩包就行,如果你的服务器是ARM架构,记得选对应的arm64包。

部署前有几件事需要提前确认:一是服务器时间必须准确,Prometheus对时间偏差很敏感,时间不对会导致数据错位甚至抓取失败,建议先确认chrony或ntp同步正常;二是防火墙策略,Prometheus默认监听9090端口,Node Exporter监听9100端口,Grafana监听3000端口,这些端口要么放行,要么先临时关闭防火墙测试;三是准备好一个软件安装目录,比如/opt,后续的二进制文件和配置都放这里。

2. 在CentOS上部署Prometheus与Node Exporter

2.1 下载并安装Prometheus服务

先创建一个专用系统用户,避免直接用root运行监控服务,这是安全底线。然后下载、解压、移动到/opt目录下。

# 创建prometheus用户,不分配登录shell useradd --no-create-home --shell /usr/sbin/nologin prometheus # 准备目录 mkdir -p /opt/prometheus mkdir -p /etc/prometheus mkdir -p /var/lib/prometheus # 下载最新稳定版,实际版本号以官方页面为准 cd /usr/local/src curl -LO https://github.com/prometheus/prometheus/releases/download/v2.53.2/prometheus-2.53.2.linux-amd64.tar.gz # 解压并移动 tar -zxvf prometheus-2.53.2.linux-amd64.tar.gz cd prometheus-2.53.2.linux-amd64 cp prometheus promtool /opt/prometheus/ cp -r consoles console_libraries /etc/prometheus/ cp prometheus.yml /etc/prometheus/

这里有个细节我特意分开做了:二进制文件放到/opt/prometheus,配置文件和规则文件放在/etc/prometheus,数据目录放在/var/lib/prometheus。这样做的好处是升级时只需要替换二进制目录,不用动配置和数据,回滚也方便。

2.2 配置systemd服务并设置开机自启

手动执行Prometheus进程不现实,生产环境必须用systemd托管。创建一个服务文件/etc/systemd/system/prometheus.service:

[Unit] Description=Prometheus Server After=network.target [Service] Type=simple User=prometheus Group=prometheus Restart=on-failure ExecStart=/opt/prometheus/prometheus \ --config.file=/etc/prometheus/prometheus.yml \ --storage.tsdb.path=/var/lib/prometheus \ --web.listen-address=0.0.0.0:9090 \ --storage.tsdb.retention.time=30d [Install] WantedBy=multi-user.target

几个启动参数简单说明一下。--storage.tsdb.retention.time=30d控制数据保留时间,默认是15天,根据你的磁盘空间决定,我一般建议30天起步,方便做月度趋势对比。--web.listen-address默认就是0.0.0.0:9090,如果你本机访问不多,可以改成内网IP。

然后启动并设置开机自启:

chown -R prometheus:prometheus /opt/prometheus /etc/prometheus /var/lib/prometheus systemctl daemon-reload systemctl enable --now prometheus systemctl status prometheus

用curl localhost:9090/-/ready检查响应,返回Prometheus Server is Ready就说明服务起来了。这时候访问http://服务器IP:9090就能看到Prometheus自带的基础UI页面。

2.3 部署Node Exporter采集Linux指标

被监控的CentOS机器上,同样先创建用户,下载Node Exporter,然后用systemd托管。重复的步骤我不再赘述,只把服务文件单独列出来:

[Unit] Description=Node Exporter After=network.target [Service] Type=simple User=node_exporter Group=node_exporter Restart=on-failure ExecStart=/opt/node_exporter/node_exporter \ --web.listen-address=:9100 \ --collector.systemd \ --collector.processes [Install] WantedBy=multi-user.target

--collector.systemd和--collector.processes这两个参数建议加上。默认Node Exporter不会采集systemd服务状态和进程数,但这两项在实际运维中非常有用,比如你想知道某台机器上有多少个失败的systemd服务单元,这个指标直接能反映出来。

启动后确认9100端口在监听:

ss -lntp | grep 9100 curl http://localhost:9100/metrics | head -n 20

能看到以node_开头的指标输出就说明正常了。常见指标有这么几类:node_cpu_seconds_total是CPU累计使用时间,node_memory_*是内存信息,node_filesystem_*是文件系统状态,node_network_*是网卡流量。

3. 配置抓取任务与核心指标解读

3.1 编辑prometheus.yml添加监控目标

在Prometheus服务器上打开/etc/prometheus/prometheus.yml,默认配置文件里已经有一个prometheus的抓取任务,那是监控Prometheus自身的。我们需要加上一个针对Linux节点的抓取任务:

scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'linux-node' static_configs: - targets: - '10.0.0.11:9100' - '10.0.0.12:9100' labels: os: 'centos'

job_name就是一组抓取任务的名称,比如你这批CentOS机器可以统一叫centos-node,后续在Grafana里筛选指标会很方便。targets列表里写的每台机器IP:端口,Prometheus启动后会周期性访问这些地址的/metrics路径。labels是附加标签,相当于给这组机器统一打标,方便做分组筛选。

改完配置后用samtool之类的工具校验一下语法更稳妥:

cd /opt/prometheus ./promtool check config /etc/prometheus/prometheus.yml

确认无报错后重载配置,Prometheus支持热加载,不用重启:

kill -HUP $(pgrep -f prometheus)

3.2 验证抓取状态与指标暴露

打开Prometheus的Web界面,依次进入“Status” -> “Targets”,能看到所有抓取目标的状态面板。如果显示UP,说明抓取正常;如果显示DOWN,点击对应目标的“Show more”能看到失败原因。

用命令快速验证也可以:

curl http://localhost:9090/api/v1/targets | jq '.data.activeTargets[] | {scrapeUrl, health}'

如果返回的状态不是"up",大概率是网络不通、9100端口没开、或者是Prometheus服务器访问不到被监控机器。后面第6章我会集中讲排查方法。

3.3 常用系统监控指标的含义与查询示例

拿到指标数据之后,最关键的是搞清楚每个指标如何转换成你关心的“使用率”“剩余空间”和“流量速率”。以下表格整理了最常用的几类指标:

指标名含义类型
node_cpu_seconds_totalCPU累计使用秒数,按mode区分Counter
node_load1 / node_load5 / node_load15系统平均负载Gauge
node_memory_MemTotal_bytes总内存大小Gauge
node_memory_MemAvailable_bytes可用内存大小Gauge
node_filesystem_size_bytes文件系统总容量Gauge
node_filesystem_avail_bytes文件系统可用空间Gauge
node_network_receive_bytes_total网卡累计接收字节数Counter
node_network_transmit_bytes_total网卡累计发送字节数Counter

这里最大的坑在于Counter类型不能直接用,必须经过rate()函数换算成每秒速率。CPU指标node_cpu_seconds_total就是这么个Counter,它表示从开机到现在CPU在各种状态(如用户态、内核态、空闲)下累计跑了多少秒。你要看CPU使用率,得先算出最近5分钟内空闲时间的变化速率,再用总数减去它:

100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

这条查询结果就是各台机器的CPU使用率百分比。内存和磁盘类型是Gauge,可以直接相除:

# 内存使用率 (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 # 磁盘使用率,排除系统自带的一些特殊文件系统 100 - (sum by(instance) (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay|squashfs"}) / sum by(instance) (node_filesystem_size_bytes{fstype!~"tmpfs|overlay|squashfs"})) * 100

网络流量要换算成比特每秒才直观:

# 入方向带宽,单位是bps rate(node_network_receive_bytes_total{device!="lo"}[5m]) * 8

在{}里头加device!="lo"是为了过滤掉回环网卡,不然本地流量也算进去会把结果带偏。

4. 接入Grafana实现可视化

4.1 安装Grafana

Prometheus自带的UI只适合临时查数据,生产监控面板基本都用Grafana。CentOS下用官方仓库安装最省事:

# 添加官方yum源,然后安装 sudo yum install -y https://dl.grafana.com/oss/release/grafana-11.1.0-1.x86_64.rpm systemctl daemon-reload systemctl enable --now grafana-server

安装完成后访问http://服务器IP:3000,默认账号和密码都是admin,首次登录会强制要求修改密码。这一步在公网环境别偷懒,务必改成强密码。

4.2 添加Prometheus数据源

进入Grafana左侧菜单“Connections” -> “Data Sources”,点击“Add data source”,选择Prometheus类型。在“URL”一栏填写http://localhost:9090,其他配置保持默认,点击下方的“Save & test”,看到绿色提示说明数据源连接成功。

如果在Grafana服务器上访问Prometheus正常,但数据源测试却失败,多半是Grafana容器或特权模式导致的网络隔离问题。本地安装一般不会遇到。

4.3 导入系统监控大盘

手写面板太费时间,直接从社区导入现成的模板更高效。在Grafana左侧菜单找到“Dashboards” -> “New” -> “Import”,在面板库中搜索“Node Exporter Full”或者直接输入面板ID 1860,点击Load,选择刚才创建的Prometheus数据源,最后Import即可。

导入完成后你就能看到一整套完整的Linux监控看板,包含CPU、内存、磁盘、网络、文件系统、systemd服务等十几个Panel。这套面板的查询逻辑可以作为你学习PromQL的绝佳教材,因为每个Panel点进去都能看到原始查询语句和变量定义方式。

4.4 自定义面板与告警配置

社区面板再牛,也不可能完全匹配你的需求。比如你想专门看某块挂载盘的写入延迟,得自己加面板。操作流程是:进入某个Dashboard右上角“Add” -> “Visualization”,选择Prometheus数据源,在查询编辑器里输入PromQL,右侧预览图表效果,顺手设置一下“Unit”单位,比如字节、百分比、秒等。

告警配置建议放在Prometheus规则文件里做,而不是在Grafana里配。因为Grafana的告警依赖Grafana本身一直在线,Prometheus规则告警则更贴近监控主干,后面第5章会专门讲。

5. 告警规则配置

5.1 编写告警规则文件

告警规则文件通常放在/etc/prometheus/下,比如叫node_rules.yml。内容按组划分,一组里可以放多条规则。举个例子:

groups: - name: node_alerts rules: - alert: InstanceDown expr: up == 0 for: 2m labels: severity: critical annotations: summary: "Instance {{ $labels.instance }} down" description: "Prometheus cannot reach {{ $labels.instance }} for more than 2 minutes." - alert: HighCpuUsage expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90 for: 10m labels: severity: warning annotations: summary: "High CPU usage on {{ $labels.instance }}" description: "CPU usage has been above 90% for 10 minutes." - alert: DiskSpaceLow expr: (1 - node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}) * 100 > 85 for: 5m labels: severity: warning annotations: summary: "Disk nearly full on {{ $labels.instance }}" description: "Disk usage has been above 85% for 5 minutes."

规则里的for字段是持续触发时间,含义是“这个条件必须连续满足多少分钟才触发告警”。这个字段非常重要,能避免瞬时尖峰导致的误报。比如CPU瞬间冲到95%但1秒后就回落,这种就不该告警,for: 10m能过滤掉大量无效告警。

改完配置后在prometheus.yml里引用这个规则文件:

rule_files: - "node_rules.yml"

然后重载Prometheus配置。进入Web界面“Status” -> “Rules”,能看到规则列表和每条规则的最新计算结果。

5.2 配置Alertmanager通知

规则触发后默认只是显示在界面上,生产环境需要推到企业微信、钉钉或邮件。这时就要安装Alertmanager。

# 下载解压后,创建配置 mkdir -p /etc/alertmanager cat > /etc/alertmanager/alertmanager.yml <<EOF route: group_by: ['alertname'] group_wait: 30s group_interval: 5m repeat_interval: 4h receiver: 'webhook' receivers: - name: 'webhook' webhook_configs: - url: 'http://127.0.0.1:8080/webhook' EOF

然后在prometheus.yml里添加alertmanager地址:

alerting: alertmanagers: - static_configs: - targets: - 'localhost:9093'

repeat_interval控制同一个告警的重复通知频率,默认4小时比较合理,既能避免刷屏,又不会漏掉持续未解决的问题。

5.3 告警测试验证

配置完成后别以为就万事大吉了,必须实际触发一次。我自己的做法是找一台测试机器,用dd命令快速占满磁盘:

dd if=/dev/zero of=/tmp/testfile bs=1M count=4096

然后去Prometheus的“Alerts”页面观察告警状态变化:先是INACTIVE,条件满足进入PENDING,持续for指定的时间后变成FIRING。如果Alertmanager配好了,这个阶段应该能收到测试通知。测完记得删掉测试文件,然后重新打开“Alerts”页面确认告警恢复,规则会自动进入INACTIVE状态。

6. 常见问题与排查技巧实录

6.1 抓取目标显示DOWN怎么办

这是最常见的故障,遇到之后按顺序排查,通常十分钟内能定位。先确认被监控机器的Node Exporter进程还活着:

systemctl status node_exporter curl http://localhost:9100/metrics

本机能输出指标说明服务正常,那就从Prometheus机器上用curl测一下网络连通性:

curl http://被监控IP:9100/metrics

这一步能直接区分是网络问题还是应用问题。如果超时,检查CentOS的firewalld是否放行了9100端口:

firewall-cmd --list-ports # 查看已放行端口 firewall-cmd --permanent --add-port=9100/tcp && firewall-cmd --reload

另一个容易忽略的是SELinux。CentOS默认开启SELinux,虽然这里监听高端口一般影响不大,但如果出现权限拒绝的错误,可以把getenforce的结果查一下。实在排查不出来,去看Node Exporter服务的日志,journalctl -u node_exporter -n 50通常会给出明确原因。

6.2 指标数据有缺失或不连续

抓取目标状态是UP,但Grafana面板上曲线出现断档,这种情况大多和服务器时间有关。Prometheus抓取数据时会带上时间戳,如果被监控机器的时间和Prometheus服务器相差超过一定阈值,Prometheus会丢弃或者错乱这部分时序数据。先同步时间:

systemctl enable --now chronyd chronyc sources

数据断档还可能因为抓取超时。默认scrape_timeout是10秒,如果某台机器上Node Exporter加了很多采集器,一次性返回大量指标导致响应超时,就会出现抓取失败。这类问题既可以加大scrape_timeout,也可以精简采集器,我倾向于后者,不用的采集器模块直接禁用,省资源又稳定。

6.3 端口安全与性能优化

Node Exporter默认裸奔在9100端口,如果机器有公网IP,这个是很大的安全隐患。最简单的加固办法就是让Node Exporter只监听内网地址,比如把启动参数改成--web.listen-address=内网IP:9100。如果Prometheus和Node Exporter不在同一个内网,建议用Nginx反向代理加Basic Auth做一层认证,不要让指标接口直接暴露公网。

性能方面,首次启动Prometheus后数据目录会持续增大,特别是采集目标多、机器数量大的时候。合理设置retention.time,定期归档或清理,不要指望无限存储。Node Exporter本身资源占用很低,真正吃资源的是Prometheus存储和大盘查询,查询语句里尽量添加时间范围和rate()窗口,避免全量扫描时间序列数据。

6.4 常见问题速查表

我用一个表格把手头经常遇到的问题汇总一下,方便你直接对照处理:

现象可能原因快速处理
Target显示DOWN9100端口未监听或防火墙拦截检查node_exporter进程,放行端口
数据有缺口被监控机时间不同步启动chronyd并同步时间
告警一直不触发规则文件没加载或for时间太长打开Rules页面确认规则状态
Grafana查不到数据数据源URL填错用localhost和IP各试一次
磁盘图表异常未过滤tmpfs等虚拟文件系统PromQL加上fstype过滤条件

写到这里,如果你已经跟着把Prometheus、Node Exporter、Grafana这套环境搭起来,并且把第3章的常见指标查询都手动跑了一遍,那么监控Linux系统运行状态这件事的骨架就算完整了。根据我自己的经验,这套体系最核心的价值不是那一堆花花绿绿的图表,而是它能让你在业务出问题之前就看到趋势。早期我们监控刚上线的时候,有一次凌晨两点的告警短信把我叫醒,打开Grafana一看,某台机器磁盘使用率连续三小时稳步上升,按那个斜率算再过两小时就写满。如果不是监控提前报警,等到白天业务高峰再发现,整个服务可能已经处于不可用状态了。最后再提一个小技巧:前期搭建的时候,你可能觉得每台机器都配一套Node Exporter很麻烦,但用配置管理工具批量分发systemd配置和二进制文件,整个流程也就几分钟的事。监控越早建,数据越早积累,后面做容量规划、排查历史故障的时候,你会感谢当初自己没偷懒。

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

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

立即咨询