3. Kubernetes 滚动升级原理:Deployment 与 StatefulSet 的滚动更新策略

滚动升级(Rolling Update)是 Kubernetes 中实现无宕机应用更新的核心机制。它通过逐步替换旧版本 Pod 实例为新版本,确保在整个更新过程中服务始终可用。理解其底层原理、关键参数与 Pod 生命周期,是实现自动化回滚工程的基础。

3.1 滚动升级的核心目标与流程

滚动升级的核心目标是在不中断服务的前提下,将应用从当前版本(Revision N)平滑过渡到目标版本(Revision N+1)。其基本流程如下:

  1. 用户触发:修改 Deployment 或 StatefulSet 的 Pod 模板(如镜像版本),提交更新。
  2. 控制器检测:Kubernetes 控制器(Deployment Controller / StatefulSet Controller)检测到期望状态与当前状态不一致。
  3. 创建新 ReplicaSet / 新 Pod:控制器根据更新策略,开始创建新版本的 Pod。
  4. 逐步替换:按照 maxSurge 和 maxUnavailable 参数的约束,逐步增加新 Pod 数量,同时缩减旧 Pod 数量。
  5. 健康检查与就绪检查:新 Pod 启动后,必须通过 Readiness Probe 才会被纳入 Service 的端点列表,开始接收流量。
  6. 完成更新:当所有旧 Pod 都被新 Pod 替换,且新 Pod 均处于 Ready 状态时,滚动升级完成。
关键区别: Deployment 和 StatefulSet 的滚动更新逻辑在 Pod 替换顺序、更新策略参数以及如何处理持久化状态上存在显著差异。StatefulSet 的滚动更新默认是顺序且有序的(从最大序号到最小序号),而 Deployment 则是并行的。
Deployment 滚动升级流程示意图 Deployment 滚动升级流程 用户触发更新 控制器检测差异 创建新 ReplicaSet 逐步替换 Pod 健康检查通过 完成滚动升级 说明:Deployment 的滚动升级是并行的,多个新 Pod 可以同时创建,多个旧 Pod 可以同时销毁。 替换节奏由 maxSurge 和 maxUnavailable 参数共同控制。

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)
例如,replicas=10, maxSurge=25%, maxUnavailable=25%,则升级过程中可用 Pod 至少为 7 个,总 Pod 最多为 13 个。

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 才会被更新。
StatefulSet 有序滚动更新示意图 StatefulSet 有序滚动更新(replicas=4, partition=2) 旧版本 Pod 组 pod-0 (v1) pod-1 (v1) 新版本 Pod 组 pod-2 (v2) pod-3 (v2) 更新规则: 1. 从最大序号 Pod 开始更新 2. 只有序号 >= partition 的 Pod 被更新 3. 前一个 Pod 就绪后,才更新下一个 4. 更新顺序:pod-3 → pod-2

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 生命周期状态作为回滚决策的依据。