Kubernetes节点NotReady故障的完整排查路径从kubelet到内核的逐层定位方法论一、故障识别与应急响应机制Kubernetes集群中节点NotReady是最常见的故障类型之一。节点状态变为NotReady后调度器停止向该节点分配新Pod。已运行的Pod在容忍时间过后被驱逐。业务服务的可用性受到直接影响。故障应急响应的第一步是确认影响范围。使用kubectl get nodes查看所有节点状态。关注NotReady节点的数量和分布。如果多个节点同时NotReady可能是控制面或网络问题。如果单个节点NotReady定位方向集中在节点本身。第二步是保护业务连续性。为关键Deployment配置PodDisruptionBudget(PDB)。PDB限制同时不可用的Pod数量。合理设置terminationGracePeriodSeconds。给予应用足够的时间优雅退出。检查HPA是否正常工作。防止流量倾斜导致雪崩。第三步是建立排查时间线。记录故障首次发现时间。记录告警触发时间、节点状态变化时间、以及最近的变更记录。变更记录是排查的重要线索。集群升级、配置变更、资源调整都可能引发NotReady。graph TD A[节点NotReady告警] -- B{受影响节点数量} B --|单节点| C[节点级排查] B --|多节点| D[集群级排查] C -- E[kubelet状态检查] E -- F{状态正常?} F --|否| G[查看kubelet日志] F --|是| H[容器运行时检查] G -- I[修复kubelet问题] H -- J{运行时正常?} J --|否| K[运行时故障排查] J --|是| L[内核与资源排查] K -- M[重启或修复运行时] L -- N[Disk/CPU/Memory] L -- O[内核日志分析] D -- P[控制面组件检查] D -- Q[网络连通性检查] P -- R[检查etcd/api-server] Q -- S[CNI插件诊断]二、第一层排查kubelet组件诊断kubelet是K8s节点代理的核心组件。它负责与api-server通信。管理Pod生命周期。上报节点状态。kubelet故障会直接导致节点NotReady。排查从kubelet服务状态开始。执行systemctl status kubelet确认服务是否运行。如果kubelet频繁重启。使用journalctl -u kubelet -f实时查看日志。重点关注以下错误模式。第一种错误模式证书过期。kubelet与api-server的通信基于TLS证书。证书过期会导致认证失败。日志中出现x509: certificate has expired。解决方案是执行kubeadm certs renew更新证书并重启kubelet。第二种错误模式磁盘空间不足。kubelet依赖磁盘存储Pod日志和临时数据。当imagefs或nodefs使用率超过阈值时。kubelet触发磁盘压力驱逐。使用df -h检查磁盘使用率。清理过期镜像和日志释放空间。第三种错误模式PLEG(Pod Lifecycle Event Generator)异常。PLEG是kubelet的内部组件。通过CRI接口轮询容器状态。PLEG卡住会导致kubelet无法正确上报Pod状态。日志中出现PLEG is not healthy。通常是容器运行时响应缓慢导致。#!/bin/bash # kubelet健康检查脚本 NODE_NAME$(hostname) LOG_FILE/var/log/kubelet-check.log # 记录检查时间戳 echo 检查时间: $(date) $LOG_FILE # 1. 检查kubelet服务状态 echo [1/5] 检查kubelet服务状态... $LOG_FILE if ! systemctl is-active --quiet kubelet; then echo [错误] kubelet服务未运行 $LOG_FILE systemctl status kubelet --no-pager $LOG_FILE 21 else echo [通过] kubelet服务运行中 $LOG_FILE fi # 2. 检查PLEG健康状态(从kubelet日志) echo [2/5] 分析PLEG健康状态... $LOG_FILE if journalctl -u kubelet --since 5 minutes ago \ | grep -q PLEG is not healthy; then echo [错误] 检测到PLEG异常 $LOG_FILE else echo [通过] PLEG状态正常 $LOG_FILE fi # 3. 检查磁盘使用率 echo [3/5] 检查磁盘使用率... $LOG_FILE DISK_USAGE$(df / | awk NR2 {print $5} | sed s/%//) if [ $DISK_USAGE -gt 85 ]; then echo [警告] 磁盘使用率: ${DISK_USAGE}%, 超过85%阈值 $LOG_FILE else echo [通过] 磁盘使用率: ${DISK_USAGE}% $LOG_FILE fi # 4. 检查inode使用率 echo [4/5] 检查inode使用率... $LOG_FILE INODE_USAGE$(df -i / | awk NR2 {print $5} | sed s/%//) if [ $INODE_USAGE -gt 85 ]; then echo [警告] inode使用率: ${INODE_USAGE}%, 超过85%阈值 $LOG_FILE else echo [通过] inode使用率: ${INODE_USAGE}% $LOG_FILE fi # 5. 检查节点条件(Condition) echo [5/5] 检查节点Condition... $LOG_FILE kubectl describe node $NODE_NAME 2/dev/null \ | grep -A5 Conditions: $LOG_FILE || \ echo [错误] 无法获取节点信息(kubectl不可用或集群不可达) $LOG_FILE echo 检查完成结果已写入 $LOG_FILE三、第二层排查容器运行时诊断kubelet通过CRI(Container Runtime Interface)与容器运行时交互。主流的运行时包括containerd和CRI-O。运行时故障会影响Pod的创建、启停和状态上报。首先确认容器运行时服务状态。containerd使用systemctl status containerd。CRI-O使用systemctl status crio。如果运行时服务正常但kubelet报告错误。使用crictl工具直接与CRI通信。这样可以隔离问题是在运行时层还是kubelet层。crictl pods列出运行时感知的所有Pod。与kubectl get pods的结果对比。如果kubelet显示Running但crictl显示不存在。说明kubelet状态与运行时状态不一致。可能是kubelet缓存问题。重启kubelet通常可以解决。crictl ps -a列出所有容器及其状态。关注处于Exited或Unknown状态的关键容器。查看容器日志定位退出原因。如果容器OOMKilled检查内存限制是否合理。如果容器频繁重启(CrashLoopBackOff)。检查应用启动逻辑和健康检查配置。crictl stats查看容器资源使用情况。如果某个容器消耗了所有节点资源。导致运行时响应变慢。PLEG检测超时。最终kubelet上报NotReady。四、第三层排查内核与系统资源诊断内核层的故障通常表现为系统调用hang、OOM Kill、文件系统只读等。这些故障直接导致容器运行时和kubelet无法正常工作。内核日志是关键的排查线索。使用dmesg -T | tail -100查看最近的日志。重点关注以下几类事件。第一OOM Kill事件。日志中出现Out of memory: Killed process。说明节点内存耗尽。需要分析内存使用峰值。调整Pod的资源限制或增加节点资源。第二文件系统错误。日志中出现EXT4-fs error、I/O error或Buffer I/O error。可能是磁盘硬件故障或文件系统损坏。使用fsck检查并修复文件系统。严重时需要更换磁盘。第三内核死锁或RCU stall。日志中出现INFO: task blocked for more than X seconds。或RCU stall detected。表明内核线程阻塞。可能由存储驱动异常或内核bug导致。收集crash dump进行分析。必要时升级内核版本。第四网络栈异常。conntrack表满是最常见的网络问题。dmesg中出现nf_conntrack: table full。使用conntrack -S检查表使用情况。调整nf_conntrack_max参数。#!/bin/bash # 系统层面全面健康检查 report() { echo [$(date %H:%M:%S)] $1 } # 检查内核日志中的严重事件 report 内核严重事件检查 ALERTS$(dmesg -T --levelemerg,alert,crit,err 2/dev/null | tail -20) if [ -n $ALERTS ]; then report 检测到内核严重事件: echo $ALERTS else report 内核日志无严重事件 fi # 检查conntrack表使用率 report conntrack表检查 if command -v conntrack /dev/null; then CONNTRACK_COUNT$(conntrack -C 2/dev/null || echo 0) CONNTRACK_MAX$(sysctl -n net.netfilter.nf_conntrack_max 2/dev/null || echo 0) if [ $CONNTRACK_MAX -gt 0 ]; then USAGE$(( CONNTRACK_COUNT * 100 / CONNTRACK_MAX )) report conntrack使用率: ${USAGE}% (${CONNTRACK_COUNT}/${CONNTRACK_MAX}) if [ $USAGE -gt 90 ]; then report [警告] conntrack表使用率超过90% fi fi fi # 检查系统Load与CPU report 系统负载检查 LOAD$(uptime | awk -Fload average: {print $2}) CPU_COUNT$(nproc) report 系统负载:${LOAD} | CPU核心数: ${CPU_COUNT} # 检查内存使用 report 内存使用检查 free -h | grep -E Mem|Swap | while read -r line; do report $line done五、总结Kubernetes节点NotReady的排查遵循自底向上的逐层方法论。第一层检查kubelet组件服务状态、证书有效期、PLEG健康、磁盘空间。第二层检查容器运行时CRI接口响应、容器状态一致性、资源消耗异常。第三层检查内核与系统资源OOM、文件系统错误、内核死锁、网络栈异常。为提升排查效率建议建立以下机制。部署节点级监控采集kubelet、CRI和内核的关键指标。配置Predictive Disk/Resource告警。在磁盘使用率达到80%时提前预警。在节点上部署预置的排查脚本。故障发生时一键运行收集诊断信息。建立故障知识库记录历史案例和解决方案。持续优化排查路径。最关键的原则是不要慌张。先确认影响范围。保护业务连续性。再逐层定位根因。记录排查全过程。为事后复盘和改进提供依据。