分析告警 kubernetes 节点 load 过高问题
2022-4-27
负载过高分析 #
通过 linux 提供的几个命令可以从不同的纬度分析系统负载。
vmstat #
这命令能从一个系统的角度反应出服务器情况,报告虚拟内存统计信息,报告有关进程、内存、分页、块的信息 IO、陷阱、磁盘和 CPU 活动。看个例子:
$ vmstat --wide --unit M 5
procs ----------------memory---------------- ---swap--- -----io---- ---system--- ---------cpu--------
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 1 0 127691 1535 73572 0 0 0 3 0 0 2 1 97 0 0
93 0 0 127674 1535 73573 0 0 0 80 49267 67634 5 1 94 1 0
0 2 0 127679 1535 73573 0 0 0 66 38537 56283 3 1 95 1 0
2 2 0 127738 1535 73574 0 0 6 86 41769 61823 5 1 93 2 0
2 0 0 127729 1535 73574 0 0 18 18 41002 59214 4 1 95 0 0
命令以及输出解释:
vmstat
- --wide 宽幅展示 比较易读
- --unit 输出单位,可以是 1000(k)、1024(K)、1000000(m) 或 1048576(M) 个字节
procs
- r: 可运行 runnable 进程数量(包括运行中 running 或者等待中 waiting 的进程)
- b: 等待 i/o 完成的阻塞 blocked 进程数
memory
显示单位受 --unit 影响
- swpd: 交换 swap 内存使用量
- free: 空闲 idle 内存数
- buff: 用作缓冲区 buffers 的内存量
- cache: 用作缓存 cache 的内存量
swap
显示单位受 --unit 影响
- si: 每秒从磁盘换入 swapped 的内存量
- so: 每秒交换 swapped 到磁盘的内存量
io
- bi: 从块设备接收的块 block (blocks/s)
- bo: 发送到块设备到块 block (blocks/s)
system
- in:每秒的中断数,包括时钟 clock
- cs:每秒上下文 context 切换的次数。
cpu
以下都是 cpu 总时间的百分比
- us: 非内核代码运行耗时 (user time & nice time)
- sy: 内核代码运行耗时 (系统耗时)
- id: 空闲 idle 时间,从 Linux 2.5.41开始它包含 i/o 等待时间
- *wa: io 等待时间,从 Linux 2.5.41开始它包含在 idle 中
- *st: 从虚拟机中窃取时间,未知
这个例子中,可见 cpu 空闲 idle 时间占比 90% 以上,说明 i/o 等待时间很高。
iostat #
cpu 统计报告 & 设备/分区 input/output 统计报告。
$ iostat -m 2 3
Linux 5.4.108-1.el7.elrepo.x86_64 (node27) 04/28/2022 _x86_64_ (80 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
2.35 0.05 0.64 0.21 0.00 96.75
Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sdb 5.13 0.00 0.19 3477 5627354
sda 3.10 0.00 0.03 1890 738773
avg-cpu: %user %nice %system %iowait %steal %idle
1.78 0.00 0.57 1.30 0.00 96.34
Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sdb 0.00 0.00 0.00 0 0
sda 0.50 0.00 0.00 0 0
avg-cpu: %user %nice %system %iowait %steal %idle
1.71 0.01 0.61 0.94 0.00 96.72
Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sdb 0.00 0.00 0.00 0 0
sda 0.00 0.00 0.00 0 0
报告解读:
iostat -m 2 3
- -m: 以兆为单位显示
- -x: 展示扩展信息
- 每隔2秒输出一次报告,总共输出3次。
- 第一份报告是系统自启动以来的统计信息,每个后续报告都是上次报告以来的统计信息。
avg-cpu
cpu 使用率报告,对于多核心系统,这里的值是全局平均值。下面每一项都是对比 cpu 总时间的使用率。
- %user: 执行用户级别应用所用的时间
- %nice: 执行具有 nice 优先级的用户级别程序所用的时间
- %system: 执行系统级别(内核)程序所用时间
- %iowait: cpu/cpus 空闲等待磁盘 i/o 请求所用的时间
- %steal: 当虚拟机管理器正服务另一个虚拟处理器时,虚拟 cpu/cpus 的被迫等待时间(被偷走的时间)
- %idle: 系统没有 i/o 请求时的 cpu/cpus 空闲时间
下面是设备使用率报告
展示每一个物理设备/分区的统计信息
- tps: 每秒向设备发出的传输次数。一次传输就是一个 i/o 请求,多个逻辑请求可以合并成一次 i/o 请求。
- MB_read/s, MB_wrtn/s: 每秒读取/写入设备的数据量,单位 M
- MB_read, MB_wrtn: 读取/写入设备的总数据量
从例子中,可见 cpu %idle 占比 90% 以上,说明 cpu 花了绝大多数时间在等待 i/o。设备的读写数据几乎没有,说明这些 i/o 并不是来自系统物理设备/分区。有可能来自挂载的网络文件存储设备。
ps #
当前进程信息快照,通过下面的命令找出存在大量 io 的进程
$ ps -e -L o state,pid,cmd | grep "^[R|D]" | sort | uniq -c | sort -k 1nr
41 R 75319 /bin/node_exporter...
命令解释:
-e every 输出所有进程
o 自定义输出列 逗号分割
-L 展示线程
进程状态码介绍
- R 在执行队列中的,正在运行中或者可以运行的 running or runnable
- D 不可中断的睡眠 (通常是 i/o)
- S 可以中断的睡眠 (正在等待某个事件完成)
- I 空闲 Idle 的内核线程
- s session leader
- < 高优先级
- + 在前台进程组中
- l 是多线程的
使用下面的命令找出占用 io 的 pod uid
$ cat /proc/75319/cgroup | awk -F "/" '{print $4}'
pode0c67fad-9fab-4f35-87b3-d918b5f09882
...
$ kubectl get pods --all-namespaces \
-ocustom-columns=NS:metadata.namespace,Name:metadata.name,UID:metadata.uid \
| grep e0c67fad-9fab-4f35-87b3-d918b5f09882