2. Kubernetes 集群升级基础:版本策略、控制面与节点升级顺序、kubeadm与托管集群差异

2.1 版本策略与升级路径

Kubernetes 社区采用 X.Y.Z 语义化版本号(主版本.次版本.补丁版本)。集群升级的核心约束是 版本偏移(Version Skew)策略,它决定了控制面与节点之间、以及各组件之间允许的版本差异。

组件 允许版本差 说明
kube-apiserver → kube-controller-manager / kube-scheduler ≤ 1 个次版本 调度器和控制器管理器版本不能高于 API Server
kube-apiserver → kubelet / kube-proxy ≤ 2 个次版本 节点组件可以比控制面低最多两个次版本
kubelet → kube-apiserver ≤ 2 个次版本 kubelet 版本不能高于 API Server,且不能低于 2 个次版本
kubectl → kube-apiserver +1 / -1 个次版本 客户端版本可以比 API Server 高或低一个次版本
运维要点: 升级路径必须逐次版本进行,禁止跨次版本升级(例如 1.24 → 1.26)。补丁版本(Z)可以跨版本升级,但建议按顺序应用以避免依赖问题。

2.2 控制面与节点升级顺序

集群升级必须遵循 先控制面、后节点 的严格顺序。控制面升级期间,现有工作负载继续运行,但集群管理操作(如创建/删除 Pod)可能暂时不可用。

集群升级顺序流程图 ① 升级控制面组件 kube-apiserver → kube-controller-manager → kube-scheduler ② 升级 etcd(可选) ③ 升级节点 逐台 drain → 升级 → uncordon 节点升级详细步骤 1. 标记节点不可调度:kubectl cordon <node> 2. 驱逐 Pod:kubectl drain <node> --ignore-daemonsets --delete-emptydir-data 3. 升级 kubelet 和 kube-proxy(kubeadm upgrade node 或包管理器) 4. 恢复调度:kubectl uncordon <node> 5. 验证节点状态:kubectl get nodes 确认 Ready 且版本正确
关键风险: 控制面升级后,如果节点版本低于控制面超过 2 个次版本,kubelet 将无法注册到集群。务必在升级前使用 kubectl get nodes -o wide 确认所有节点的 kubelet 版本。

2.3 kubeadm 与托管集群差异

kubeadm 自建集群与云托管集群(如 AKS、EKS、GKE)在升级流程、控制面可管理性、节点升级策略上存在本质差异。下表对比了核心区别:

维度 kubeadm 自建集群 托管集群(AKS/EKS/GKE)
控制面升级 手动执行 kubeadm upgrade apply,需逐台升级主节点 云厂商自动升级控制面,用户只需选择目标版本
etcd 升级 需手动备份并升级,kubeadm 1.22+ 支持自动迁移 由云厂商管理,用户无感知
节点升级 逐台 drain → 升级 kubelet → uncordon,完全手动 节点池升级:AKS 支持 surge 升级,EKS 支持滚动更新
回滚能力 需从 etcd 快照恢复,流程复杂 控制面可快速回滚到上一版本(部分厂商支持)
API Server 停机时间 多主节点 HA 部署时无停机,单主节点有短暂中断 零停机,云厂商通过负载均衡器实现平滑切换
升级前检查 kubeadm upgrade plan 手动执行 云厂商自动执行预检查,失败时阻止升级

2.4 kubeadm 升级实战流程

以下是一个典型的 kubeadm 集群从 1.27.x 升级到 1.28.y 的完整命令序列:

# 1. 升级控制面(主节点)
kubeadm upgrade plan v1.28.y
kubeadm upgrade apply v1.28.y

# 2. 升级 kubelet 和 kubectl(主节点)
apt-mark unhold kubelet kubectl
apt-get update && apt-get install -y kubelet=1.28.y-00 kubectl=1.28.y-00
apt-mark hold kubelet kubectl
systemctl daemon-reload && systemctl restart kubelet

# 3. 升级工作节点
kubectl cordon <node-name>
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

# 在节点上执行
kubeadm upgrade node
apt-mark unhold kubelet kubectl
apt-get update && apt-get install -y kubelet=1.28.y-00 kubectl=1.28.y-00
apt-mark hold kubelet kubectl
systemctl daemon-reload && systemctl restart kubelet

# 恢复调度
kubectl uncordon <node-name>
托管集群升级示例(AKS):
az aks upgrade --resource-group myRG --name myCluster --kubernetes-version 1.28.y
该命令自动升级控制面,然后通过 --node-image-only 或节点池升级策略逐个升级节点。

2.5 升级前巡检清单

  • 版本兼容性检查: 确认目标版本与当前集群的 API 资源兼容性,使用 kubectl convert 检查废弃 API。
  • etcd 备份: 使用 etcdctl snapshot save 创建快照,并验证快照完整性。
  • 节点健康检查: 确认所有节点 Ready,kubelet 版本在允许范围内。
  • Pod 分布检查: 确保工作负载有足够的副本和 PDB(PodDisruptionBudget)以容忍节点 drain。
  • 存储和网络插件: 确认 CNI 和 CSI 插件版本与目标 Kubernetes 版本兼容。
  • 监控和告警: 升级期间临时调整告警阈值,避免因节点 drain 触发误报。
kubeadm vs 托管集群升级流程对比 kubeadm 自建集群 手动执行 kubeadm upgrade plan 逐台 drain → 升级 → uncordon etcd 手动备份与恢复 运维复杂度高,需逐节点操作 托管集群(AKS/EKS/GKE) 一条命令升级控制面 节点池自动滚动升级 etcd 由云厂商管理 控制面不可自定义,依赖厂商策略
选型建议: 生产环境优先考虑托管集群以降低升级运维成本。如果必须使用 kubeadm,建议部署至少 3 个控制面节点实现 HA,并建立完整的升级 SOP 和回滚预案。