kubernetes-guide/troubleshooting/node/node-high-load.md

96 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 节点高负载
Kubernetes 节点高负载如何排查?本文来盘一盘。
## 如何判断节点高负载?
可以通过 `top``uptime` 来确定 load 大小,如果 load 小于 CPU 数量,属于低负载,如果大于 CPU 数量 2~3 倍,就比较高了,当然也看业务敏感程度,不太敏感的大于 4 倍算高负载。
## 排查思路
观察监控:通常不是因为内核 bug 导致的高负载,在卡死之前从监控一般能看出一些问题,可以观察下各项监控指标。
排查现场:如果没有相关监控或监控维度较少不足以查出问题,就尝试登录节点抓现场分析。有时负载过高通常使用 ssh 登录不上,如果可以用 vnc可以尝试下使用 vnc 登录。
## 排查现场思路
loadavg 可以认为是 R状态线程数和D状态线程数的总和 R 代表需要 cpu是 cpu 负载。 D 通常代表需要 IO是 IO 负载)
简单判断办法:
```bash
ps -eL -o lwp,pid,ppid,state,comm | grep -E " R | D "
```
然后数一下各种状态多少个进程,看看是 D 住还是 R。
如果是长时间 D 住,可以进一步查看进程堆栈看看 D 在哪里:
```bash
cat /proc/<PID>/stack
```
如果是大量进程/线程在 R 状态,那就是同时需要 CPU 的进程/线程数过多CPU 忙不过来了,可以利用 perf 分析程序在忙什么:
```bash
perf -p <PID>
```
## 线程数量过多
如果 load 高但 CPU 利用率不高,通常是同时 running 的进程/线程数过多,排队等 CPU 切换的进程/线程较多。
通常在 load 高时执行任何命令都会非常卡,因为执行这些命令也都意味着要创建和执行新的进程,所以下面排查过程中执行命令时需要耐心等待。
看系统中可创建的进程数实际值:
```bash
cat /proc/sys/kernel/pid_max
```
> 修改方式: sysctl -w kernel.pid_max=65535
通过以下命令统计当前 PID 数量:
```bash
ps -eLf | wc -l
```
如果数量过多,可以大致扫下有哪些进程,如果有大量重复启动命令的进程,就可能是这个进程对应程序的 bug 导致。
还可以通过以下命令统计线程数排名:
```bash
printf "NUM\tPID\tCOMMAND\n" && ps -eLf | awk '{$1=null;$3=null;$4=null;$5=null;$6=null;$7=null;$8=null;$9=null;print}' | sort |uniq -c |sort -rn | head -10
```
找出线程数量较多的进程,可能就是某个容器的线程泄漏,导致 PID 耗尽。
随便取其中一个 PID用 nsenter 进入进程 netns:
```bash
nsenter -n --target <PID>
```
然后执行 `ip a` 看下 IP 地址,如果不是节点 IP通常就是 Pod IP可以通过 `kubectl get pod -o wide -A | grep <IP>` 来反查进程来自哪个 Pod。
## 陷入内核态过久
有些时候某些 CPU 可能会执行耗时较长的内核态任务,比如大量创建/销毁进程,回收内存,需要较长时间 reclaim memory必须要执行完才能切回用户态虽然内核一般会有 migration 内核线程将这种负载较高的核上的任务迁移到其它核上,但也只能适当缓解,如果这种任务较多,整体的 CPU system 占用就会较高,影响到用户态进程任务的执行,对于业务来说,就是 CPU 不够用,处理就变慢,发生超时。
CPU 内核态占用的 Prometheus 查询语句:
```txt
sum(irate(node_cpu_seconds_total{instance="10.10.1.14",mode="system"}[2m]))
```
## IO 高负载
参考 [IO 高负载](io-high-load.md) 进行排查。
## FAQ
### 如果机器完全无法操作怎么办?
有时候高负载是无法 ssh 登录的,即使通过 vnc 方式登录成功,由于机器太卡也是执行不了任何命令。如通过监控也看不出任何原因,又想要彻查根因,可以从虚拟化底层入手,给虚拟机发信号触发 coredump (无需登录虚拟机),如果用的云产品,可以提工单让虚拟主机的产品售后来排查分析。