一、Deployment 只有两种主流更新策略¶
Deployment 的更新策略主要有两类:
RecreateRollingUpdate
默认值是 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: 1或2maxUnavailable: 0或1
这样虽然保守,但资源预算更可控,也更容易评估上线风险。
六、怎么做选择更稳妥¶
如果你是无状态服务,默认建议从 RollingUpdate 开始;如果你是强互斥应用、升级必须清场,再考虑 Recreate。而在真正的生产环境里,更新策略从来不是 YAML 美观问题,而是“可用性、资源预算、发布时长”三者之间的平衡。