Rancher Windows节点卡 Waiting for Node Ref?排查 no VM found 全过程
2026/9/16 4:33:46 网站建设 项目流程

Rancher 里加 Windows worker 节点,最让人头疼的就是卡在 “Waiting for Node Ref” 这步。我接触过不少集群,Windows 节点本来就有各种兼容性包袱,再碰上这种状态,基本等于节点白加了,kubelet 起不来不代表注册成功,卡住之后 UI 上一直转圈,集群 CPU 也一直在空转。最近又有一个环境踩了同样的坑,报错里还多了一句 “no VM found error”,排查了一下午,把整个过程记下来,给后面遇到的人一个参考。

先说结论:这个状态本质上是 Rancher 的 node controller 没能把“集群里的 Node 对象”和“Rancher 自己管理的机器记录(Node Ref)”绑定起来。而 “no VM found” 大概率是基础设施层的信息丢了,或者节点驱动创建实例时就没把 VM 元数据写全。下面拆开讲。

1. 先搞清楚 “Waiting for Node Ref” 和 “no VM found” 到底在说什么

1.1 Rancher 的节点生命周期:Node、Machine、Node Ref 三者的关系

打开 Rancher UI 看节点列表时,你看到的每一行其实对应着两层数据:一层是 Kubernetes 集群里的node对象(由 kubelet 启动后注册到 kube-apiserver),另一层是 Rancher 自己维护的cluster.provisioning.cattle.iomanagement.cattle.io下的 machine 记录。Rancher 靠Node Ref把这两者关联起来。

当你通过 Rancher 添加节点(不管是自定义节点还是通过 vSphere 等节点驱动),控制平面会先创建一个 machine 对象,里面写好 hostname、角色、标签等期望信息。然后 kubelet 启动、注册 Node 对象后,Rancher 的 node controller 会把 Node 对象的名字(通常是主机名)和 machine 对象里的spec.nodeName做匹配。匹配成功后,UI 上这个节点才会从 “Waiting for Node Ref” 变成 Ready。

这个机制说白了就相当于:你要把一个人加入通讯录,得先有他的登记表,然后他本人来公司报到,报到时用自己的姓名和登记表对上号。登记表写了张三,来的人也叫张三,系统才能把他标记为“在职”。

1.2 “no VM found” 是从哪儿冒出来的

这个错误并不是每台卡住的 Windows 节点都会出现,它更容易出现在用 vSphere、AWS、Azure 这类节点驱动创建节点的场景里。

Rancher 通过节点驱动创建 Windows worker 时,会调用对应的云平台 API 去创建虚拟机。如果 VM 已经创建成功但后续被外部删除、改名为别的,或者 vCenter 里的文件夹/资源池路径变了,Rancher 的 machine controller 在同步状态时去查 VM 信息,查到不到就会抛no VM found。这个错误一旦出现,节点状态就更不可能推进到 Node Ref 匹配成功,因为 Rancher 认为这台机器已经不存在了。

另一种情况是 Rancher 使用自定义命令注册 Windows 节点,但注册脚本中的CATTLE_NODE_NAME或主机名参数和 Rancher 里 hostname 的预期值不一致,也会在日志里出现类似找不到对应机器元数据的提示。虽然严格说不是真的找不到 VM,但表达出来的问题本质一样:机器身份对不上。

2. 故障定位:不要急着删节点,先抓证据

遇到这种状态,很多人第一反应是把节点从 Rancher 里删掉重来。先忍住。硬删有风险,比如 node 对象变成 terminating 一直清不掉,或者 Rancher 里记录残留导致重新添加时依然报错。正确的做法是先花十几分钟把现场信息抓全。

2.1 在 Rancher 侧确认当前状态

先到 Rancher UI 的集群节点页面,看节点列表是否显示:

  • Node 名称是空的,还是已经显示主机名
  • 状态列是不是一直显示 Waiting
  • “查看详情”(三个点里的 View YAML)里对象的状态字段是什么

