Kubernetes 滚动升级原理:ReplicaSet、Deployment 与更新策略

滚动升级(Rolling Update)是 Kubernetes 中实现无宕机应用更新的核心机制。其底层依赖 ReplicaSet 与 Deployment 控制器的协同工作,并通过 maxSurge 和 maxUnavailable 两个参数精确控制更新速率与资源消耗。理解这三者的关系,是后续进行 Prometheus 监控与故障排查的基础。

2.1 核心组件:ReplicaSet 与 Deployment

Deployment 并不直接管理 Pod,而是通过管理 ReplicaSet 来间接控制 Pod 的副本数量与版本。每次更新都会创建一个新的 ReplicaSet,并逐步调整新旧 ReplicaSet 的副本数。

组件 职责 滚动升级中的角色
Pod 运行容器化应用的最小单元 被替换的对象,每次更新会创建新版本 Pod,销毁旧版本 Pod
ReplicaSet 确保指定数量的 Pod 副本始终运行 每个版本对应一个 ReplicaSet;滚动升级时,新旧两个 ReplicaSet 同时存在,副本数动态调整
Deployment 声明式更新控制器,管理 ReplicaSet 的创建、缩放与回滚 编排整个滚动升级流程,根据策略计算新旧 ReplicaSet 的目标副本数

关键理解: Deployment 是“策略层”,ReplicaSet 是“执行层”。滚动升级的本质是 Deployment 控制新旧 ReplicaSet 的副本数此消彼长,直到新 ReplicaSet 完全接管所有流量。

2.2 滚动更新策略:maxSurge 与 maxUnavailable

Deployment 的 strategy.rollingUpdate 字段包含两个核心参数,它们共同定义了滚动升级的“节奏”和“资源占用”。

参数 类型 默认值 含义 典型场景
maxSurge 整数或百分比 25% 滚动升级过程中,允许超出期望副本数的最大 Pod 数量 快速扩容场景:增大该值可加速更新,但会消耗更多集群资源
maxUnavailable 整数或百分比 25% 滚动升级过程中,允许不可用 Pod 的最大数量(相对于期望副本数) 高可用场景:减小该值可保证更多 Pod 在线,但更新速度变慢

计算公式(假设期望副本数为 replicas=10,maxSurge=25%,maxUnavailable=25%):

  • 最大 Pod 总数 = replicas + maxSurge = 10 + 2.5(向上取整 3)= 13
  • 最小可用 Pod 数 = replicas - maxUnavailable = 10 - 2.5(向下取整 2)= 8
  • 滚动升级期间,集群中 Pod 总数始终在 8~13 之间波动。

2.3 滚动升级流程:新旧 ReplicaSet 的交替

以下 SVG 图展示了 Deployment 从 v1 升级到 v2 时,新旧 ReplicaSet 副本数的变化过程(假设 replicas=5,maxSurge=1,maxUnavailable=1)。

Deployment 滚动升级流程:新旧 ReplicaSet 副本数变化 滚动升级流程:新旧 ReplicaSet 副本数变化 replicas=5, maxSurge=1, maxUnavailable=1 T0 T1 T2 T3 T4 RS-v1 副本数: 5 RS-v1 副本数: 4 RS-v2 副本数: 1 RS-v1 副本数: 2 RS-v2 副本数: 3 RS-v1 副本数: 1 RS-v2 副本数: 5 RS-v2 副本数: 5 说明:整个过程中,Pod 总数始终在 [4, 6] 之间(minAvailable=4, maxTotal=6) 旧 RS 逐步缩容,新 RS 逐步扩容,直到新 RS 完全接管

2.4 滚动升级的完整步骤

  1. 触发更新:修改 Deployment 的 Pod template(如镜像版本),Kubernetes API Server 记录新的 spec。
  2. 创建新 ReplicaSet:Deployment controller 检测到版本变化,创建一个新的 ReplicaSet(RS-v2),初始副本数为 0。
  3. 计算目标副本数:根据 maxSurge 和 maxUnavailable 计算当前允许的最大 Pod 总数和最小可用 Pod 数。
  4. 逐步扩容新 RS:增加 RS-v2 的副本数(创建新版本 Pod),同时确保不超过最大 Pod 总数。
  5. 逐步缩容旧 RS:减少 RS-v1 的副本数(删除旧版本 Pod),同时确保不低于最小可用 Pod 数。
  6. 健康检查等待:新 Pod 通过 readiness probe 后,才继续下一轮扩容/缩容操作。
  7. 完成:当 RS-v2 副本数达到期望值,RS-v1 副本数降为 0 时,滚动升级完成。旧 ReplicaSet 保留在集群中,用于回滚。

常见陷阱:

  • readiness probe 配置不当:如果新 Pod 的 readiness probe 一直失败,Deployment 会认为新 Pod 不可用,导致滚动升级卡住,新旧 Pod 同时存在。
  • maxSurge 设置过大:在资源紧张的集群中,可能导致节点资源耗尽,Pod 调度失败。
  • maxUnavailable 设置为 0:严格保证所有旧 Pod 都可用,但更新速度极慢,且如果新 Pod 启动失败,更新将完全阻塞。

2.5 滚动升级策略配置示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 3          # 允许最多超出 3 个 Pod
      maxUnavailable: 2    # 允许最多 2 个 Pod 不可用
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: my-app:2.0.0
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

监控联动提示: 在 Prometheus 中,可以通过 kube_deployment_status_replicas_available 和 kube_deployment_status_replicas_unavailable 指标实时观察滚动升级过程中可用副本数的变化。当 unavailable 指标持续高于 maxUnavailable 时,说明更新可能遇到了问题。