3. Deployment 滚动更新机制详解:ReplicaSet、滚动更新策略与更新流程

Deployment 的滚动更新(Rolling Update)是 Kubernetes 中最核心的应用发布策略。它通过逐步替换旧版本 Pod 实例,实现零停机、可控速率的应用升级。理解其底层组件 ReplicaSet 以及策略参数 maxSurge 与 maxUnavailable,是优化证书轮换等敏感作业流程的基础。

3.1 核心组件:ReplicaSet 的版本化控制

Deployment 并不直接管理 Pod,而是通过 ReplicaSet(RS) 进行间接管理。每次 Deployment 的 Pod 模板(spec.template)发生变更(例如更新证书文件或镜像版本),Kubernetes 都会创建一个新的 ReplicaSet,并逐步调整新旧 RS 的副本数。

组件 职责 与滚动更新的关系
Deployment 声明式管理,维护期望状态 触发更新、控制策略、记录版本历史
ReplicaSet (旧) 维持旧版本 Pod 数量 在更新过程中被逐步缩容至 0
ReplicaSet (新) 维持新版本 Pod 数量 在更新过程中被逐步扩容至期望副本数
Pod 运行实际应用实例 承载证书文件,被逐个替换
关键认知: 滚动更新的本质是 ReplicaSet 之间的副本转移。旧 RS 缩容一个 Pod,新 RS 就扩容一个 Pod,直到所有流量切换到新版本。Deployment 的 revisionHistoryLimit 属性控制保留多少个旧 RS,用于快速回滚。

3.2 滚动更新策略:maxSurge 与 maxUnavailable

滚动更新的速率和资源占用由 strategy.rollingUpdate 下的两个关键参数控制。这两个参数可以是整数(数量)或百分比(相对于期望副本数)。

参数 含义 默认值 典型场景
maxSurge 更新过程中,允许超出期望副本数的最大 Pod 数量 25% 控制更新期间的资源峰值,避免集群过载
maxUnavailable 更新过程中,允许不可用 Pod 的最大数量 25% 保证服务的最小可用实例数,维持服务容量

参数计算示例(期望副本数 replicas=10):

  • maxSurge=25%:更新期间最多允许 10 * 25% = 2.5,向上取整为 3 个额外 Pod。集群中 Pod 总数最多为 10 + 3 = 13 个。
  • maxUnavailable=25%:更新期间最多允许 10 * 25% = 2.5,向下取整为 2 个 Pod 不可用。集群中可用 Pod 最少为 10 - 2 = 8 个。
证书轮换优化建议: 对于证书挂载场景,建议将 maxUnavailable 设置为 0,确保更新过程中始终有足够的 Pod 处理业务流量,避免因证书短暂缺失导致服务中断。同时,适当调大 maxSurge 可以加速轮换过程。

3.3 滚动更新流程详解

以下 SVG 图展示了从触发更新到完成的完整流程,以及新旧 ReplicaSet 的副本变化。

Deployment 滚动更新流程(replicas=4, maxSurge=1, maxUnavailable=1) 阶段 1:初始状态 RS-v1 (4) RS-v2 (0) 触发更新 阶段 2:扩容新 RS RS-v1 (4) RS-v2 (1) maxSurge=1 → 新增 1 个 Pod 阶段 3:缩容旧 RS RS-v1 (3) RS-v2 (1) maxUnavailable=1 → 删除 1 个旧 Pod 完成 RS-v1 (0) RS-v2 (4) 流程说明: 1. 用户更新 Deployment 的 Pod 模板(如替换证书 Secret 引用的 ConfigMap)。 2. Controller 创建新 RS-v2,并根据 maxSurge 扩容 1 个新 Pod。 3. 新 Pod 就绪后,根据 maxUnavailable 缩容 RS-v1,删除 1 个旧 Pod。 4. 重复步骤 2-3,直到 RS-v1 副本数为 0,RS-v2 副本数达到期望值。 更新过程中 Pod 状态变化 旧 Pod (v1) Terminating 新 Pod (v2) Running (v2)

3.4 更新流程中的关键步骤与状态检查

Kubernetes Controller Manager 中的 Deployment Controller 负责执行滚动更新,其核心逻辑是一个循环,直到新旧 RS 的副本数达到期望状态。

  1. 检测变更: Controller 监听到 Deployment 的 Pod 模板发生变化(如 spec.template.spec.containers[].image 或挂载的 Secret/ConfigMap 版本更新)。
  2. 暂停旧 RS: 将旧 ReplicaSet 标记为不再接收新 Pod 请求。
  3. 创建新 RS: 根据新的 Pod 模板创建一个新的 ReplicaSet,初始副本数为 0。
  4. 执行扩容(新 RS): 计算当前可扩容数量,不超过 maxSurge 的限制。新 Pod 启动并通过 Readiness Probe 检查后,标记为 Ready。
  5. 执行缩容(旧 RS): 计算当前可缩容数量,不超过 maxUnavailable 的限制。Controller 向旧 Pod 发送 SIGTERM 信号,等待 TerminationGracePeriodSeconds 后强制删除。
  6. 重复步骤 4-5: 直到新 RS 的副本数等于期望副本数,旧 RS 的副本数归零。
  7. 更新状态: Deployment 的 status.updatedReplicas 等于期望副本数,status.readyReplicas 等于可用副本数,滚动更新完成。
证书轮换陷阱: 如果 Pod 的 Readiness Probe 配置不当(例如探针依赖的证书文件在挂载延迟后才生效),新 Pod 可能永远不会进入 Ready 状态,导致滚动更新卡住。建议在 Readiness Probe 中增加对证书文件存在性的检查,并设置合理的 initialDelaySeconds。

3.5 滚动更新策略配置示例

以下是一个针对证书轮换场景优化的 Deployment YAML 配置片段,强调安全性和可控性。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cert-renewal-app
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2        # 允许最多额外创建 2 个 Pod,加速轮换
      maxUnavailable: 0  # 确保更新期间所有旧 Pod 都可用,零停机
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: my-app:latest
        volumeMounts:
        - name: cert-volume
          mountPath: /etc/certs
        readinessProbe:
          exec:
            command:
            - cat
            - /etc/certs/tls.crt
          initialDelaySeconds: 5
          periodSeconds: 10
      volumes:
      - name: cert-volume
        secret:
          secretName: my-tls-secret
参数选择建议:
  • maxUnavailable=0: 适用于证书轮换等对服务连续性要求极高的场景,确保任何时候都有足够的 Pod 处理请求。
  • maxSurge=1 或 2: 在集群资源充足的情况下,适当增加该值可以缩短轮换时间。对于大规模集群,建议设置为 10%-25% 以避免资源冲击。
  • Readiness Probe: 必须包含对证书文件或挂载点的检查,防止 Pod 在证书未就绪时被纳入 Service 端点。

3.6 滚动更新 vs 其他更新策略

策略 更新方式 适用场景 证书轮换适用性
RollingUpdate 逐步替换 Pod 大多数无状态应用,需要零停机 ✅ 推荐,配合 maxUnavailable=0
Recreate 先删除所有旧 Pod,再创建新 Pod 有状态应用或需要完全重启的场景 ❌ 不推荐,会导致服务短暂中断
Blue/Green 同时运行两套环境,切换 Service 流量 需要快速回滚、A/B 测试 ✅ 可用,但资源消耗翻倍
Canary 先更新少量 Pod,验证后再全量更新 灰度发布、风险控制 ✅ 可用,适合验证新证书兼容性