K8s节点NotReady故障排查实战手册:12种典型场景与精准修复策略

当集群监控大屏突然亮起红色告警,某个节点状态赫然显示"NotReady"时,作为运维负责人的你,心跳是否漏了半拍?别担心,这份手册将带你像资深SRE一样,快速锁定问题根源并实施精准修复。不同于常规理论文档,我们直接从生产环境中最常见的12种故障模式切入,每个案例都配有 可立即执行的诊断命令 已验证的解决方案

1. 节点状态基础诊断框架

在深入具体案例前,我们需要建立系统化的排查路径。以下是每个NotReady节点都应该执行的基础检查流程:

第一步:快速状态确认

# 获取节点基础状态
kubectl get nodes -o wide
# 查看详细事件记录
kubectl describe node <故障节点名称> | grep -A 20 "Conditions:"

第二步:核心组件健康检查

# 检查kubelet运行状态(节点上执行)
systemctl status kubelet --no-pager -l
# 查看最近50条kubelet日志
journalctl -u kubelet -n 50 --no-pager | grep -i error

第三步:资源瓶颈分析

# 内存与交换分区检查
free -h
# 磁盘空间分析(重点关注/var分区)
df -h | grep -v tmpfs
# 进程资源占用排序
ps aux --sort=-%mem | head -10

提示:将上述命令保存为 node_check.sh 并赋予执行权限,可快速建立排查工具包

关键指标阈值参考表

指标类型 正常范围 危险阈值 检查命令
内存可用量 >总内存20% <500MB free -h
根分区使用率 <80% >90% df -h /
CPU负载(5分钟) <核心数×2 >核心数×4 uptime
节点时钟偏移 <100ms >500ms ntpstat

2. 网络连接类故障排查

2.1 Case 1: "use of closed network connection"错误

典型现象

  • 节点日志持续输出 write tcp 127.0.0.1:37742->127.0.0.1:60443: use of closed network connection
  • kubelet与API Server的通信时断时续

根本原因 : 这是Kubernetes处理HTTP/2连接时的一个已知问题,当连接处于半关闭状态时,kubelet仍尝试发送数据会导致此错误。该问题在以下版本中已修复:

  • v1.22.15+
  • v1.23.12+
  • v1.24.6+

应急处理方案

# 重启kubelet服务
systemctl restart kubelet
# 验证修复(观察5分钟)
watch -n 5 'kubectl get nodes | grep <节点名>'

长期解决方案 : 升级集群到已修复版本,或应用以下补丁配置:

# kubelet配置片段
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
http2MaxStreamsPerConnection: 100  # 默认250,降低可减少连接竞争

2.2 Case 2: etcd请求超时

典型现象

  • 日志出现 etcdserver: request timed out
  • 节点状态在Ready与NotReady间频繁波动

排查步骤

# 检查etcd集群健康状态
ETCDCTL_API=3 etcdctl --endpoints=https://<etcd-ip>:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key endpoint health

# 查看etcd存储性能
ETCDCTL_API=3 etcdctl --write-out=table endpoint status

常见修复方案

  1. 存储空间优化
# 获取当前修订版本
rev=$(ETCDCTL_API=3 etcdctl --endpoints=... endpoint status | grep -oP 'revision:\s+\K\d+')
# 执行压缩操作
ETCDCTL_API=3 etcdctl --endpoints=... compact $((rev-1000))
# 整理碎片
ETCDCTL_API=3 etcdctl --endpoints=... defrag
  1. 性能调优参数
# etcd启动参数建议
--quota-backend-bytes=8589934592  # 8GB空间限制
--auto-compaction-retention=24h    # 24小时自动压缩
--enable-pprof=true                # 开启性能分析

3. 运行时与资源类故障

3.1 Case 3: 容器运行时无响应

典型现象

  • 日志显示 container runtime status check may not have completed yet
  • docker ps crictl ps 命令卡死

问题定位

# 检查容器运行时进程状态
ps aux | grep -E 'dockerd|containerd'
# 强制清理卡死的容器进程
for pid in $(ps -ef | grep -E 'docker-containerd-shim|containerd-shim' | awk '{print $2}'); do
  kill -9 $pid
