调试处于 NotReady 状态的 Kubernetes 节点

发布: (2026年2月22日 GMT+8 00:20)
8 分钟阅读
原文: Dev.to

Source: Dev.to

Matheus

一个卡在 NotReady 状态的节点是最常见且最具破坏性的 Kubernetes 问题之一。当节点变为 NotReady 时,控制平面会停止向其调度新 Pod,并在超时后开始驱逐现有工作负载。

下面介绍如何诊断根本原因并加以解决。

NotReady 是什么意思?

每个 Kubernetes 节点都会运行一个 kubelet 进程,定期向 API 服务器报告其状态。当 API 服务器停止收到这些心跳(默认:每 10 秒一次,超时后 40 秒),它会将节点标记为 NotReady

NotReady 状态表示:控制平面无法确认该节点健康且可用于工作。

使用以下命令检查节点状态:

kubectl get nodes

显示问题的输出:

NAME          STATUS     ROLES    AGE   VERSION
worker-01     Ready         45d   v1.34.2
worker-02     NotReady      45d   v1.34.2
worker-03     Ready         45d   v1.34.2

Step 1: Check Node Conditions

Start with kubectl describe node to see what conditions are reported:

kubectl describe node worker-02

Look at the Conditions section:

Conditions:
Type                 Status  Reason
----                 ------  ------
MemoryPressure       False   KubeletHasSufficientMemory
DiskPressure         True    KubeletHasDiskPressure
PIDPressure          False   KubeletHasSufficientPID
Ready                False   KubeletNotReady

Common condition flags

ConditionMeaning
DiskPressure: True节点文件系统空间不足。当磁盘使用率超过驱逐阈值(默认 85%)时,Kubernetes 会开始驱逐 Pod。
MemoryPressure: TrueRAM 已耗尽。kubelet 会根据 Pod 的 QoS 类别杀死相应的 Pod。
PIDPressure: True节点的进程 ID 用尽,通常是由于 Pod 中的 fork‑bomb 或容器进程泄漏导致。
Ready: False通用的 “kubelet 不健康” 状态;需要进一步检查 kubelet 日志以定位问题。

步骤 2:检查 Kubelet 日志

Kubelet 是维护节点健康的代理。如果它崩溃或配置错误,节点会变为 NotReady

# SSH into the node
ssh worker-02

# Check kubelet status
systemctl status kubelet

# View recent logs
journalctl -u kubelet --since "10 minutes ago" --no-pager

常见 kubelet 问题

症状可能原因解决办法
kubelet 服务已停止进程崩溃或 OOM 被杀systemctl restart kubelet
证书已过期TLS 证书轮换失败kubeadm certs renew all
“Failed to connect to apiserver”网络问题或 API 服务器宕机检查网络、防火墙规则、API 服务器健康状态
“PLEG is not healthy”容器运行时出现问题systemctl restart containerd
“node not found”节点已从集群中删除重新加入:kubeadm join …

第3步:检查容器运行时

Kubernetes 依赖容器运行时(containerd 或 CRI‑O)。如果运行时出现异常,kubelet 将无法管理 Pod。

# Check containerd status
systemctl status containerd

# Check runtime endpoint
crictl info

# List containers (should show running system containers)
crictl ps

如果 containerd 无响应:

systemctl restart containerd
systemctl restart kubelet

Step 4: 检查资源耗尽

导致 NotReady 节点的最常见原因是资源耗尽。

磁盘空间

df -h /
df -h /var/lib/kubelet
df -h /var/lib/containerd

修复方法: 清理未使用的容器镜像和已停止的容器。

# containerd
crictl rmi --prune

# Docker(如果使用)
docker system prune -af

内存

free -h
# 检查内存占用最高的进程
ps aux --sort=-%mem | head -20

修复方法: 找出占用过多内存的 Pod 并确保已设置资源限制。

kubectl top pods --all-namespaces --sort-by=memory | head -20

进程 ID

# 检查当前 PID 数量与上限
cat /proc/sys/kernel/pid_max
ls /proc | grep -c '^[0-9]'

第5步:检查网络

如果节点无法访问 API 服务器,即使它本身健康,也会显示 NotReady

# 测试 API 服务器连通性
curl -k https://:6443/healthz

# 检查 DNS 解析
nslookup kubernetes.default.svc.cluster.local

# 验证网络插件(CNI)是否在运行
crictl ps | grep -E "calico|flannel|cilium|weave"

CNI 插件崩溃? 这其实相当常见。如果你的网络插件 Pod(Calico、Flannel、Cilium 等)未运行,所有网络都会失效:

kubectl get pods -n kube-system | grep -E "calico|flannel|cilium"

第6步:检查云提供商问题

  • 实例已被 自动伸缩器或抢占式实例回收 终止
  • 实例健康检查在云提供商层面失败

(根据您特定云提供商的诊断继续排查。)

网络 ACL 或安全组阻止 kubelet‑to‑API‑server 流量

检查您云提供商的实例状态:

# AWS EKS
aws ec2 describe-instance-status --instance-ids <instance-id>

# GKE – check node pool status
gcloud container node-pools describe <node-pool> --cluster <cluster-name>

# AKS
az aks nodepool show --name <nodepool-name> --cluster-name <cluster-name> -g <resource-group>

预防:在 NotReady 发生前阻止它

  • 为所有 Pod 设置资源请求和限制。如果没有限制,单个 Pod 可能会消耗全部内存并导致节点崩溃。
  • 在托管服务上启用节点自动修复(GKE 和 AKS 原生支持;EKS 通过节点健康检查实现)。
  • 监控磁盘使用情况,并在达到 70 % 容量时设置警报,远早于 85 % 驱逐阈值。
  • 使用 Pod 中断预算(PDB) 来控制可以同时被驱逐的 Pod 数量。
  • 保持 Kubernetes 版本最新。旧版本存在已知的 kubelet bug,可能导致错误的 NotReady 事件。可在 ReleaseRun 上检查您所使用版本的健康状态。

快速故障排除流程图

kubectl describe node    # Check conditions
  • DiskPressure/MemoryPressure 为 true 吗? → 清理资源。
  • kubelet 正在运行吗?systemctl status kubelet → 如有必要重新启动。
  • containerd 正在运行吗?systemctl status containerd → 如有必要重新启动。
  • 节点能够访问 API 服务器吗? → 检查网络/防火墙规则。
  • CNI 插件正在运行吗? → 核实 kube‑system 命名空间下的 pod。
  • 仍然卡住? → 查看 journalctl -u kubelet 获取具体错误信息。

跟踪您的 Kubernetes 版本健康

运行较旧的 Kubernetes 版本会增加 kubelet 错误导致 NotReady 事件的风险。Kubernetes 1.32 将于 2026年2月28日 达到生命周期终止(EOL)。如果您仍在使用该版本,请查阅我们的 迁移手册

ReleaseRun 的 Kubernetes 中心 监控每个版本的健康状态、CVE 状况以及 EOL 日期。

相关阅读

0 浏览
Back to Blog

相关文章

阅读更多 »

从船长的椅子:Kristiyan Velkov

Docker 沙箱:在不受监督的情况下安全运行 Claude Code 等编码代理 2026 年 1 月 30 日 为 Claude Code、Gemini、Codex 和 Kiro 提供安全沙箱。运行 c...