在 Kubernetes 生态中,让 Windows 节点通过 kubeadm 完成初始化并加入集群,是一套与 Linux 节点差异明显的流程。很多团队在搭建混合集群时,习惯性地把 Linux 上的 kubeadm init 和 join 命令直接搬到 Windows Server 上,结果节点状态永远卡在 NotReady,甚至 kubelet 根本无法启动。根本原因在于 Windows 的内核网络栈、容器运行时以及服务管理机制与 Linux 完全不同,kubeadm 并没有为 Windows 提供一套开箱即用的 init 子命令,而是要求我们在 Linux 控制面做好前置配置后,于 Windows 侧以手动 join 的方式完成“初始化”。

Linux 控制面的前置准备
要让 Windows 节点被 kubeadm 顺利接纳,第一步并不是在 Windows 上操作,而是调整 Linux 控制面节点。Kubernetes 从 1.14 之后引入了对 Windows 节点的官方支持,但要求控制面开启 IPVS 代理模式,并正确配置网桥的 IPv4 转发。如果集群原本使用 iptables 模式,Windows 节点上的 Pod 将无法与控制面 Service 通信。我们需要修改 kube-proxy 的 ConfigMap,将 mode 字段设为 ipvs,同时确认节点上加载了 br_netfilter 模块。
另一个容易被忽视的点是网络插件的选型。Linux 侧常用的 Flannel 默认只处理 Linux 的 VXLAN,而 Windows 需要 Flannel 的 host-gw 或 VXLAN 针对 Windows 的适配版本,也就是通常所说的 Flannel for Windows。在初始化控制面时,应提前部署支持 Windows 的 YAML,例如使用社区维护的 flannel.yml,其中包含了针对 nodeSelector 的调度规则,确保 Windows 专用守护进程只落在 Windows 节点。若跳过这步,后续 Windows 节点加入后网络插件无法启动,节点直接被标记为 NoSchedule。
此外,控制面初始化时生成的令牌和发现 CA 哈希必须妥善保存。由于 Windows 不支持 kubeadm init phase 的大部分阶段,我们无法在 Windows 上重新生成集群证书,只能复用 Linux 控制面已有的加入凭证。建议在执行 kubeadm init 后立即使用 kubeadm token create --print-join-command 拿到完整命令,并记下 --discovery-token-ca-cert-hash 的值,这是 Windows 节点执行 join 时校验控制面身份的唯一依据。
Windows 主机的运行时与二进制部署
在 Windows Server 2019 或 2022 上,首要任务是安装兼容的容器运行时。目前官方推荐的是 Docker EE 或 containerd 的 Windows 版本,其中 Docker EE 需要开启 Linux 容器可选功能之外的 Windows 容器功能。安装完成后,必须将运行时配置为使用 nat 或 transparent 网络驱动,否则 kubelet 启动时会报网络接口不匹配。与 Linux 不同,Windows 没有 systemd,因此 kubelet 通常以 Windows 服务形式注册,或者通过 PowerShell 脚本直接前台运行以便排错。
接下来是获取 Kubernetes 二进制文件。我们需要从官方仓库下载与控制面版本完全一致的 kubeadm.exe、kubelet.exe、kubectl.exe,注意架构必须是 amd64。将这些文件放到 C:k 目录,并配置环境变量 PATH 以便全局调用。与 Linux 上包管理器自动放置不同,Windows 的 kubeadm 不会自己写服务项,必须借助 sc.exe 或 nssm 把 kubelet 注册为服务,否则重启后节点掉线。下面是一段典型的注册 kubelet 为服务的 PowerShell 片段:
$binPath = "C:kkubelet.exe --hostname-override=$env:computername --kubeconfig=C:kconfig --pod-infra-container-image=mcr.microsoft.com/oss/kubernetes/pause:3.6" New-Service -name kubelet -binaryPathName $binPath -DisplayName kubelet -StartupType Automatic Start-Service kubelet
这段脚本把 kubelet 指向了本地配置文件,并指定了 Windows 专用的 pause 镜像。值得注意的是,Windows 的 pause 镜像与 Linux 完全不同,若错误引用了控制面默认的 pause 镜像,kubelet 会反复拉取失败。同时,kubeadm 在 Windows 上仅用于执行 join 阶段,它读取的是我们通过 --kubeconfig 传入的凭据,而不是像 Linux 那样自动从 /etc/kubernetes 读取。
执行 kubeadm join 与排错要点
当控制面与 Windows 运行时都就绪后,即可在 Windows 节点以管理员权限执行 join。命令格式与 Linux 类似,但必须附加 --node-name 明确指定主机名,并确认令牌未过期。典型命令如下:
kubeadm.exe join 192.168.0.10:6443 --token abcdef.0123456789abcdef ` --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxx ` --node-name win-node-01
加入过程会调用 kubelet 向 API Server 注册节点,并拉取 kube-proxy 与网络插件的 Windows 版本 Pod。如果此处报出 unable to recognize network plugin,通常是因为 kubelet 的 --network-plugin 参数未设为 cni,或者 C:kcni 目录下缺少配置文件。Windows 的 CNI 路径与 Linux 的 /etc/cni 不同,需要手动从 Flannel 发行包中拷贝 flanneld.exe 和 host-local 等插件到指定目录。
节点成功加入后,使用 kubectl get nodes 应能看到操作系统列为 windows。但此时往往仍是 NotReady,原因在于 Windows 节点上的 kube-proxy 和 flannel Pod 可能处于 CrashLoopBackOff。排查时建议先描述 Pod 日志:kubectl describe pod -n kube-system -l k8s-app=kube-proxy-win。常见问题包括 Service 的 ClusterIP 段与 Windows 主机路由冲突,或防火墙阻断了 4789 的 VXLAN 端口。关闭 Windows 防火墙或添加入站规则后,节点通常在几分钟内转为 Ready,至此 kubeadm 初始化 Windows 节点的核心流程才算真正完成。
从架构视角看,Windows 节点经 kubeadm 接入后并不具备与 Linux 完全一致的能力,例如不支持特权容器、HostNetwork 模式受限。因此在生产混合集群中,应通过 taint 和 label 明确区分负载类型,把只兼容 Windows 的 IIS、.NET Framework 应用调度到这些节点,而把云原生 Linux 负载隔离在外。只有这样,kubeadm 初始化的 Windows 节点才能稳定承载业务而不引发调度混乱。
kubeadmWindows节点Kubernetes修改时间:2026-08-13 11:51:39