4. Deployment 滚动更新:rollingUpdate 策略、maxSurge 与 maxUnavailable 参数、更新过程演示

滚动更新(Rolling Update)是 Kubernetes Deployment 默认的更新策略,它通过逐步替换旧 Pod 实例来保证服务在更新期间持续可用。本节将深入解析 rollingUpdate 策略的核心参数 maxSurge 与 maxUnavailable,并通过完整的更新过程演示帮助理解其工作原理。

4.1 rollingUpdate 策略概述

当 Deployment 的 spec.strategy.type 设置为 RollingUpdate 时,Kubernetes 会按照用户定义的参数逐步替换 Pod。该策略的核心目标是:在保证服务可用性的前提下,平滑地将所有 Pod 从旧版本迁移到新版本。

策略类型 描述 适用场景
RollingUpdate 逐步替换旧 Pod,保持一定数量的 Pod 可用 生产环境默认策略,追求零停机更新
Recreate 先删除所有旧 Pod,再创建新 Pod 开发环境或允许短暂停服的场景
最佳实践: 生产环境始终使用 RollingUpdate 策略,并配合 readinessProbe 和 livenessProbe 确保流量只路由到就绪的 Pod。

4.2 maxSurge 与 maxUnavailable 参数详解

这两个参数共同控制滚动更新的速率和资源占用,是精细化调优的关键。

4.2.1 maxUnavailable

定义: 更新过程中允许处于不可用状态的 Pod 最大数量或百分比(相对于期望副本数)。

  • 作用: 保证更新期间至少有 replicas - maxUnavailable 个 Pod 处于可用状态。
  • 取值: 整数(如 1)或百分比(如 25%),默认值为 25%。
  • 示例: 若 replicas=10,maxUnavailable=25%,则更新期间最多允许 2 个 Pod 不可用,确保至少 8 个 Pod 持续提供服务。

4.2.2 maxSurge

定义: 更新过程中允许超出期望副本数的 Pod 最大数量或百分比。

  • 作用: 控制可以提前创建的新 Pod 数量,加速更新过程。
  • 取值: 整数(如 1)或百分比(如 25%),默认值为 25%。
  • 示例: 若 replicas=10,maxSurge=25%,则更新期间最多允许 12 个 Pod 同时存在(10 + 2),新 Pod 创建后旧 Pod 才被删除。
参数 控制方向 默认值 典型配置 影响
maxUnavailable 最小可用 Pod 数 25% 0(零停机)或 1(保守) 影响服务可用性下限
maxSurge 最大额外 Pod 数 25% 1(资源受限)或 100%(快速更新) 影响更新速度和资源占用
注意: 当 maxUnavailable=0 时,必须设置 maxSurge>0,否则无法创建新 Pod 来替换旧 Pod,更新将卡住。反之,maxSurge=0 时,maxUnavailable 必须大于 0。

4.3 滚动更新过程演示

以下通过一个实际案例演示滚动更新的完整流程。假设 Deployment 配置如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
        version: v1
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80

执行更新命令:kubectl set image deployment/web-app nginx=nginx:1.25

4.3.1 更新步骤分解

  1. 初始状态: 4 个 version=v1 的 Pod 全部运行,ReplicaSet web-app-xxx-v1 管理所有 Pod。
  2. 创建新 ReplicaSet: Kubernetes 创建新的 ReplicaSet web-app-yyy-v2,期望副本数为 0。
  3. 扩容新 RS: 根据 maxSurge=1,允许最多 5 个 Pod 同时存在。系统在旧 RS 保持 4 个 Pod 的基础上,为新 RS 创建 1 个新 Pod(version=v2)。
  4. 缩容旧 RS: 新 Pod 通过 readinessProbe 检查变为 Ready 后,根据 maxUnavailable=1,系统从旧 RS 中删除 1 个旧 Pod(version=v1)。此时总 Pod 数回到 4。
  5. 循环执行: 重复步骤 3-4,每次创建 1 个新 Pod,删除 1 个旧 Pod,直到所有旧 Pod 被替换。
  6. 完成状态: 4 个 version=v2 的 Pod 全部运行,旧 ReplicaSet 副本数缩为 0。
关键观察: 在整个过程中,始终有 3 到 4 个 Pod 处于 Ready 状态(replicas - maxUnavailable = 3),服务从未中断。

4.3.2 滚动更新状态图

滚动更新过程状态图(replicas=4, maxSurge=1, maxUnavailable=1) 阶段 1:初始 v1 v1 v1 v1 4 个 v1 Pod 运行中 阶段 2:创建 1 个 v2 v1 v1 v1 v1 v2 总 Pod 数 = 5(maxSurge=1) 阶段 3:删除 1 个 v1 v1 v1 v1 删除 v2 总 Pod 数 = 4(maxUnavailable=1) 阶段 4:循环至完成 v2 v2 v2 v2 4 个 v2 Pod 全部就绪 说明: • 每次循环创建 1 个新 Pod(v2),删除 1 个旧 Pod(v1),保证总 Pod 数不超过 5,可用 Pod 数不低于 3。 • 实际更新速率受 Pod 就绪时间、资源配额和节点调度能力影响。

4.4 滚动更新参数配置建议

场景 maxSurge maxUnavailable 说明
零停机更新(资源充足) 25% 或 1 0 保证所有旧 Pod 在更新期间持续服务,新 Pod 就绪后才删除旧 Pod
快速更新(容忍短暂降级) 100% 或 replicas 50% 允许创建大量新 Pod 并行替换,但可能造成资源竞争
资源受限环境 1 1 每次只替换 1 个 Pod,对集群资源冲击最小
保守更新(关键服务) 10% 10% 缓慢替换,配合 minReadySeconds 确保稳定性
生产建议: 对于无状态服务,推荐配置 maxSurge=25% 和 maxUnavailable=25%,在速度和稳定性之间取得平衡。对于有状态服务或数据库,建议 maxSurge=0 配合 maxUnavailable=1,确保数据一致性。

4.5 滚动更新回滚机制

当更新过程中出现故障(如新版本 CrashLoopBackOff),Kubernetes 会自动暂停更新。运维人员可以通过以下命令手动回滚:

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

# 回滚到指定版本
kubectl rollout undo deployment/web-app --to-revision=2

# 查看更新历史
kubectl rollout history deployment/web-app

回滚时,Kubernetes 会复用相同的 rollingUpdate 策略参数,以同样的滚动方式将 Pod 恢复到旧版本,确保回滚过程同样平滑。

4.6 滚动更新与 CRI 资源调度的关系

滚动更新过程中,新 Pod 的创建会触发 CRI(Container Runtime Interface)接口的资源调度流程:

  • kubelet 调用 CRI: 新 Pod 被调度到节点后,kubelet 通过 CRI 接口(如 containerd、CRI-O)创建容器。
  • 资源预留与限制: CRI 根据 Pod 的 resources.requests 和 resources.limits 配置,向容器运行时申请 CPU、内存等资源。
  • 节点资源压力: 若 maxSurge 设置过大,可能导致节点资源超分,触发 kubelet 的驱逐机制(Eviction)。
CRI 集成提示: 在滚动更新期间,建议监控节点资源使用率。若使用 containerd,可通过 ctr 命令查看容器资源状态;若使用 CRI-O,可通过 crictl stats 实时观察 Pod 资源消耗。