使用[Prometheus] Node Exporter 监控CPU、内存和磁盘
目录
- [目次] Prometheusで監視システムを作る with Docker
总结
以下是用PromQL监控CPU和内存的Prometheus示例。
相关文章
请参考以下链接以设置 Prometheus 和 Node Exporter 的环境搭建步骤。
设置 Prometheus 环境的方法如下。
参考にPromQL的基础知识,请看这里。
在处理PromQL之前,最好要了解的知识在这里。
中央处理器利用率
在example.com:9100上安装了node-exporter,计算除去idle模式的每个模式在最近一分钟内的平均CPU使用时间的PromQL。
rate(node_cpu_seconds_total{mode!="idle"}[1m])
以下的表格总结了各个模式及其意义。在上述例子中,我们剔除了idle的结果。
当你执行top命令时,会出现以下类型的行,这里显示的us,sy,ni等代表这些模式。
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
对于多核心CPU
如果是多核节点的情况,可以通过以下方式计算每个模式的平均值。
without(cpu)是为了计算每个CPU的平均值,在计算时忽略CPU编号的表达式。
avg without(cpu) (rate(node_cpu_seconds_total{instance="example.com:9100", mode!="idle"}[1m]))
除了avg之外,还有avg_over_time。
avg和rate组合在一起计算,而avg_over_time则简单地计算时间范围内的平均值。
可以这样使用:
avg_over_time(node_cpu_seconds_total{mode!="idle"}[1m])
参考一:用示例学习!使用PromQL自由绘制图表(Prometheus + Grafana)
输出CPU使用率超过80%的示例。
avg without(cpu) (rate(node_cpu_seconds_total{instance="example.com:9100", mode!="idle"}[1m])) >= 0.8
路德-阿贝雷奇
如果要进行标准化处理,应该按照CPU核心数量进行除法运算。
FYI: CPU负载还是标准化CPU负载更好?
输出超过1的负载平均值(进行正常化)。
# ロードアベレージ / CPUコア数
node_load1 / count(count(node_cpu_seconds_total{instance="example.com:9100"}) without (mode)) without (cpu) > 1
内存使用率
# メモリ総容量 - メモリ空き容量 = 現在の使用量
node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes
输出内存使用率超过80%以上的内容
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes >= 0.8
儲存容量
磁盘使用率
1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)
inode利用率
inode的利用率
1 - (node_filesystem_files_free / node_filesystem_files)
通过I/O请求导致的CPU使用率
Prometheus的rate(node_disk_io_time_seconds_total[1m])等同于iostat命令中的%util值。
%util是由对设备的I/O请求引起的CPU使用率。
参考:如何查看iostat。
试试给I/O负载
给予I/O负载,然后比较iostat命令和PormQL rate(node_disk_io_time_seconds_total[1m])的结果。
提供负荷
使用stress-ng命令对30GB数据进行写入,以给系统施加负荷。
参考:使用stress-ng命令在CPU、内存和磁盘上施加负载。
$ stress-ng -d 3 --hdd-bytes 30G
iostat结果
$ iostat -dtx 10
Linux 3.10.0-1127.19.1.el7.x86_64 (example.com) 06/09/2021 _x86_64_ (8 CPU)
# stress-ngコマンド実行前
06/09/2021 03:35:04 PM
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 0.00 0.14 0.19 1.52 16.90 44.59 72.03 0.00 4.61 0.56 5.11 0.11 0.02
scd0 0.00 0.00 0.00 0.00 0.00 0.00 9.96 0.00 0.72 0.72 0.00 0.72 0.00
# stress-ngコマンド実行後
06/09/2021 03:35:14 PM
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 0.00 0.10 2.10 2051.00 91.60 1031840.25 1005.24 86.22 82.18 0.14 82.26 0.33 67.81
scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
# stress-ngコマンド実行後、utilが100%近くなっている
06/09/2021 03:35:24 PM
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 0.00 2.40 0.20 2980.60 3.20 1498235.60 1005.26 127.44 84.47 4.50 84.48 0.34 99.97
scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
PromQL的结果
根據I/O請求所產生的CPU使用率。
rate(node_disk_io_time_seconds_total[1m])
我可以确认 iostat 命令的 %uti 和 PromQL 的结果都接近于100%。
I/O延迟
这些值是从/proc/diskstats获得的。
$ cat /proc/diskstats
252 0 vda 4682174 4304 929662806 2502865 27994455 2461794 1996846903 172438082 0 3754119 98035986
252 1 vda1 152 0 1216 61 0 0 0 0 0 61 61
252 2 vda2 4681923 4304 929656982 2502765 27816578 2461786 1996846823 172315078 0 2975909 96782251
11 0 sr0 53 0 528 38 0 0 0 0 0 38 38
可以通过比较PromQL的结果和/proc/diskstats的值来确认它们是相同的。
虽然小数点的位置可能会有所不同,但这可能是由于使用毫秒或秒进行测量的差异。
(/proc/diskstats:7列目)0.038382502.86500000000022502865node_disk_reads_completed_total
(/proc/diskstats:4列目)535346821744682174node_disk_write_time_seconds_total
(/proc/diskstats:11列目)00172438.082172438082node_disk_writes_completed_total
(/proc/diskstats:8列目)002799445527994455
阅读 (Yuè dú)
每个读取操作所花费的时间之和(以秒为单位)除以成功完成的读取操作的总数 = 每次读取操作所花费的秒数
rate(node_disk_read_time_seconds_total[1m]) / rate(node_disk_reads_completed_total[1m])
写
每次写入所花费的平均时间 = 完成所有写入所花费的总时间(秒)/ 成功完成的写入次数
rate(node_disk_write_time_seconds_total[1m]) / rate(node_disk_writes_completed_total[1m])
平均I/O请求大小
“The weighted number of seconds”在直译时是“加权秒数”,但是意义不太清楚。如果是加权平均的话就能理解了。这是在某种程度上给秒数加了权重吗?权重是针对什么的呢?大小?输入/输出数量?
加重平均是一种计算方法 – 【程序员的统计学】不只有一种计算平均值的方法。
这个操作是用来获取/proc/diskstats文件中最后一列的值。关于最后一列的值,在下面进行了解释。
除正在进行的操作之外,所有字段都是随时间累加的计数器。最后一个字段,即加权毫秒数,表示执行I/O操作所花费的时间,它包括了当前正在进行的操作;它基本上是每个操作所花费时间的总和,再加上尚未完成的操作的时间。
引用来源:https://www.xaprb.com/blog/2010/01/09/how-linux-iostat-computes-its-results/
尝试比较PromQL和/proc/diskstats的值。
$ cat /proc/diskstats
252 0 vda 4682204 4304 929664814 2502877 27998500 2462121 1996915380 172444038 0 3754432 98041060
252 1 vda1 152 0 1216 61 0 0 0 0 0 61 61
252 2 vda2 4681953 4304 929658990 2502777 27820589 2462113 1996915300 172321011 0 2976171 96787196
11 0 sr0 53 0 528 38 0 0 0 0 0 38 38
可以通过比较PromQL的结果和/proc/diskstats中的值确认它们相同。
小数点位置不同是因为存在以下差异。
-
- /proc/diskstats => the weighted number of milliseconds spent doing I/Os
- node_disk_io_time_weighted_seconds_total => the weighted number of seconds spent doing I/Os
(/proc/diskstats:最後の列目)0.0383898041.0698041060
虽然我不明白“加重秒数”的意义,但据说算出I/O请求的平均大小如下。
rate(node_disk_io_time_weighted_seconds_total[1m])
在施加负荷之后执行会有以下的感觉。
$ stress-ng -d 3 --hdd-bytes 30G
警示规则的描述示例
groups:
- name: sample001
rules:
- alert: cpu_usage_exceeds_80%
# CPU使用率が80%を超えているもの
expr: avg without(cpu) (rate(node_cpu_seconds_total{mode!="idle"}[1m])) >= 0.8
for: 5m
labels:
severity: critical
annotations:
firing_text: "[{{ $labels.env }}] {{ $labels.instance }} CPU usage exceeds 80%"
resolved_text: "[{{ $labels.env }}] {{ $labels.instance }} CPU usage falls"
- alert: cpu_load_avg_exceeds_1
# ロードアベレージが1を超えたもの
expr: node_load1 / count(count(node_cpu_seconds_total) without (mode)) without (cpu) > 1
for: 5m
labels:
severity: critical
annotations:
firing_text: "[{{ $labels.env }}] {{ $labels.instance }} CPU load average exceeds 1"
resolved_text: "[{{ $labels.env }}] {{ $labels.instance }} CPU load average falls"
- alert: memory_usage_exceeds_80%
# メモリ使用率が80%以上のもの
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes >= 0.8
for: 5m
labels:
severity: critical
annotations:
firing_text: "[{{ $labels.env }}] {{ $labels.instance }} Memory usage exceeds 80%"
resolved_text: "[{{ $labels.env }}] {{ $labels.instance }} Memory usage falls"
- alert: disk_usage_exceeds_80%
# ディスク使用率が80%以上のもの
expr: 1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes) >= 0.8
for: 5m
labels:
severity: critical
annotations:
firing_text: "[{{ $labels.env }}] {{ $labels.instance }} Disk usage exceeds 80%"
resolved_text: "[{{ $labels.env }}] {{ $labels.instance }} Disk usage falls"
- alert: disk_usage_exceeds_80%
# inode使用率が80%以上のもの
expr: 1 - (node_filesystem_files_free / node_filesystem_files) >= 0.8
for: 5m
labels:
severity: critical
annotations:
firing_text: "[{{ $labels.env }}] {{ $labels.instance }} Inode usage exceeds 80%"
resolved_text: "[{{ $labels.env }}] {{ $labels.instance }} Inode usage falls"
- alert: io_usage_exceeds_80%
# I/OリクエストによるCPU使用率が80%以上のもの
expr: rate(node_disk_io_time_seconds_total[1m]) >= 0.8
for: 5m
labels:
severity: critical
annotations:
firing_text: "[{{ $labels.env }}] {{ $labels.instance }} I/O usage exceeds 80%"
resolved_text: "[{{ $labels.env }}] {{ $labels.instance }} I/O usage falls"
其他 tā)
顺便说一下,在Node Exporter中无法捕捉CPU错误和内存错误。
请参考
-
- モニタリングツールPrometheusを使う
-
- Prometheus でNodeのモニタリング
-
- サンプルで学ぶ!PromQLで自在にグラフを描こう (Prometheus + Grafana)
-
- Prometheusクエリ道場
-
- Understanding Machine CPU usage
-
- A Deep Dive into Kubernetes Metrics — Part 2
- Kubernetesにおけるストレージ関連のメトリクス一覧