3. K8s Deployment 滚动更新原理:ReplicaSet、滚动更新策略参数

滚动更新(Rolling Update)是 Kubernetes Deployment 默认的更新策略,其核心目标是在不中断服务的前提下,逐步用新版本 Pod 替换旧版本 Pod。理解滚动更新的底层机制,是制定回滚策略与多租户权限联动方案的基础。

3.1 核心组件:ReplicaSet 的版本管理角色

Deployment 并不直接管理 Pod,而是通过 ReplicaSet(RS) 实现 Pod 的副本控制与版本追踪。每次 Deployment 的 Pod 模板(spec.template)发生变更时,Kubernetes 会创建一个新的 ReplicaSet,并逐步调整新旧 RS 的副本数。

组件 职责 与滚动更新的关系
Deployment 声明式管理 Pod 模板与副本数 触发更新、控制滚动策略、记录版本历史
ReplicaSet (旧) 维护旧版本 Pod 的期望副本数 滚动过程中逐步缩容至 0,保留作为回滚目标
ReplicaSet (新) 维护新版本 Pod 的期望副本数 滚动过程中逐步扩容至目标副本数
Pod 运行实际容器实例 被 RS 管理,滚动更新中逐个被替换
关键认知: Deployment 的 revisionHistoryLimit 参数控制保留多少个旧 ReplicaSet。保留的 RS 越多,可回滚的版本数越多,但会占用 etcd 存储资源。生产环境建议保留 5-10 个版本。

3.2 滚动更新流程:ReplicaSet 的交替扩容与缩容

下图展示了 Deployment 从 v1 滚动更新至 v2 时,新旧 ReplicaSet 的副本数变化过程(假设 replicas=5,maxSurge=1,maxUnavailable=1)。

滚动更新过程中 ReplicaSet 副本数变化 RS-v1 (replicas=5) RS-v2 (replicas=0) → 更新触发 RS-v1 (replicas=4) RS-v2 (replicas=1) → 扩容 1 个新 Pod RS-v1 (replicas=3) RS-v2 (replicas=2) → 缩容 1 个旧 Pod RS-v1 (replicas=1) RS-v2 (replicas=4) → 交替进行 RS-v1 (replicas=0) RS-v2 (replicas=5) → 更新完成
滚动更新核心原则: 在整个过程中,可用 Pod 总数始终维持在 desiredReplicas - maxUnavailable 到 desiredReplicas + maxSurge 之间,确保服务不中断。

3.3 滚动更新策略参数:maxSurge 与 maxUnavailable

这两个参数定义在 Deployment 的 spec.strategy.rollingUpdate 中,控制滚动更新的速率与资源占用。

参数 类型 默认值 含义 影响
maxSurge 整数或百分比 25% 更新过程中,允许超出期望副本数的最大 Pod 数量 控制更新速度与资源消耗;值越大,更新越快,但资源峰值越高
maxUnavailable 整数或百分比 25% 更新过程中,允许不可用 Pod 的最大数量 控制服务可用性下限;值越小,服务越稳定,但更新越慢

3.4 参数组合的典型场景

不同的参数组合适用于不同的业务需求。以下表格展示了常见配置及其效果:

场景 maxSurge maxUnavailable 行为描述 适用场景
快速更新 100% 100% 先创建全部新 Pod,再销毁全部旧 Pod(相当于蓝绿部署) 测试环境、可接受短暂双倍资源占用的场景
零停机 1 (或 10%) 0 先创建 1 个新 Pod,确认就绪后再销毁 1 个旧 Pod,确保始终有全部旧 Pod 提供服务 生产环境关键服务,要求严格零停机
资源受限 0 1 (或 10%) 先销毁 1 个旧 Pod,再创建 1 个新 Pod,不额外占用资源 集群资源紧张,无法承受额外 Pod 开销
均衡模式 25% 25% 默认配置,在速度与稳定性之间取得平衡 大多数通用场景

3.5 参数配置示例

以下 YAML 片段展示了一个配置了滚动更新策略的 Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2          # 允许最多超出 2 个 Pod
      maxUnavailable: 1    # 允许最多 1 个 Pod 不可用
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: my-app:2.0.0
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
重要提醒: 滚动更新依赖 readinessProbe(就绪探针) 来判断新 Pod 是否可用。如果未配置就绪探针,Kubernetes 会默认 Pod 启动后立即就绪,可能导致流量路由到尚未完全初始化的 Pod,引发请求失败。生产环境务必为每个容器配置合理的就绪探针。

3.6 滚动更新与回滚的关联

滚动更新过程中,旧 ReplicaSet 不会被立即删除,而是保留在 revisionHistory 中。当更新出现问题时,可以通过 kubectl rollout undo 命令快速回滚到任意历史版本:

# 查看 Deployment 的更新历史
kubectl rollout history deployment/my-app

# 回滚到上一个版本
kubectl rollout undo deployment/my-app

# 回滚到指定版本(例如 revision=3)
kubectl rollout undo deployment/my-app --to-revision=3

回滚的本质是:将目标 ReplicaSet 的 Pod 模板重新设置为当前 Deployment 的模板,并触发一次新的滚动更新。因此,回滚过程同样遵循 maxSurge 和 maxUnavailable 参数的约束。

3.7 多租户场景下的滚动更新考量

在多租户集群中,滚动更新策略需要与资源配额(ResourceQuota)和 Pod 安全策略联动:

  • 资源配额限制: 如果 maxSurge 设置过大,可能导致租户的 Pod 数量超出其 ResourceQuota,更新被拒绝。建议为每个租户设置合理的 maxSurge 上限。
  • Pod 中断预算(PDB): 对于关键租户服务,应配置 PDB 限制同时中断的 Pod 数量,防止滚动更新导致租户服务降级。
  • 更新速率控制: 通过 RBAC 限制租户对 spec.strategy.rollingUpdate 的修改权限,防止租户设置过于激进的更新参数影响集群稳定性。
最佳实践: 在多租户环境中,建议平台团队为每个租户的 Deployment 注入默认的滚动更新策略(如 maxSurge=1, maxUnavailable=0),并通过准入控制器(Admission Controller)强制校验,确保租户无法覆盖这些安全参数。