3. 节点资源竞争诊断基础:理解CPU、内存、磁盘IO、网络带宽等资源竞争的表现
在Kubernetes集群中,节点资源竞争是导致Pod性能下降、调度失败、甚至节点状态异常的核心原因之一。作为SRE,你需要能够快速识别出是哪一种资源成为了瓶颈。本节将系统性地剖析CPU、内存、磁盘IO、网络带宽这四类资源竞争时的典型表现与诊断切入点。
3.1 资源竞争的本质与影响
资源竞争发生在多个进程(或Pod中的容器)同时争抢同一类有限资源时。操作系统内核通过调度器、内存管理器、块设备层和网络协议栈来协调这些竞争。当竞争超过阈值,就会产生“饥饿”现象,表现为延迟增加、吞吐量下降或进程被驱逐。
3.2 四类资源竞争的表现与诊断指标
下表总结了四类资源竞争的核心表现、关键指标以及典型的kubectl debug切入点:
| 资源类型 | 竞争时的典型表现 | 关键诊断指标 | kubectl debug切入点 |
|---|---|---|---|
| CPU | 请求延迟增加、应用吞吐量下降、CPU节流(throttling) | CPU使用率、runqueue长度、CPU限流时间 | kubectl debug node/<node> --profile=sysadmin → top / mpstat -P ALL 1 |
| 内存 | OOMKill、页面频繁换入换出、内存碎片、Pod被驱逐 | 可用内存、swap使用率、major page fault、oom_score | kubectl debug node/<node> --profile=sysadmin → vmstat 1 / cat /proc/meminfo |
| 磁盘IO | IO等待高、读写延迟飙升、日志写入阻塞、数据库查询超时 | iowait%、await、svctm、IOPS、吞吐量 | kubectl debug node/<node> --profile=sysadmin → iostat -x 1 / iotop |
| 网络带宽 | 连接超时、丢包率上升、TCP重传、带宽饱和 | 带宽利用率、丢包率、TCP重传率、连接队列溢出 | kubectl debug node/<node> --profile=sysadmin → sar -n DEV 1 / ss -s |
3.3 CPU资源竞争深度解析
CPU竞争通常表现为可运行队列(runqueue)的堆积。当runqueue长度持续超过CPU核心数的2倍时,说明CPU已经过载。在Kubernetes环境中,CPU的CFS配额(Completely Fair Scheduler)会导致CPU节流(throttling),即使节点整体CPU未满,单个Pod也可能因达到limit而被限流。
kubectl debug node/<node> -it --image=busybox -- chroot /host 进入节点后,执行 cat /sys/fs/cgroup/cpu/kubepods/besteffort/pod<pod-uid>/cpu.stat 查看 nr_throttled 和 throttled_time,这是判断Pod是否被CPU限流的直接证据。
3.4 内存资源竞争深度解析
内存竞争最严重的后果是OOMKill。Kubernetes的kubelet会根据Pod的oom_score_adj和实际内存使用量来决定杀死哪个进程。除了OOM,内存回收压力也会导致性能抖动。当系统内存不足时,内核会启动kswapd进行页面回收,表现为major page fault急剧增加,应用响应时间显著变长。
# 在节点上查看内存回收压力
kubectl debug node/worker-1 -it --image=nicolaka/netshoot -- chroot /host
# 观察procs中的r(运行队列)和b(不可中断睡眠,通常为IO)
vmstat 1 5
# 查看内存详细状态
cat /proc/meminfo | grep -E "^(MemTotal|MemFree|MemAvailable|SwapTotal|SwapFree|Dirty|Writeback)"
3.5 磁盘IO资源竞争深度解析
磁盘IO竞争是“隐形杀手”,因为它通常不会直接导致进程退出,而是让所有IO操作变慢。关键指标是iowait%和await。iowait%表示CPU等待IO完成的时间占比,如果持续超过30%,说明磁盘已经成为瓶颈。对于使用本地SSD的节点,IOPS和延迟是关键;对于网络存储(如AWS EBS、Ceph),还需要关注网络延迟对IO的影响。
iostat -x 1 中的 await 和 svctm 综合判断。
3.6 网络带宽资源竞争深度解析
网络带宽竞争在微服务架构中尤为突出。当网络接口的带宽利用率持续超过80%时,TCP的拥塞控制机制会开始丢包和重传,导致应用层感知到明显的延迟抖动。除了带宽,连接跟踪表(conntrack)溢出也是常见问题,特别是在高并发场景下。
# 在节点上查看网络带宽和错误
kubectl debug node/worker-1 -it --image=nicolaka/netshoot -- chroot /host
# 查看所有网络接口的流量、错误、丢包
sar -n DEV 1 3
# 查看TCP连接状态统计
ss -s
# 查看conntrack表使用情况
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
3.7 资源竞争诊断流程图
下面的SVG流程图展示了从发现Pod性能问题到定位具体资源竞争类型的诊断路径:
3.8 综合诊断案例:一次典型的资源竞争场景
假设你收到告警:某Node上的Pod响应延迟从5ms飙升到500ms。按照上述流程图,你可以快速执行以下步骤:
- 进入节点:
kubectl debug node/worker-2 -it --image=nicolaka/netshoot -- chroot /host - 查看整体负载:
top发现CPU空闲,但iowait%高达45%。 - 定位IO源头:
iotop -oP发现一个Pod的日志进程在大量写入。 - 确认资源竞争类型: 磁盘IO竞争。
- 根因: 该Pod的日志级别被误设为DEBUG,导致每秒产生大量日志。
- 解决方案: 调整日志级别,并考虑将日志挂载到独立的、更高性能的卷上。