K8s 一个季度一个版本,升级是个常态。本文按 kubeadm 跨 3 个版本的实战记录。

跨版本规则

K8s 官方只支持 N→N+1 升级。要跨多版本就要"逐级跳":

1.27 → 1.28 → 1.29 → 1.30

每跳一次必须等集群稳定(一天以上),不能连续跳。

单步升级流程

以 1.27 → 1.28 为例。

1. 升 control plane(第一个 master)

# 1. 升 kubeadm
dnf install -y kubeadm-1.28.0-0 --disableexcludes=kubernetes

# 2. 看升级计划
kubeadm upgrade plan

# 3. 真正升级
kubeadm upgrade apply v1.28.0

# 4. drain 节点
kubectl drain master1 --ignore-daemonsets

# 5. 升 kubelet/kubectl
dnf install -y kubelet-1.28.0-0 kubectl-1.28.0-0
systemctl daemon-reload
systemctl restart kubelet

# 6. uncordon
kubectl uncordon master1

2. 升其他 master

# 在 master2、master3 上
kubeadm upgrade node    # 注意是 node 不是 apply
# 然后同上升 kubelet

3. 升 worker

逐个节点:

# 控制面执行
kubectl drain worker1 --ignore-daemonsets --delete-emptydir-data

# 节点上执行
dnf install -y kubeadm-1.28.0-0 kubelet-1.28.0-0
kubeadm upgrade node
systemctl restart kubelet

# 控制面执行
kubectl uncordon worker1

必看 release notes 的坑

跨版本最容易翻车的点:

1.28 砍了

  • --feature-gates 里的 GA feature 不再接受(会报 invalid feature gate)
  • in-tree GCE/AWS/Azure/vSphere 存储插件全部移到 CSI

1.29 砍了

  • Secret 默认开启 SecretImmutability
  • KubeProxyConfiguration v1alpha1 弃用
  • Pod 安全准入策略对照 v1.29 检查

1.30 砍了

  • app.kubernetes.io/component 一些保留值变化
  • CRI v1alpha2 完全删除,runtime 必须支持 v1

CNI 兼容性

CNI 插件也要升:

  • Calico:跨版本 K8s 升级前先升 Calico 到对应版本
  • Cilium:同上
  • 自研 CNI:每次升前测一遍
# 查当前 CNI 版本
kubectl get daemonset -n kube-system -l k8s-app=calico-node -o jsonpath='{.items[0].spec.template.spec.containers[0].image}'

回滚

K8s 不支持降级!只能:
- 备份 etcd
- 失败就用 etcd 备份恢复,然后从快照重启

我的升级 checklist

  1. ☐ 备份 etcd(强制)
  2. ☐ 看 release notes(关键)
  3. ☐ staging 演练过(必须)
  4. ☐ kubelet 配置文件检查兼容性
  5. ☐ CRI runtime 版本检查
  6. ☐ 准备 PodDisruptionBudget(drain 才不会断业务)
  7. ☐ 一台一台升,每台升完观察 10 分钟

教训:跨版本升级出问题最常见的是 webhook(如 cert-manager、ingress-nginx)和 CNI 不兼容,新版本一定先升 webhook 再升 K8s。

标签: none

添加新评论