3. 滚动升级原理:策略、参数与流程拆解
滚动升级(Rolling Update)是 Kubernetes 节点池升级的默认策略,其核心思想是“逐步替换”:每次只升级少量节点,在保证整体集群负载能力不降级的前提下,完成全部节点的版本切换。理解 maxSurge 与 maxUnavailable 的配合关系,是排障的基础。
3.1 滚动升级策略对比
Kubernetes 支持三种升级策略,但节点池场景下最常用的是滚动升级。下表对比了三种策略的适用场景与风险:
| 策略类型 | 执行方式 | 集群容量影响 | 升级速度 | 典型场景 |
|---|---|---|---|---|
| 滚动升级(RollingUpdate) | 逐批替换旧节点,每批数量由参数控制 | 可控,可维持最小可用节点数 | 中等,可调 | 生产环境默认策略 |
| 重建升级(Recreate) | 先删除所有旧节点,再创建新节点 | 升级期间容量为零 | 最快(但中断最长) | 测试环境、可接受完全中断的场景 |
| 原地升级(In-Place) | 直接修改节点系统组件,不重建节点 | 无额外容量消耗 | 最快(无调度延迟) | 托管节点池(如 GKE、AKS) |
排障提示: 在自建集群中,滚动升级是排查“节点池版本卡住”问题的主要战场。maxSurge 和 maxUnavailable 配置错误,是导致升级进度阻塞的常见根因。
3.2 maxSurge 与 maxUnavailable 详解
这两个参数共同决定了滚动升级的“节奏”与“安全边界”。它们的单位可以是数量(整数)或百分比(基于节点池总节点数)。
| 参数 | 含义 | 默认值 | 典型配置 | 排障关注点 |
|---|---|---|---|---|
maxSurge |
升级过程中,允许超出期望节点数的最大额外节点数 | 25% | 1 或 10% |
过大可能导致资源争抢;过小会拖慢升级速度 |
maxUnavailable |
升级过程中,允许同时不可用的最大节点数 | 25% | 0 或 1 |
设为 0 可保证零中断,但升级速度最慢 |
关键公式: 滚动升级的“安全窗口” = maxSurge + maxUnavailable。例如,节点池有 10 个节点,maxSurge=1,maxUnavailable=1,则升级期间最多允许 12 个节点存在(10+1+1),但最多只能有 1 个节点不可用。
3.3 升级流程拆解(5 步循环)
滚动升级是一个循环迭代的过程,每次迭代处理一批节点。以下 SVG 图展示了单批节点的完整生命周期:
3.4 参数组合对升级行为的影响
不同的 maxSurge 与 maxUnavailable 组合,会产生截然不同的升级行为。以下表格总结了四种典型组合的效果:
| 组合场景 | maxSurge | maxUnavailable | 升级行为 | 适用场景 |
|---|---|---|---|---|
| 零中断保守型 | 0 | 1 | 每次只升级 1 个节点,先创建新节点,再驱逐旧节点,保证始终有 N 个节点可用 | 核心生产集群,不允许 Pod 中断 |
| 快速替换型 | 1 | 1 | 允许 1 个额外节点和 1 个不可用节点,升级速度较快 | 大多数生产环境默认推荐 |
| 激进加速型 | 25% | 25% | 允许大量节点同时替换,升级速度最快,但资源争抢风险高 | 非生产环境、紧急版本升级 |
| 资源受限型 | 0 | 0 | 不允许任何额外节点或不可用节点,升级无法启动(死锁) | ❌ 错误配置,需避免 |
死锁场景: 当 maxSurge=0 且 maxUnavailable=0 时,滚动升级无法启动任何批次,因为既不能创建新节点(maxSurge=0),也不能删除旧节点(maxUnavailable=0)。这是排障中常见的“升级进度 0%”根因之一。
3.5 升级流程中的状态机
从控制器视角看,滚动升级是一个有限状态机。以下 SVG 图展示了节点池在升级过程中的状态转换:
3.6 排障视角:升级流程中的常见阻塞点
基于上述流程拆解,以下是每个步骤对应的典型故障模式:
- 步骤① 标记不可调度失败: 节点处于
NotReady状态,kubelet 失联,cordon 操作无法执行。 - 步骤② 驱逐 Pod 失败: PodDisruptionBudget(PDB)设置过于严格,导致驱逐操作被阻塞;或 Pod 存在
local storage且未设置--delete-emptydir-data。 - 步骤③ 删除节点失败: 云商 API 限流、节点处于保护状态(如 AWS Termination Protection)、或自建集群中 etcd 记录残留。
- 步骤④ 创建节点失败: 云资源配额不足、镜像拉取失败、初始化脚本(UserData)报错。
- 步骤⑤ 等待就绪超时: kubelet 证书过期、CNI 插件未部署、节点组件版本不兼容。
实战建议: 在升级前执行
kubectl get pdb --all-namespaces 检查所有 PDB 配置,确保 maxUnavailable 或 minAvailable 不会阻止驱逐。这是排障“升级卡在 0%”的第一步。