done

根治方案

# 重建容器运行时服务
systemctl stop kubelet
systemctl stop docker
rm -rf /var/lib/docker/containerd/*
systemctl start docker
systemctl start kubelet

3.2 Case 4: 镜像文件系统异常

典型现象

  • 事件日志出现 Warning InvalidDiskCapacity invalid capacity 0 on image filesystem
  • 新Pod无法拉取镜像

快速修复

# 重启containerd服务
systemctl restart containerd
# 验证修复
crictl images

深度处理

# 检查存储驱动配置
cat /etc/containerd/config.toml | grep -A 5 '^\[plugins\.\"io\.containerd\.grpc\.v1\.cri\"\.containerd\.runtimes\.runc\.options\]'
# 典型配置示例
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
  SystemdCgroup = true

4. 配置与系统类故障

4.1 Case 5: 节点时间不同步

典型现象

  • 日志中出现 systemd: Time has been changed
  • 跨节点服务调用出现证书验证失败

诊断与修复

# 检查时间偏移量
chronyc tracking | grep -i skew
# 强制立即同步
chronyc makestep
# 检查NTP服务状态
systemctl status chronyd

配置建议

# /etc/chrony.conf 关键配置
pool 2.cn.pool.ntp.org iburst
makestep 1.0 3
maxdistance 1.0

4.2 Case 6: cgroup驱动不一致

典型现象

  • 日志报错 cgroup driver "cgroupfs" is different from docker
  • kubelet启动后立即崩溃

解决方案

# 修改kubelet启动参数
sed -i 's/--cgroup-driver=.*/--cgroup-driver=systemd/' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
# 应用配置
systemctl daemon-reload
systemctl restart kubelet

验证方法

docker info | grep -i cgroup
kubelet --cgroup-driver | grep systemd

5. 高级诊断工具与技术

5.1 节点事件智能分析

使用kubectl结合jq进行高级事件过滤:

# 提取最近1小时的关键警告事件
kubectl get events --field-selector type=Warning \
  -o json | jq -r '.items[] | select(.lastTimestamp > "'$(date -d '1 hour ago' -Ins --utc | sed 's/+0000/Z/')'") | .message'

5.2 Prometheus监控集成

关键监控指标示例:

# 节点就绪状态
kube_node_status_condition{condition="Ready",status="true"}

# PLEG健康检查
rate(kubelet_pleg_relist_duration_seconds_sum[5m]) > 1

# 资源压力预测
predict_linear(node_memory_MemAvailable_bytes[1h], 3600) < 0

5.3 自动化修复脚本示例

#!/bin/bash
NODE=$1

function check_kubelet() {
  ssh $NODE "systemctl is-active kubelet" | grep -q active || {
    echo "Restarting kubelet..."
    ssh $NODE "systemctl restart kubelet"
  }
}

function check_docker() {
  ssh $NODE "docker ps" >/dev/null 2>&1 || {
    echo "Restarting docker..."
    ssh $NODE "systemctl restart docker"
  }
}

check_kubelet
check_docker

6. 最佳实践与经验总结

在管理过数十个生产集群后,我总结出以下节点稳定性保障原则:

  1. 预防性维护周期

    • 每周检查节点时钟同步状态
    • 每月验证etcd存储健康度
    • 每季度审计kubelet配置一致性
  2. 关键配置清单

    - [ ] 确保所有节点使用相同的容器运行时版本
    - [ ] 统一cgroup驱动配置(推荐systemd)
    - [ ] 设置合理的kubelet--node-status-update-frequency(默认10s)
    - [ ] 配置适当的--eviction-hard内存阈值(建议memory.available<500Mi)
    
  3. 故障演练建议

    • 定期模拟网络分区场景
    • 测试磁盘压力下的Pod驱逐行为
    • 验证kubelet自动恢复能力

记住,节点NotReady状态就像发烧症状,关键是要快速找到真正的病因。掌握这12种典型案例的处理方法,配合系统化的排查流程,你就能在下次告警响起时从容应对。

更多推荐