更可靠的方式是直接用 kubectl 看 Rancher 侧的 CRD,假设你通过 kubeconfig 能访问到 local 集群(也叫 Rancher Server 所在的集群),可以执行:

kubectl get machine -n fleet-default -o wide kubectl get cluster.provisioning.cattle.io <集群名> -n fleet-default -o yaml

如果 machine 列表里看不到 Windows 节点对应的那条记录,说明机器对象压根没创建成功,这是第一类根因;如果 machine 有记录但状态里有报错信息(比如no VM found),这是第二类根因;如果 machine 记录正常但集群里的 node 对象一直没出现,则是 kubelet 注册流程的问题,属于第三类根因。

2.2 抓 Rancher 的 controller 日志

Rancher 的 node controller 负责同步 machine 和 node 的状态,它的日志信息量最大。如果 Rancher 是单容器部署,可以这样看:

docker logs <rancher-server-container> --since 1h | grep -i "node-ref\|waiting\|no vm found\|machine" | tail -100

如果是 Rancher 高可用部署在另一个集群里,就用下面的方式找。这里是嵌套集群,得先确认 Rancher 的 pod 名字,再进去抓日志:

kubectl get pods -n cattle-system | grep rancher kubectl logs -n cattle-system <rancher-pod> --since=1h | grep -iE "machine|cattle-node|noderef|nofinitee|no vm found" | tail -300

注意看日志里有没有这类关键词:

  • Failed to find VM
  • Waiting for node Ref
  • failed to create node ref
  • machine ... not found

如果日志里出现 “VM not found”,基本可以确定是基础设施层的问题,往下跳到第四章的场景一去处理。

2.3 检查 Windows 节点上的 kubelet 和容器运行时

如果 Rancher 侧日志看不出明显错误,就得登录到 Windows worker 节点上,看 kubelet 有没有正常启动。

在 Windows 上,Rancher 使用 RKE2 或 RKE1 的 Windows 形态(rancher-agent + containerd/docker)来拉起集群组件。检查服务状态:

Get-Service kubelet Get-Service rancher-agent Get-Process -Name kubelet -ErrorAction SilentlyContinue

如果 kubelet 服务存在但没有运行,先看 Windows 事件日志:

Get-WinEvent -LogName Application -MaxEvents 100 | Where-Object { $_.Message -match "kubelet|containerd|runtime" } | Format-List

再看 rancher-agent 的容器日志。如果用的是 containerd,可以执行:

crictl ps -a crictl logs <agent-container-id>

如果用的是 Docker EE/CE,则用:

docker ps -a docker logs <agent-container-id>

这里特别提醒:Windows 节点上 rancher-agent 容器通常需要和 kubelet 共用同一个容器运行时,而且启动顺序有讲究——先启动 container runtime,再启动 kubelet,然后 rancher-agent 才能正常和 Rancher server 通信。你要是看到 kubelet 进程反复崩溃重启,多半是 runtime 没起好,或者没有以正确的参数调用。

3. 核心原因与修复方案:分场景处理

场景一:节点驱动创建,VM 不存在或漂移(报 no VM found)

这个场景多见于 vSphere 等虚拟化环境。Rancher 通过 vSphere 驱动创建 Windows worker 后,虚拟机在 vCenter 里被改名了、被误删了,或者从某个 Cluster 迁移到了别的 Cluster,导致 Rancher 按照dataCentervmNamevmMoRef这些信息去查时返回空。

第一步,登录 vSphere 客户端确认 VM 是否真实存在。不要只看名字,要看路径。Rancher 在创建 VM 时记录的是folderresourcePool路径,你改过名字或者移动过 VM,这些信息就会对不上。

第二步,如果 VM 还在但路径变了,最简单的办法是在 Rancher 里把这条 machine 记录删掉,然后在 vSphere 里把 VM 名改回原名(或者让它重新符合 Rancher 的命名规则),再通过节点驱动重新添加。听起来有点暴力,但这是最干净的方案。

