kubeadm join 失败主因是前置条件未对齐:/etc/hosts 映射需完整一致;容器运行时版本必须与 master 完全相同;kubelet/kubeadm/kubectl 三者版本须严格匹配;selinux 必须 disabled、防火墙必须关闭。

kubeadm join 是添加 Worker 节点的核心命令,但直接执行它大概率失败——真正卡住你的不是命令本身,而是前置条件没对齐。
节点加入前必须检查的 4 个硬性条件
新机器不是“装完 kubeadm 就能 join”的。Master 和 Worker 必须在以下四点完全一致,否则 kubeadm join 会卡在 preflight 或证书校验阶段:
-
/etc/hosts中所有节点(包括新 Worker)的 IP 和主机名映射要完整且一致;缺一条就可能让 kubelet 连不上 API Server - 容器运行时版本(
containerd或docker)必须和 Master 完全相同;比如 Master 用的是containerd v1.7.20,新节点不能是v1.8.0 -
kubelet、kubeadm、kubectl三者版本号要严格匹配 Master 上的输出:kubeadm version、kubelet --version - 系统级配置:SELinux 必须为
disabled,防火墙(firewalld或ufw)必须关闭;哪怕只开一个端口(如 6443),也可能被 iptables 规则拦截
kubeadm join 命令怎么生成才不会过期
Master 上执行 kubeadm token create --print-join-command 输出的命令默认 24 小时失效。生产环境加节点不能赌时间——尤其你半夜收到扩容告警,又刚好 token 过期了。
更稳妥的做法是显式指定永不过期的 token:
kubeadm token create --ttl 0 --print-join-command
注意:--ttl 0 表示“永不过期”,但不等于“永久安全”。它只是跳过 token 生命周期检查,CA 证书哈希(--discovery-token-ca-cert-hash)仍需有效。如果 Master 的 CA 轮转过,这个 hash 就得重新算。
如果你不确定 CA 是否轮转,直接用这个命令重生成完整命令:
kubeadm init phase upload-certs --upload-certs && kubeadm token create --ttl 0 --print-join-command
Worker 节点执行 kubeadm join 后状态一直是 NotReady
这是最常被误判为“加节点失败”的现象。实际上,kubectl get nodes 显示 NotReady 并不意味着 join 失败,而只是网络没通——CNI 插件还没部署。
关键判断依据是:
- 执行
kubeadm join后,kubectl get nodes能看到新节点(哪怕状态是NotReady),说明 join 成功 - 执行
kubectl describe node <node-name></node-name>,看 Events 里有没有Network plugin is not ready类提示 - 检查
ls /etc/cni/net.d/是否为空;为空就是 CNI 没装
此时不要重复执行 join,而是回到 Master 部署 CNI(比如 Flannel):
kubectl apply -f https://github.com/flannel-io/flannel/releases/download/v0.24.2/kube-flannel.yml
等 30 秒左右,节点状态通常就会变成 Ready。注意:Flannel 镜像在国内可能拉不到,建议提前 docker load 导入离线包。
为什么 kubectl drain 和 kubectl delete node 不能反过来做
删节点时顺序反了,会导致大量 Pod 卡在 Terminating 状态,甚至残留“孤儿 Pod”——它们还在节点上跑着,但 Kubernetes 已经认为这台机器不存在了。
正确顺序只能是:
- 先
kubectl cordon <node></node>(禁止调度) - 再
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data</node>(驱逐 Pod) - 最后
kubectl delete node <node></node>(从 API 删除记录)
漏掉 cordon,drain 期间新 Pod 可能又被调度上来;漏掉 --ignore-daemonsets,drain 会卡住(因为 kube-proxy、flannel 这类 DaemonSet Pod 无法被驱逐);--delete-emptydir-data 不加,emptyDir 数据不会清,下次重用这台机器时可能引发冲突。
/etc/hosts 里多了一个空格,都足以让整个流程停在某个看似无关的环节。加节点不是一次性的操作,而是一套需要反复验证的环境对齐过程。











