【前情提要】监控架构总算是理清楚了,小林终于明白 exporter、Prometheus、Grafana、Alertmanager 各自在监控链路里负责什么。老周说:“明天开始动手装。先装 node_exporter,让机器学会报告自己的状态。”小林打开终端准备安装。他还没意识到,9100 端口、systemd 服务、指标路径,每一个都可能让他折腾一番。
一、为什么要先装 node_exporter?
早上到工位,小林打开终端,打算直接装 Prometheus。
老周拦住他:“别急。你先装 node_exporter。”
“为啥不先装 Prometheus?”
“因为 Prometheus 是‘收数据的人’,你现在还没数据可收。”老周说,“你得先让机器学会‘报告自己的状态’。node_exporter 就是干这个的。”
“它报告啥?”
“CPU、内存、磁盘、网络、文件系统、负载、进程数……基本上你能想到的系统指标,它都有。”老周说,“你可以把它理解成机器的‘体检医生’。它不治病,但会告诉你哪里不正常。”
“那它和 Prometheus 啥关系?”
“node_exporter 把指标暴露在一个 HTTP 端口上,Prometheus 定期去拉。就像医生把体检报告放在桌上,Prometheus 定期去取。”
小林明白了:“所以 node_exporter 是‘数据源’,Prometheus 是‘数据收集器’。”
“对。”老周说,“开始装。”
二、安装 node_exporter
“Ubuntu 上装 node_exporter,有两种方式。”老周说,“apt 和二进制。你选哪个?”
“apt 简单吧?”
“对。”老周说,“但 apt 源里的版本可能旧。不过对你入门够用了。先用 apt。”
小林敲:
sudo apt update
sudo apt install -y prometheus-node-exporter
输出:
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
prometheus-node-exporter
...
Setting up prometheus-node-exporter (1.x.x-1) ...
“装完了。”小林说。
“验证一下。”
systemctl status prometheus-node-exporter
输出:
● prometheus-node-exporter.service - Prometheus exporter for machine metrics
Loaded: loaded (/lib/systemd/system/prometheus-node-exporter.service; enabled; vendor preset: enabled)
Active: active (running) since ...
“active (running),说明在跑。”老周说,“你看,apt 装的好处是,它自动帮你创建了 systemd 服务,自动启动,自动开机自启。你不用手动配。”
“那它监听哪个端口?”
“默认 9100。”老周说,“你验证一下。”
sudo ss -lntp | grep 9100
输出:
LISTEN 0 4096 *:9100 *:* users:(("prometheus-node",pid=1234,fd=3))
“看到了吧?9100 端口在监听。”老周说,“现在你 curl 一下。”
curl -s http://localhost:9100/metrics | head -30
输出:
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0.000123
go_gc_duration_seconds{quantile="0.25"} 0.000234
...
# HELP node_cpu_seconds_total Seconds the CPUs spent in each mode.
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 12345.67
node_cpu_seconds_total{cpu="0",mode="system"} 234.56
node_cpu_seconds_total{cpu="0",mode="user"} 567.89
...
“这一大堆就是指标。”老周说,“你别被吓到,常用的就那几个。”
三、/metrics 页面:机器的“体检报告”
“你现在打开浏览器,访问 http://localhost:9100/metrics。”老周说。
小林在 Ubuntu 里打开 Firefox,输入地址。页面出来一大堆文本,密密麻麻。
“这玩意儿能看懂?”
“你不需要全看懂。”老周说,“你只需要知道,每一行都是一个指标。格式是 指标名{标签} 数值。”
“那常用的指标有哪些?”
老周拿过小林的笔记本,写了一个清单。
CPU 相关:
node_cpu_seconds_total{cpu="0",mode="idle"} 12345.67
node_cpu_seconds_total{cpu="0",mode="system"} 234.56
node_cpu_seconds_total{cpu="0",mode="user"} 567.89
“node_cpu_seconds_total 是 CPU 累计使用时间,按核心和模式分类。mode="idle" 是空闲,mode="system" 是系统态,mode="user" 是用户态。你算 CPU 使用率,就是 1 - idle / total。”
内存相关:
node_memory_MemTotal_bytes 4.0e+09
node_memory_MemAvailable_bytes 2.5e+09
node_memory_MemFree_bytes 1.2e+09
node_memory_Buffers_bytes 1.0e+08
node_memory_Cached_bytes 8.0e+08
“MemTotal 是总内存,MemAvailable 是可用内存,MemFree 是空闲内存。你算内存使用率,用 MemAvailable / MemTotal,别用 MemFree。因为 MemFree 不包括缓存,会显得内存很紧张,其实不是。”
磁盘相关:
node_filesystem_size_bytes{mountpoint="/"} 5.0e+10
node_filesystem_avail_bytes{mountpoint="/"} 3.0e+10
“node_filesystem_size_bytes 是文件系统总大小,node_filesystem_avail_bytes 是可用大小。你算磁盘使用率,用 (size - avail) / size。注意标签里的 mountpoint,你要看哪个分区,就加对应的 mountpoint。”
网络相关:
node_network_receive_bytes_total{device="ens160"} 1.2e+08
node_network_transmit_bytes_total{device="ens160"} 5.6e+07
“node_network_receive_bytes_total 是累计接收字节,node_network_transmit_bytes_total 是累计发送字节。这俩是 Counter,你关心的是速率,不是总量。”
系统负载:
node_load1 0.5
node_load5 0.3
node_load15 0.2
“node_load1 是 1 分钟平均负载,node_load5 是 5 分钟,node_load15 是 15 分钟。负载和 CPU 核心数有关,单核负载 1.0 就是满载,四核负载 4.0 才是满载。”
小林记下:
- CPU:
node_cpu_seconds_total
- 内存:
node_memory_MemTotal_bytes、node_memory_MemAvailable_bytes
- 磁盘:
node_filesystem_size_bytes、node_filesystem_avail_bytes
- 网络:
node_network_receive_bytes_total、node_network_transmit_bytes_total
- 负载:
node_load1、node_load5、node_load15
四、用 grep 和 awk 过滤指标
“指标太多,怎么只看我关心的?”小林问。
“grep 过滤。”老周说,“比如你只看 CPU 空闲指标:”
curl-s http://localhost:9100/metrics | grep"node_cpu_seconds_total"
输出:
node_cpu_seconds_total{cpu="0",mode="idle"} 12345.67
node_cpu_seconds_total{cpu="0",mode="system"} 234.56
node_cpu_seconds_total{cpu="0",mode="user"} 567.89
...
“只看内存:”
curl -s http://localhost:9100/metrics | grep"node_memory"
“只看磁盘:”
curl -s http://localhost:9100/metrics | grep"node_filesystem"
“那 awk 呢?”
“awk 提取数值。比如你只看 CPU 空闲的数值:”
curl -s http://localhost:9100/metrics | grep 'node_cpu_seconds_total{cpu="0",mode="idle"}' | awk '{print $2}'
输出:
12345.67
“但注意,awk 默认按空格分隔,{cpu="0",mode="idle"} 里没有空格,所以 $1 是指标名,$2 是数值。”老周说,“如果标签里有空格,就得用 -F 指定分隔符。不过 node_exporter 的标签里一般没空格。”
“那我想算 CPU 使用率,怎么写?”
“先取总时间,再取空闲时间,算差值。”老周说,“但这个计算比较复杂,你以后用 PromQL 更简单。现在先学会看指标就行。”
小林记下:
grep "node_cpu":过滤 CPU 指标
grep "node_memory":过滤内存指标
grep "node_filesystem":过滤磁盘指标
awk '{print $2}':提取数值
五、node_exporter 的 systemd 服务
“你刚才 systemctl status 看到了,node_exporter 是一个 systemd 服务。”老周说,“服务名是 prometheus-node-exporter。”
“那我能改它的启动参数吗?”
“能。”老周说,“配置文件在 /etc/default/prometheus-node-exporter。你打开看看。”
cat /etc/default/prometheus-node-exporter
输出:
# Set the command-line arguments to pass to the node exporter.
ARGS=""
“默认是空的。”老周说,“你可以加参数。比如改监听地址:”
ARGS="--web.listen-address=0.0.0.0:9100"
“但默认就是 0.0.0.0:9100,不用改。你以后想改端口,或者排除某些采集器,再改这里。”
“那改了之后怎么生效?”
sudo systemctl restart prometheus-node-exporter
“restart,不是 reload。因为改的是启动参数,不是配置文件。reload 不重新读启动参数。”
“那如果服务挂了,怎么排查?”
“先看状态。”
systemctl status prometheus-node-exporter
“如果 failed,看日志。”
sudo journalctl -u prometheus-node-exporter -n 50
“journalctl 是 systemd 的日志工具。-u 指定服务,-n 50 看最后 50 行。”
小林记下:
- 服务名:
prometheus-node-exporter
- 配置文件:
/etc/default/prometheus-node-exporter
- 改配置后:
sudo systemctl restart prometheus-node-exporter
- 看日志:
sudo journalctl -u prometheus-node-exporter -n 50
六、排错挑战:9100 端口连不上
下午,小林想在 Mac 上访问 Ubuntu 的 node_exporter,看看指标。
他在 Mac 浏览器里输入:
http://192.168.x.x:9100/metrics
浏览器转圈,然后提示:
无法访问此网站
“啥?”小林又试了一次。还是不行。
他 SSH 到 Ubuntu,本地 curl 一下:
curl -s http://localhost:9100/metrics | head -5
输出正常。
“本地能访问,Mac 访问不了。”小林嘀咕。
他检查服务:
systemctl status prometheus-node-exporter
输出:
Active: active (running)
“在跑啊。”
他检查端口:
sudo ss -lntp | grep9100
输出:
LISTEN 0 4096 *:9100 *:* users:(("prometheus-node",pid=1234,fd=3))
“*:9100,说明监听所有接口啊。”小林更懵了。
他喊来老周。
老周看了一眼,问:“你 Ubuntu 的 ufw 开了吗?”
小林检查:
sudo ufw status
输出:
Status: active
“开了。”小林说。
“那你看 9100 端口放行了吗?”
小林看输出:
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
“没放行 9100。”小林说。
“那就对了。”老周说,“ufw 只放行了 22 和 80,9100 没放行。你 Mac 访问 9100,被防火墙拦了。”
小林放行:
sudo ufw allow 9100/tcp
再次在 Mac 浏览器访问:
http://192.168.x.x:9100/metrics
页面出来了。
排错思路总结:
- 本地 curl 能访问,远程访问不了,先检查防火墙。
sudo ufw status 看防火墙状态。
- 如果 active,看对应端口是否放行。
- 没放行,
sudo ufw allow 端口/tcp。
- 如果防火墙没启用,检查服务监听地址是否为
0.0.0.0(而不是 127.0.0.1)。
- 最后检查 Mac 和 Ubuntu 网络是否通(ping)。
“记住,”老周说,“本地能访问,远程不能访问,90% 是防火墙。你以后遇到这个问题,先看 ufw。”
七、练习
- 练习一:在 Ubuntu 里用 apt 安装
prometheus-node-exporter,确认 systemctl status 显示 active (running)。用 curl -s http://localhost:9100/metrics | head -20 查看指标,确认能正常输出。
- 练习二:用 grep 过滤出
node_cpu_seconds_total、node_memory、node_filesystem 三类指标,分别保存到三个文件 ~/cpu.txt、~/memory.txt、~/disk.txt。统计每个文件的行数。
- 练习三:在 Mac 上访问 Ubuntu 的
http://192.168.x.x:9100/metrics。如果访问不了,检查 ufw 状态,放行 9100 端口,再次访问确认成功。
参考答案
练习一:
sudo apt update
sudo apt install -y prometheus-node-exporter
systemctl status prometheus-node-exporter
curl-s http://localhost:9100/metrics | head -20
练习二:
curl -s http://localhost:9100/metrics | grep"node_cpu_seconds_total" > ~/cpu.txt
curl -s http://localhost:9100/metrics | grep"node_memory" > ~/memory.txt
curl -s http://localhost:9100/metrics | grep"node_filesystem" > ~/disk.txt
wc -l ~/cpu.txt ~/memory.txt ~/disk.txt
练习三:
Ubuntu:
sudo ufw status
sudo ufw allow 9100/tcp
sudo ufw status
Mac 浏览器访问 http://192.168.x.x:9100/metrics,确认显示指标。
八、下集预告
node_exporter 装好了,机器的“体检报告”能看了。老周说:“现在装 Prometheus,让它去取报告。”小林打开 Prometheus 官网,准备下载。但他不知道,prometheus.yml 的 YAML 缩进、scrape_configs 的配置、up 指标的验证,每一个都可能让他折腾。
下一集:《Prometheus 登场:把数据收进来》