深色模式
kubeadm 集群滚动升级
摘要:kubeadm 集群升级必须严格按小版本递进:先升级第一个控制面节点,再其余控制面,最后滚动升级 worker。本文给出完整命令序列、升级前检查清单、常见失败处理与回退方案。
适用环境
- kubeadm 搭建的自管集群(不适用于云托管集群)
- 控制面奇数个(1/3/5)
- 已备份 etcd(见 etcd 备份相关章节)
- 具备所有节点的 root 权限
操作步骤
一、升级前必做检查
bash
kubectl get nodes -o wide
kubectl version
kubectl get pod -A | grep -v Running # 确认当前无异常
# 备份 etcd(控制面节点上执行)
sudo ETCDCTL_API=3 etcdctl snapshot save /data/etcd-before-upgrade.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
危险
kubeadm 不支持跨小版本升级(如 1.27 直接跳 1.30)。必须 1.27 → 1.28 → 1.29 → 1.30 逐个来。跨版本升级会直接报错或留下不一致状态。
二、第一个控制面节点升级
bash
# 1. 查看可升级版本
sudo kubeadm upgrade plan
# 2. 升级 kubeadm 工具本身(以 Debian 系为例)
sudo apt-mark unhold kubeadm
sudo apt-get update && sudo apt-get install -y kubeadm=1.29.x-*
sudo apt-mark hold kubeadm
kubeadm version
# 3. 执行控制面升级
sudo kubeadm upgrade apply v1.29.x1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
upgrade apply 会:拉新镜像 → 更新静态 Pod 清单 → 等待组件健康 → 更新集群内 kubeadm 配置。
三、升级 kubelet 与 kubectl
bash
kubectl drain <该控制面节点> --ignore-daemonsets
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet=1.29.x-* kubectl=1.29.x-*
sudo apt-mark hold kubelet kubectl
sudo systemctl daemon-reload
sudo systemctl restart kubelet
kubectl uncordon <该控制面节点>1
2
3
4
5
6
7
2
3
4
5
6
7
四、其余控制面节点
bash
sudo kubeadm upgrade node # 注意:不是 upgrade apply
# 然后同样升级 kubelet/kubectl 并 drain/uncordon1
2
2
建议
upgrade apply 只在第一个控制面节点执行一次(它负责更新集群级配置),其余控制面节点用 upgrade node。执行反了会导致配置冲突。
五、worker 节点滚动升级
对每个 worker 重复:
bash
# 在控制面执行
kubectl cordon <worker节点>
kubectl drain <worker节点> --ignore-daemonsets --delete-emptydir-data
# 在 worker 节点执行
sudo apt-mark unhold kubeadm kubelet kubectl
sudo apt-get install -y kubeadm=1.29.x-* kubelet=1.29.x-* kubectl=1.29.x-*
sudo apt-mark hold kubeadm kubelet kubectl
sudo kubeadm upgrade node
sudo systemctl daemon-reload && sudo systemctl restart kubelet
# 回到控制面
kubectl uncordon <worker节点>1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
一次只处理一个 worker,确认其 Pod 全部 Running 后再做下一个。
六、升级后验证
bash
kubectl get nodes # 全部为新版本且 Ready
kubectl get pod -A
kubectl -n kube-system get pod
sudo kubeadm upgrade plan # 应提示已是最新1
2
3
4
2
3
4
七、升级失败的回退
kubeadm 不提供一键回退,正确做法是用备份的 etcd 快照恢复:
bash
sudo kubeadm reset
sudo ETCDCTL_API=3 etcdctl snapshot restore /data/etcd-before-upgrade.db ...1
2
2
危险
etcd 快照恢复是全集群回滚,会丢失升级后产生的所有变更(新建的 Pod、ConfigMap 等)。这是最后手段,不要指望它做日常回退。因此升级前一定要在低峰期并先备份。
八、常见失败处理
bash
# 镜像拉取失败 → 手动预拉
sudo kubeadm config images pull --kubernetes-version=v1.29.x
# coreDNS 卡住 → 检查其镜像版本是否匹配
kubectl -n kube-system get deploy coredns -o yaml | grep image
# 控制面组件起不来
sudo journalctl -u kubelet -f
kubectl -n kube-system describe pod kube-apiserver-<节点>1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
验证
- [ ]
kubectl get nodes全部显示目标版本且 Ready - [ ]
kubectl get pod -A全部 Running - [ ] 新建测试 Pod 能正常调度运行
- [ ]
kubeadm upgrade plan提示无需再升级
常见坑
- 跨版本升级:必须逐级,见上文危险提示。
- 忘了
apt-mark unhold:包被锁定导致安装不生效,升级后版本没变化。 - swap 未关闭:kubelet 启动失败,执行
sudo swapoff -a并注释/etc/fstab中的 swap 行。 - 升级后 CNI 插件异常:部分 CNI 与新版 K8s 有兼容矩阵要求,需同步升级 CNI。
- 弃用 API 未处理:升级后旧 API(如
extensions/v1beta1Ingress)失效,应提前用kubent类工具扫描。