第三步,如果你希望保留这台 VM,不想重建,也可以在 vCenter 里把 VM 改回和 Rancher machine 记录一致的名称和路径,然后手动触发一次 Rancher 的 machine 同步:

kubectl annotate machine <machine-name> -n fleet-default "provisioning.cattle.io/reconcile=true"

注意这种方式能不能恢复取决于报错阶段:如果只是查询 VM 失败,这样能拉回来;如果 Rancher 已经把 machine 置为 failed,annotate 不一定有效,还是要删除重建。

场景二:自定义命令注册的 Windows worker,卡在注册流程中断

很多 Windows 节点是用“编辑集群 → 节点 → Windows”里给出的注册命令添加的。复制命令后,在 Windows Server 上以管理员身份运行 PowerShell 执行。如果中间网络断过、agent 容器启动失败,或者执行命令时没有以管理员运行,就容易卡在 Waiting for Node Ref。

先确认 rancher-agent Windows 容器是否拉取成功,这一步极其重要。Windows 节点拉取 rancher-agent 镜像体积挺大(通常几个 G),网络不好可能一直失败。上面已经给了查看容器日志的命令。如果发现 agent 容器日志里报连不上 Rancher server 的地址,先检查防火墙是否放行了 443 端口,以及 Rancher server 的 URL 是否用的是内网可达地址。

确认网络没问题后,重新执行注册命令。执行前先清理可能残留的 agent 容器:

crictl rm -f <agent-container-id>

如果是 docker runtime:

docker rm -f <agent-container-id>

然后重新用 PowerShell 执行注册脚本。这里有个细节:注册命令里包含了 Windows 特定的参数,比如--windows--worker等;如果复制时遗漏了这些参数,agent 可能按 Linux 逻辑走,导致组件不匹配,节点自然注册不上。所以重新执行前,最好逐项核对命令参数。

场景三:Rancher 数据不一致,machine 记录残留

这种场景没有明显的 infra 层错误,但节点就是一直 Waiting。多发生在离线环境、多重启 Rancher、或者 Rancher 版本升级过程中。Rancher 数据库里的 cluster-machine 关联记录可能损坏或不同步。

处理思路是:把 Rancher 侧预期要绑定这台节点的 machine 对象删掉,让 Rancher 重建,同时保留 Windows 节点上的 kubelet 和 agent 继续运行。

在 Rancher 所在的本地集群执行:

kubectl get machines -n fleet-default | grep <windows-node-hostname> kubectl delete machine <machine-name> -n fleet-default --wait=false

删除后观察 Rancher 是否自动重建 machine。如果自动重建了,通常几分钟内节点状态就会更新;如果没有重建,再到集群的 provisioning 文件里确认节点设置是否还保留着。

这类操作我实验过多次,在大多数场景下,删掉“期望状态”里的 machine 对象,而不用动集群里已经注册的 node 对象,可以让 Rancher 自动找回状态。但如果 node 对象本身也没有注册成功(比如 kubelet 一直没起来),那上面这步就做无用功,得先回到场景二把 kubelet 拉起。

4. 补充:Windows 节点加入 Rancher 的常规流程与常见误区

4.1 正确流程回顾

完整跑通一个 Windows worker 节点加入 Rancher 集群,差不多是这样的:

  1. 在 Rancher UI 编辑集群,在节点角色里勾选 Windows 的 Worker 角色,拿到一串注册命令(PowerShell 格式)。
  2. 在 Windows Server 2019 或 2022 上,以管理员身份打开 PowerShell,执行那串命令。命令内部会完成 containerd/docker 环境准备、镜像拉取、rancher-agent 启动。
  3. rancher-agent 起来以后,会向 Rancher server 注册 machine 信息,并拉起 kubelet。
  4. kubelet 向集群 kube-apiserver 注册 node 对象成功后,Rancher 的节点控制器完成绑定,节点状态从 Waiting 变为 Ready。

