3. Kubernetes 滚动升级原理:Deployment 与 StatefulSet 的滚动更新策略
滚动升级(Rolling Update)是 Kubernetes 中实现无宕机应用更新的核心机制。它通过逐步替换旧版本 Pod 实例为新版本,确保在整个更新过程中服务始终可用。理解其底层原理、关键参数与 Pod 生命周期,是实现自动化回滚工程的基础。
3.1 滚动升级的核心目标与流程
滚动升级的核心目标是在不中断服务的前提下,将应用从当前版本(Revision N)平滑过渡到目标版本(Revision N+1)。其基本流程如下:
- 用户触发:修改 Deployment 或 StatefulSet 的 Pod 模板(如镜像版本),提交更新。
- 控制器检测:Kubernetes 控制器(Deployment Controller / StatefulSet Controller)检测到期望状态与当前状态不一致。
- 创建新 ReplicaSet / 新 Pod:控制器根据更新策略,开始创建新版本的 Pod。
- 逐步替换:按照
maxSurge和maxUnavailable参数的约束,逐步增加新 Pod 数量,同时缩减旧 Pod 数量。 - 健康检查与就绪检查:新 Pod 启动后,必须通过 Readiness Probe 才会被纳入 Service 的端点列表,开始接收流量。
- 完成更新:当所有旧 Pod 都被新 Pod 替换,且新 Pod 均处于 Ready 状态时,滚动升级完成。
关键区别: Deployment 和 StatefulSet 的滚动更新逻辑在 Pod 替换顺序、更新策略参数以及如何处理持久化状态上存在显著差异。StatefulSet 的滚动更新默认是顺序且有序的(从最大序号到最小序号),而 Deployment 则是并行的。
3.2 Deployment 滚动更新策略与参数
Deployment 的滚动更新策略通过 spec.strategy.rollingUpdate 字段配置,包含两个核心参数:maxSurge 和 maxUnavailable。这两个参数共同决定了滚动升级的速度和资源消耗。
| 参数 | 类型 | 默认值 | 含义 | 示例(replicas=10) |
|---|---|---|---|---|
| maxSurge | 整数或百分比 | 25% | 滚动升级过程中,允许超出期望副本数的最大 Pod 数量。 | 25% → 最多允许 2 个额外 Pod(10 * 25% = 2.5,向上取整为 3) |
| maxUnavailable | 整数或百分比 | 25% | 滚动升级过程中,允许处于不可用状态的最大 Pod 数量。 | 25% → 最多允许 2 个 Pod 不可用(10 * 25% = 2.5,向上取整为 3) |
参数协同逻辑: 在滚动升级的每个时间点,控制器会确保:
- 可用 Pod 数量 ≥ (期望副本数 - maxUnavailable)
- 总 Pod 数量 ≤ (期望副本数 + maxSurge)
3.2.1 参数配置示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 3 # 允许最多 3 个额外 Pod
maxUnavailable: 2 # 允许最多 2 个 Pod 不可用
template:
spec:
containers:
- name: app
image: my-app:v2
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
3.3 StatefulSet 滚动更新策略与参数
StatefulSet 的滚动更新策略与 Deployment 有本质区别。StatefulSet 默认采用 有序、顺序的滚动更新,即从 Pod 序号最大的实例开始更新,逐个替换,确保有状态应用的稳定性。
| 特性 | Deployment | StatefulSet |
|---|---|---|
| 更新顺序 | 并行,无顺序保证 | 有序,从最大序号到最小序号 |
| Pod 标识 | 随机名称,无持久标识 | 固定名称(如 pod-0, pod-1),有持久标识 |
| PVC 关联 | 无持久化存储关联 | 每个 Pod 绑定独立的 PVC |
| maxSurge | 支持 | 不支持(始终为 0) |
| maxUnavailable | 支持 | 支持(需配合 spec.updateStrategy.rollingUpdate.maxUnavailable) |
| 分区更新 | 不支持 | 支持(通过 partition 参数实现金丝雀发布) |
3.3.1 StatefulSet 分区更新(Partition)
StatefulSet 的 partition 参数允许将更新限制在序号大于等于该值的 Pod 上。这是实现金丝雀发布和灰度发布的关键机制。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-stateful-app
spec:
replicas: 5
serviceName: "my-service"
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 3 # 只更新序号 >= 3 的 Pod(即 pod-3, pod-4)
template:
spec:
containers:
- name: app
image: my-stateful-app:v2
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
重要提示: 当
partition 设置为 3 时,只有 pod-3 和 pod-4 会被更新到 v2 版本。pod-0、pod-1、pod-2 仍保持旧版本。将 partition 设置为 0 时,所有 Pod 才会被更新。
3.4 滚动升级中的 Pod 生命周期
在滚动升级过程中,每个 Pod 都会经历完整的生命周期阶段。理解这些阶段对于配置健康检查和实现自动化回滚至关重要。
| 阶段 | 状态 | 触发条件 | 对滚动升级的影响 |
|---|---|---|---|
| Pending | Pod 已被调度,但容器未启动 | 创建新 Pod 请求 | 如果长时间 Pending,可能阻塞后续更新 |
| Running (Not Ready) | 容器已启动,但未通过 Readiness Probe | 容器启动完成 | Pod 不会接收流量,不影响 Service 可用性 |
| Running (Ready) | 容器已启动,且通过 Readiness Probe | Readiness Probe 返回成功 | Pod 开始接收流量,滚动升级可以继续 |
| Terminating | Pod 正在被销毁 | 收到删除信号(SIGTERM) | 旧 Pod 从 Service 端点列表中移除,流量被切断 |
| Failed / CrashLoopBackOff | Pod 启动失败或持续崩溃 | Liveness Probe 失败或容器退出 | 滚动升级会暂停,等待用户干预或触发回滚 |
3.4.1 滚动升级暂停条件
Kubernetes 控制器在以下情况下会暂停滚动升级:
- 新 Pod 无法通过 Readiness Probe:新 Pod 启动后,如果在
progressDeadlineSeconds(默认 600 秒)内未变为 Ready,升级被视为失败。 - 新 Pod 进入 CrashLoopBackOff:容器持续崩溃,无法稳定运行。
- 旧 Pod 无法正常终止:旧 Pod 在
terminationGracePeriodSeconds(默认 30 秒)内未完成优雅关闭。
自动化回滚的触发点: 当滚动升级被暂停或失败时,Prometheus 监控系统可以通过检测
kube_deployment_status_condition{condition="Progressing", status="False"} 或 kube_deployment_status_observed_generation 与 metadata.generation 不匹配等指标,自动触发回滚操作。
3.5 滚动升级流程总结
以下表格总结了 Deployment 和 StatefulSet 在滚动升级中的关键差异,帮助你在实际工程中选择合适的策略:
| 对比维度 | Deployment | StatefulSet |
|---|---|---|
| 适用场景 | 无状态应用 | 有状态应用(数据库、消息队列等) |
| 更新顺序 | 并行,无顺序 | 有序,从最大序号到最小序号 |
| maxSurge | 支持(默认 25%) | 不支持(始终为 0) |
| maxUnavailable | 支持(默认 25%) | 支持(默认 1) |
| 分区更新 | 不支持 | 支持(通过 partition 参数) |
| 回滚方式 | kubectl rollout undo 或修改镜像版本 |
修改镜像版本或调整 partition 参数 |
| 监控指标 | kube_deployment_status_condition |
kube_statefulset_status_current_revision |
理解这些原理后,你就能在 Prometheus 监控驱动的自动化回滚工程中,精准地判断何时触发回滚、如何配置滚动升级参数以平衡速度与安全性,以及如何利用 Pod 生命周期状态作为回滚决策的依据。