worker01 NotReady 排查与修复步骤

文章目录

    • [为什么其他节点也是 localhost:6443 却是 Ready?(Kubespray 设计)](#为什么其他节点也是 localhost:6443 却是 Ready?(Kubespray 设计))
    • [诊断结论(从 control plane 与 worker01 日志)](#诊断结论(从 control plane 与 worker01 日志))
    • [在 worker01 上执行的步骤(SSH 到 192.168.22.152)](#在 worker01 上执行的步骤(SSH 到 192.168.22.152))
      • [1. SSH 登录](#1. SSH 登录)
      • [2. 检查 kubelet 与 containerd](#2. 检查 kubelet 与 containerd)
      • [3. 处理 "invalid capacity 0 on image filesystem"](#3. 处理 “invalid capacity 0 on image filesystem”)
      • [4. 确认本机 6443 与 Kubespray 代理(重要)](#4. 确认本机 6443 与 Kubespray 代理(重要))
      • [5. 再次查看 kubelet 日志(重点看 Ready 与 image filesystem)](#5. 再次查看 kubelet 日志(重点看 Ready 与 image filesystem))
      • [6. 从 control plane 侧再次检查](#6. 从 control plane 侧再次检查)
    • 小结

为什么其他节点也是 localhost:6443 却是 Ready?(Kubespray 设计)

Kubespray 部署的集群里,worker 节点上的 kubelet.confserver: https://localhost:6443预期配置,不是笔误。

  • Kubespray 在每个节点(包括 worker)上会跑一个 本机 API 代理 (例如 nginx-proxy-<node名> Pod),在本机 监听 127.0.0.1:6443,把 kubelet 的请求转发到真正的 apiserver(master 或 LB)。
  • 所以 kubelet 配 https://localhost:6443 时,实际连的是本机上的这个代理,由代理再去连 control plane。
  • worker02 Ready:说明 worker02 上的 nginx-proxy 等代理 Pod 正常运行,本机 6443 有进程在监听,kubelet 能连上。
  • worker01 NotReady :说明 worker01 上没有进程在监听 localhost:6443 ,所以 kubelet 报 connection refused。常见原因是:该节点上的 nginx-proxy(或等价代理)Pod 没起来------例如因重启后 containerd 的 sandbox 状态异常,导致 "sandbox name is reserved" 等错误,Pod 创建失败,代理自然起不来。

因此:不要 把 worker01 的 kubelet 改成直连 master IP,否则会和 Kubespray 设计不一致(证书/代理都按 localhost 设计)。应恢复本机代理能正常启动,即解决 containerd sandbox 冲突,让 nginx-proxy 等 Pod 在 worker01 上跑起来。


诊断结论(从 control plane 与 worker01 日志)

  • 节点: worker01,IP 192.168.22.152
  • 状态 : NotReady,Condition 为 NodeStatusUnknown,信息为 "Kubelet stopped posting node status."
  • Taints : node.kubernetes.io/unreachable:NoExecuteNoSchedule
  • 关键事件 : 节点 Rebooted ;kubelet 连 https://localhost:6443connection refused ;CreatePodSandbox 报 sandbox name is reserved for xxx(nodelocaldns、nginx-proxy-worker01、kube-proxy 等);Calico 访问 10.233.0.1 超时(因节点未 Ready,网络未就绪)。

结论 :worker01 上负责监听 localhost:6443 的 nginx-proxy(或等价)Pod 起不来 ,根因是 containerd 侧 sandbox 名字占用冲突 (重启后状态不同步)。应在本机清理 containerd 的 CRI 状态并重启 containerd/kubelet,使 nginx-proxy 等系统 Pod 能正常创建,本机 6443 有代理监听后 kubelet 即可上报、节点变为 Ready。


在 worker01 上执行的步骤(SSH 到 192.168.22.152)

1. SSH 登录

bash 复制代码
ssh 192.168.22.152
# 或使用你的跳板机/账号,例如: ssh user@192.168.22.152

2. 检查 kubelet 与 containerd

bash 复制代码
sudo systemctl status kubelet
sudo systemctl status containerd

若任一为 inactivefailed,先尝试启动并看日志:

bash 复制代码
sudo systemctl start containerd
sudo systemctl start kubelet
sudo journalctl -u kubelet -n 80 --no-pager
sudo journalctl -u containerd -n 50 --no-pager

3. 处理 "invalid capacity 0 on image filesystem"

该告警通常与 kubelet 使用的「镜像文件系统」路径有关(containerd 的 root 或 image 目录)。检查以下目录是否存在、可读且所在分区非满:

bash 复制代码
# 镜像/容器数据目录
sudo df -Th /var/lib/containerd
sudo df -Th /var/lib/kubelet
ls -la /var/lib/containerd
ls -la /var/lib/kubelet

# 若使用 overlay,看 overlay 挂载
mount | grep overlay

/var/lib/containerd 或 kubelet 的 image 目录在异常挂载上(或刚重启未挂好),先确保挂载正常,再重启 containerd 和 kubelet:

bash 复制代码
sudo systemctl restart containerd
sleep 5
sudo systemctl restart kubelet

4. 确认本机 6443 与 Kubespray 代理(重要)

Kubespray 下 kubelet 连的是本机 localhost:6443,由本机上的 nginx-proxy 等 Pod 代理到 apiserver。先确认本机是否有进程在监听 6443:

bash 复制代码
# 本机 6443 是否有监听(若为空说明 nginx-proxy 等代理未起)
ss -tlnp | grep 6443
# 或
sudo netstat -tlnp | grep 6443
  • 若 6443 无监听:说明本机 API 代理 Pod(如 nginx-proxy-worker01)没起来,需先修 containerd/sandbox(见下),让该 Pod 能创建;或临时改 kubelet server 为 master 地址以恢复 Ready,再修代理。

  • 若有监听 :再测 kubelet 能否连上:

    bash 复制代码
    curl -sk https://127.0.0.1:6443/healthz

从本机测到 control plane 的直连(可选,用于判断网络是否通):

bash 复制代码
curl -sk https://192.168.22.151:6443/healthz

若本机 6443 无监听且日志里有 "sandbox name is reserved",优先做 containerd 状态清理

bash 复制代码
sudo systemctl stop kubelet
sudo systemctl stop containerd

清理 CRI sandbox 目录时,若出现 "Device or resource busy" (多为 sandbox 下的 shm tmpfs 仍挂载),需先卸载再删:

bash 复制代码
# 先卸载 sandbox 下的 shm 挂载点
SANDBOX_ROOT=/var/run/containerd/io.containerd.grpc.v1.cri/sandboxes
for d in "$SANDBOX_ROOT"/*/shm; do
  [ -d "$d" ] && sudo umount "$d" 2>/dev/null
done
# 再删除 sandbox 目录
sudo rm -rf "$SANDBOX_ROOT"/*

然后启动服务:

bash 复制代码
sudo systemctl start containerd
sleep 5
sudo systemctl start kubelet

若重启后仍报 "sandbox name ... is reserved for 633ecebd..." 等:说明名字占用在 containerd 内部状态里,只删 sandbox 目录不够,需要二选一:

方法 A:用 crictl 删掉占用的 sandbox(先试)

bash 复制代码
# 看所有 pod(含已退出的),找到对应 SANDBOX_ID 的 pod
crictl pods -a
# 若日志里写的 reserved for 633ecebd...,看是否有该 ID 或对应 nginx-proxy 的 pod,然后停掉并删掉
crictl stopp <POD_ID>   # 若还在跑
crictl rmp <POD_ID>     # 删除 pod,会释放 sandbox 名字

方法 B:清空整个 CRI 运行时状态(方法 A 找不到或删不掉时)

停 kubelet/containerd 后,先 umount sandbox 下的 shm(同上),然后删掉整个 CRI 状态目录,让 containerd 不再保留任何 sandbox 名字:

bash 复制代码
sudo systemctl stop kubelet
sudo systemctl stop containerd

SANDBOX_ROOT=/var/run/containerd/io.containerd.grpc.v1.cri/sandboxes
for d in "$SANDBOX_ROOT"/*/shm; do [ -d "$d" ] && sudo umount "$d" 2>/dev/null; done
sudo rm -rf /var/run/containerd/io.containerd.grpc.v1.cri
# 然后启动
sudo systemctl start containerd
sleep 5
sudo systemctl start kubelet

删掉 io.containerd.grpc.v1.cri 后,该节点上所有 CRI 的 sandbox/容器状态会清空,kubelet 会按当前 Pod 列表重新创建,包括 nginx-proxy。

然后观察 nginx-proxy 等 Pod 是否在 worker01 上 Running,以及 ss -tlnp | grep 6443 是否出现。

5. 再次查看 kubelet 日志(重点看 Ready 与 image filesystem)

bash 复制代码
sudo journalctl -u kubelet -f -n 100 --no-pager

观察是否仍有 InvalidDiskCapacityimage filesystem 相关报错;正常时应有 "Node worker01 status is now: NodeReady" 之类事件。

6. 从 control plane 侧再次检查

可执行 kubectl 的机器 上执行:

bash 复制代码
kubectl get nodes
kubectl describe node worker01

若 Ready 恢复,节点上的 unreachable taint 通常会由 control plane 自动清理;若长时间未清理,可手动去掉 taint(仅在确认节点已正常后):

bash 复制代码
kubectl taint nodes worker01 node.kubernetes.io/unreachable:NoExecute-
kubectl taint nodes worker01 node.kubernetes.io/unreachable:NoSchedule-

小结

项目 内容
节点 worker01,192.168.22.152
现象 NotReady,kubelet 连 localhost:6443 被拒;CreatePodSandbox "sandbox name is reserved"
原因 Kubespray 用本机 nginx-proxy 提供 localhost:6443;worker01 上该 Pod 因 sandbox 冲突起不来
建议操作 SSH 到 worker01 → 确认 `ss -tlnp

按上述步骤在 worker01 上执行后,若仍有问题,把 journalctl -u kubelet -n 100describe node worker01 的完整输出贴出即可继续排查。

相关推荐
可观测性用观测云21 小时前
云原生网关 Ingress-Nginx 链路追踪实战:OpenTelemetry 采集与观测云集成方案
nginx·kubernetes
哈里谢顿2 天前
Kubernetes Operator核心概念、实现原理和实战开发
云原生
阿里云云原生2 天前
你的 OpenClaw 真的在受控运行吗?
云原生
阿里云云原生2 天前
5 分钟零代码改造,让 Go 应用自动获得全链路可观测能力
云原生·go
Shanyoufusu122 天前
RKE2 单节点集群安装 Rancher+ 私有镜像仓库搭建 完整教程
云原生
阿里云云原生2 天前
Dify 官方上架 Higress 插件,轻松接入 AI 网关访问模型服务
云原生
AI攻城狮2 天前
OpenClaw Session 管理完全指南:Context 压缩、重置与持久化
人工智能·云原生·aigc
蝎子莱莱爱打怪3 天前
GitLab CI/CD + Docker Registry + K8s 部署完整实战指南
后端·docker·kubernetes
阿里云云原生6 天前
阿里云获评 Agentic AI 开发平台领导者,函数计算 AgentRun 赢下关键分!
云原生
蝎子莱莱爱打怪6 天前
Centos7中一键安装K8s集群以及Rancher安装记录
运维·后端·kubernetes