很多问题出在第 2 步和第 3 步衔接的地方:agent 容器起来了,但 kubelet 没起来;或者 kubelet 起来了,但 agent 一直报错。这俩进程之间并没有强依赖,但如果你想彻底重启,就得把它们按顺序都清理掉再重来一遍。

4.2 Windows 节点常见坑位清单

这里列几个我见过的实操问题,不一定每个都会导致 “no VM found”,但都会让人在排查时走弯路:

  • 没加 Windows 专属污点/标签。Rancher 给 Windows worker 会默认打上node.kubernetes.io/os=windows:NoSchedule这类污点。如果注册命令里漏了参数,或者手动编辑集群时把污点删了,Linux 平台的 Pod 不要被调度到 Windows,Windows POD 又要选择指定运行时,互相挤兑之后节点状态就会很奇怪。
  • 主机名大小写。Windows 主机名经常是大写或者带数字后缀,kubelet 注册时会把主机名转成小写。Rancher 在期望状态(machine)里写的是你提供的名字,可能和实际注册名字大小写不一致,导致 Node Ref 一直对不上。遇到这种情况,要么在注册命令里显式指定CATTLE_NODE_NAME为小写,要么修改 Windows 主机名后重启再注册。
  • 内存和 CPU 不满足最低要求。Windows 节点对资源的要求比 Linux 高不少,如果 VM 只有 2G 内存、1 核 CPU,kubelet 很容易启动失败或反复重启。Rancher UI 上表现就是节点一直 Waiting,日志里却是一堆 OOM 或资源不足的信息。
  • 容器 runtime 版本不匹配。RKE2 要求 containerd 版本和 kubelet 配套。如果你自己手动装过 docker/containerd,再跑 Rancher 注册命令,很容易因版本冲突导致 ranche-agent 启动失败。

4.3 用注册命令时推荐加的两个参数

在 PowerShell 执行注册命令时,如果你希望节点名更可控,可以加:

$env:CATTLE_NODE_NAME = "win-worker-01"

然后再执行原本的注册命令。这样可以避免因 Windows 主机名默认值引发的匹配问题。

如果节点所在网络到 Rancher server 公网地址不通,但内网可达,你可以在命令前加环境变量指定内网地址:

$env:CATTLE_SERVER = "https://rancher.internal:443"

这么做的前提是 Rancher server 的证书里包含这个内网地址,否则 agent 会因证书校验失败而退出。

5. 常见问题速查表:按症状直接查方案

表面现象可能根因优先处理动作
节点卡在 Waiting for Node Ref,无具体报错node 对象和 machine 对象未关联,kubelet 可能没起来先看 kubelet 日志,确认进程是否存活;再查 Rancher machine 对象状态
日志出现no VM foundvSphere/云驱动里 VM 已不存在或路径漂移进 vCenter/云控制台确认 VM,改名/移动路径后 annotate 同步或删除重建
注册命令执行后,agent 容器一段时间后被自动退出Windows 容器镜像拉取失败,或 CATTLE_SERVER 指向地址不可达检查crictl logsdocker logs,确认网络与镜像仓库连通性
节点状态显示 Waiting,但控制台里 node 列表已能看到该节点Rancher 的 machine 对象建立失败,或 CRD 数据不一致删除对应 machine 对象,观察是否自动重建
kubelet 进程反复重启runtime 版本不对,或资源不足检查 containerd/docker 版本,和 Rancher 文档对齐;提高 VM 规格
加完节点后 Kubernetes 无法调度 Windows Pod节点缺少os=windows污点或 label检查节点标签和污点,重新执行注册命令并确认参数完整

这个表是我自己后期复盘时整理的,不一定覆盖所有异常,但能覆盖我遇到过的 90% 的卡顿场景。排查顺序永远是:先看基础网络中不通,再看 agent 容器日志,再看 kubelet,最后动 Rancher 里的 CRD。

6. 几个必须强调的实操注意事项

6.1 不要随便在 Rancher 里点“删除节点”

