一、Deployment 只有两种主流更新策略

Deployment 的更新策略主要有两类:

  • Recreate
  • RollingUpdate

默认值是 RollingUpdate。它们的区别并不抽象,可以直接理解成两种上线哲学:

  • Recreate:先停旧版本,再起新版本
  • RollingUpdate:边起新版本,边下旧版本

二、Recreate 适合什么场景

如果你的应用无法容忍新旧版本并存,比如数据库初始化逻辑互斥、文件锁冲突、老旧单体服务升级过程必须清场,那么 Recreate 反而更简单直接。

一个典型配置如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  strategy:
    type: Recreate
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        resources:
          requests:
            cpu: "100m"
            memory: "100Mi"
          limits:
            cpu: "500m"
            memory: "1Gi"

更新资源或模板后重新应用:

kubectl apply -f nginx-recreate.yaml
kubectl get pods

Recreate 的优点是行为简单、切换干净;缺点也很明显:旧 Pod 全部删除到新 Pod 就绪之间,业务会出现空窗期。

三、RollingUpdate 才是大多数无状态服务的默认答案

对于 Web 服务、API 服务、前后端分离应用而言,通常更希望上线过程中服务持续可用。这时用 RollingUpdate 更合适。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2

这两个参数决定了滚动过程的节奏:

  • maxUnavailable:更新期间最多允许多少旧副本暂时不可用
  • maxSurge:更新期间最多允许超出期望值创建多少新副本

比如副本数是 4,maxUnavailable=25%,就表示最多允许 1 个副本暂时不可用;maxSurge=25% 则表示最多可额外多起 1 个新副本。

四、为什么很多高可用场景会用 maxUnavailable=0

原文里特别强调了一种配置:

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1

这套参数的核心目标只有一个:更新期间不减少可用副本。

它适合的场景通常是:

  • 支付、交易、订单等高连续性业务
  • 单个 Pod 的负载已经接近设计上限,不能承受先减副本再切换
  • 事务处理较长,不希望旧 Pod 被过早摘除

它的代价也同样直接:

  • 需要额外资源来容纳新 Pod
  • 更新速度会更慢,因为替换更严格、更加串行

五、为什么有些团队更喜欢固定值而不是百分比

在大规模集群里,百分比会随着副本数增长而放大资源抖动。例如副本数从 10 增加到 100 时,同样的 30% 就意味着 surge 数量从 3 变成 30,资源消耗完全不是一个量级。

因此很多关键业务会更偏好固定值:

  • maxSurge: 12
  • maxUnavailable: 01

这样虽然保守,但资源预算更可控,也更容易评估上线风险。

六、怎么做选择更稳妥

如果你是无状态服务,默认建议从 RollingUpdate 开始;如果你是强互斥应用、升级必须清场,再考虑 Recreate。而在真正的生产环境里,更新策略从来不是 YAML 美观问题,而是“可用性、资源预算、发布时长”三者之间的平衡。