4. Kubernetes 版本升级机制:控制平面与节点升级官方流程
Kubernetes 版本升级是集群生命周期管理中最关键的操作之一。官方推荐的升级路径遵循“先控制平面,后工作节点”的原则,且版本号只能逐级递增(例如从 1.27.x 升级到 1.28.x),不可跨大版本升级。本章详解基于 kubeadm 的升级流程,以及 kubectl drain、cordon 等核心命令在节点管理中的作用。
4.1 升级前的版本兼容性检查
在开始升级之前,必须确认目标版本与当前集群的兼容性。Kubernetes 社区维护的版本偏差策略(Version Skew Policy)规定了控制平面与节点之间的最大允许版本差。
| 组件 | 版本偏差规则 | 说明 |
|---|---|---|
| kube-apiserver | 最高版本 | 集群中所有组件的版本上限 |
| kube-controller-manager / kube-scheduler | ≤ apiserver 版本 | 可以比 apiserver 低一个次要版本 |
| kubelet | ≤ apiserver 版本,且 ≥ apiserver - 2 | 允许最多落后两个次要版本 |
| kube-proxy | 与 kubelet 相同 | 必须与节点上的 kubelet 版本一致 |
kubeadm upgrade plan 命令可以自动检查当前集群的版本状态,并列出所有可升级的目标版本及其兼容性信息。这是升级前必须执行的第一步。
4.2 控制平面升级流程(kubeadm upgrade)
控制平面升级是整个升级过程的核心,涉及 API Server、Controller Manager、Scheduler 以及 etcd 等关键组件。使用 kubeadm 工具可以自动化大部分操作。
4.2.1 升级主控制平面节点
以下是在第一个控制平面节点上执行升级的标准步骤:
- 检查可升级版本:
kubeadm upgrade plan - 升级 kubeadm 本身: 使用包管理器(apt/yum)将 kubeadm 升级到目标版本。
- 执行控制平面升级:
kubeadm upgrade apply v1.28.x - 升级 kubelet 和 kubectl: 使用包管理器升级这两个组件,然后重启 kubelet 服务。
- 验证节点状态:
kubectl get nodes确认节点版本已更新。
# 步骤 1:查看升级计划
kubeadm upgrade plan
# 步骤 2:升级 kubeadm(以 Ubuntu/Debian 为例)
apt-get update && apt-get install -y kubeadm=1.28.x-00
# 步骤 3:应用升级
kubeadm upgrade apply v1.28.x
# 步骤 4:升级 kubelet 和 kubectl
apt-get install -y kubelet=1.28.x-00 kubectl=1.28.x-00
systemctl restart kubelet
# 步骤 5:验证
kubectl get nodes
4.2.2 升级其余控制平面节点
对于高可用集群中的其他控制平面节点,使用 kubeadm upgrade node 命令:
# 在其余控制平面节点上执行
kubeadm upgrade node
该命令会自动检测节点角色并执行相应的升级操作,无需再次指定版本号。
4.3 节点管理命令:cordon 与 drain
在升级工作节点之前,必须将节点上的 Pod 迁移到其他节点,以避免服务中断。Kubernetes 提供了两个关键命令来实现这一目标。
4.3.1 kubectl cordon
cordon 命令将节点标记为“不可调度”(SchedulingDisabled)。新创建的 Pod 不会被调度到该节点上,但节点上已有的 Pod 会继续运行。
# 标记节点为不可调度
kubectl cordon node-worker-1
# 验证节点状态
kubectl get nodes
# 输出示例:node-worker-1 Ready,SchedulingDisabled
4.3.2 kubectl drain
drain 命令在 cordon 的基础上,进一步驱逐节点上所有非 DaemonSet 的 Pod。它会先执行 cordon 操作,然后逐出 Pod,并等待 Pod 在新的节点上启动。
# 驱逐节点上的 Pod(忽略 DaemonSet)
kubectl drain node-worker-1 --ignore-daemonsets --delete-emptydir-data
# 常用参数说明:
# --ignore-daemonsets:忽略 DaemonSet 管理的 Pod(它们不会被驱逐)
# --delete-emptydir-data:允许删除使用 emptyDir 的 Pod(数据会丢失)
# --force:强制驱逐,即使 Pod 不属于 ReplicaSet/Deployment
cordon:只阻止新 Pod 调度,不驱逐已有 Pod。drain:阻止新 Pod 调度 + 驱逐已有 Pod(安全迁移)。
drain,否则节点上的 Pod 会在 kubelet 重启期间中断服务。
4.4 工作节点升级流程
完成控制平面升级后,可以开始升级工作节点。推荐使用滚动升级策略,逐个节点进行操作。
- 标记节点不可调度并驱逐 Pod:
kubectl drain node-worker-1 --ignore-daemonsets - 升级 kubeadm、kubelet、kubectl: 使用包管理器升级到目标版本。
- 执行节点升级:
kubeadm upgrade node - 重启 kubelet:
systemctl restart kubelet - 恢复节点调度:
kubectl uncordon node-worker-1 - 验证节点状态: 确认节点版本已更新且状态为 Ready。
# 在目标工作节点上执行
kubectl drain node-worker-1 --ignore-daemonsets --delete-emptydir-data
# 升级组件
apt-get install -y kubeadm=1.28.x-00 kubelet=1.28.x-00 kubectl=1.28.x-00
# 执行节点升级
kubeadm upgrade node
# 重启 kubelet
systemctl restart kubelet
# 恢复调度(在控制平面节点上执行)
kubectl uncordon node-worker-1
4.5 升级流程总览图
下图展示了从控制平面到工作节点的完整升级流程,以及各阶段使用的关键命令。
4.6 升级后的验证与回滚准备
升级完成后,必须执行一系列验证操作,确保集群功能正常。同时,应保留升级前的备份,以便在出现问题时快速回滚。
| 验证项 | 命令/方法 | 预期结果 |
|---|---|---|
| 节点版本 | kubectl get nodes |
所有节点版本显示为目标版本 |
| 核心组件状态 | kubectl get pods -n kube-system |
所有核心 Pod 处于 Running 状态 |
| API Server 健康 | kubectl cluster-info |
显示集群信息,无错误 |
| 工作负载运行 | kubectl get pods --all-namespaces |
业务 Pod 正常运行,无 CrashLoopBackOff |
| etcd 健康 | kubectl exec -n kube-system etcd-pod -- etcdctl endpoint health |
所有 etcd 端点健康 |
kubeadm upgrade apply 之前,建议备份 etcd 数据目录(通常位于 /var/lib/etcd)。如果升级失败,可以通过恢复 etcd 备份并重新安装旧版 kubeadm 来执行回滚。对于工作节点,回滚操作相对简单:只需重新安装旧版本的 kubelet 并重启服务即可。