只要节点卡在 Waiting for Node Ref,很多人就想把它从节点列表里删掉再重新添加。但如果你删的是 Rancher 里这个被管理的机器记录,同时没有先去 Windows 节点上停止 kubelet,集群里的 node 对象会变成孤儿节点,一直存留在集群中,即使机器已经不在 Rancher 管理列表里了。

这会导致后续想重新添加节点时,新 kubelet 注册的 node 名字和一个旧 node 记录冲突,状态持续 NotReady。所以如果你决定走“删除重建”路线,请先登录 Windows 节点,停止并禁用相关服务:

Stop-Service kubelet -Force Stop-Service rancher-agent -Force Set-Service kubelet -StartupType Disabled Set-Service rancher-agent -StartupType Disabled

然后再到 Rancher UI 里删除节点。这样清理得干净,重建时才不会残留 “Node Ref” 匹配问题。

6.2 使用 kubeconfig 直接看集群内 node 对象

Rancher UI 显示的是管理平面状态,容易掩盖真实问题。我建议你随时准备一个能访问目标集群的 kubeconfig。在本地执行:

kubectl get nodes -o wide

如果kubectl get nodes里能看到 Windows 节点,但状态是 NotReady,那问题在 kubelet 或容器运行时;如果节点列表里压根看不到 Windows 节点,那问题在注册流程,和 Rancher 的 machine 对象无关。这两类问题的处理方向完全不同,这个判断可以帮你省掉大量的无效排查时间。

6.3 Rancher 版本差异导致的显示不一致

Rancher 2.6 和 2.7 之间的节点管理逻辑差别不算大,但 2.8 之后对 Windows 的支持做了一些调整。老版本里Waiting for Node Ref相对少见,新版本则更严格,machine 必须拿到“节点驱动提供的VM信息”才能完成绑定。

如果你正在用不支持的 Windows 版本(比如 Windows Server 2016 或 Windows 11 客户端),Rancher agent 本身可能就有兼容性问题,建议直接换成 Windows Server 2022 的 LTSC 版本再试。这个听起来像是废话,但确实是我见过最多的隐性误配场景之一。

7. 最后分享一点个人体会,关于 Windows 节点排障的顺序

Windows 节点不像 Linux 节点那样好折腾,很多常规命令没有、输出格式也不一样,在 Rancher 排错时尤其容易一头雾水。踩过几次坑之后,我的经验是:先抓日志,再动资源;先看最近的变更,再盲修配置。

遇到卡在 Waiting for Node Ref 且带 “no VM found” 的节点,我的第一判断往往是基础设施层出了问题——不是 Rancher 不干活,而是它查不到这台机器了。这时候与其在 Rancher 页面里反复点击重试,不如直接去 vCenter / 云控制台看一眼这台 Windows worker 的虚拟机还在不在。

如果 VM 一切正常,再回到 Rancher 这边看 machine 状态。如果 machine 状态也是好的,那就要怀疑是不是注册命令的问题。这个时候去 Windows 节点上把 rancher-agent 容器日志拉出来看,通常能直接看到它尝试连接 Rancher server 的过程,以及失败的具体原因。

另外,Windows 节点重新注册时,尽量把 kubelet 和 agent 的服务全部停掉、清理容器,再执行注册命令。Rancher 的注册脚本要做的是“从零拉一个新的 worker”,你不能骗它说已经有一个 worker 在跑了,否则后续资源组(比如 Calico/Tigera Operator 的 Windows 版本)配置很可能会错乱。

如果你只是临时想恢复集群调度能力,又不想马上修节点,可以先把 Windows 节点的调度禁用掉,把工作负载调度到 Linux 节点上。但记得,这只适合临时保可用性,根本不是修复手段,一定要回来处理节点本身。

这个 “no VM found” 的报错看起来很唬人,很多时候就是因为虚拟化层数据漂移或者创建节点时的信息不对称。你只要按照“基础设施 → 容器运行时 → kubelet → Rancher 机器数据”的顺序逐层排查,大多数场景都能在半小时内定位到根因。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询