3. Deployment 滚动更新原理:核心参数详解
Deployment 的滚动更新(RollingUpdate)策略是 Kubernetes 中最常用的无状态应用发布方式。其核心在于通过四个关键参数控制更新的速率、可用性容忍度、就绪检测与超时终止。理解这些参数是排查滚动中断、优化集群升级效率的基础。
3.1 滚动更新流程概览
滚动更新的本质是“逐步替换旧 Pod,同时保证集群中可用的 Pod 数量不低于安全阈值”。控制器会创建新 ReplicaSet,逐步扩容新 Pod、缩容旧 Pod,直到所有 Pod 都运行在新版本上。
3.2 四大核心参数详解
滚动更新策略定义在 spec.strategy.rollingUpdate 下,配合 spec.minReadySeconds 和 spec.progressDeadlineSeconds 共同决定更新行为。
| 参数 | 类型 | 默认值 | 作用域 | 核心作用 |
|---|---|---|---|---|
| maxSurge | int / 百分比 | 25% | 滚动更新 | 更新期间允许超出期望副本数的最大 Pod 数量 |
| maxUnavailable | int / 百分比 | 25% | 滚动更新 | 更新期间允许不可用 Pod 的最大数量 |
| minReadySeconds | int | 0 | Pod 就绪 | Pod 进入 Ready 状态后,等待该时长才视为“可用” |
| progressDeadlineSeconds | int | 600 | 更新进度 | 更新未完成时,超过该时长则标记为 Progressing=False |
3.3 maxSurge 与 maxUnavailable:速率与可用性平衡
这两个参数共同决定了滚动更新的“并行度”和“安全边界”。
- maxSurge:控制“最多可以多创建多少个 Pod”。例如副本数 10,maxSurge=25%(向上取整为 3),则更新期间最多允许 13 个 Pod 同时运行。
- maxUnavailable:控制“最多可以有多少个 Pod 不可用”。例如副本数 10,maxUnavailable=25%(向上取整为 3),则更新期间至少要有 7 个 Pod 保持可用。
关键公式:
- 最大可用 Pod 数 = 期望副本数 + maxSurge
- 最小可用 Pod 数 = 期望副本数 - maxUnavailable
- 滚动更新期间,实际 Pod 总数始终在 [最小可用, 最大可用] 区间内
3.4 minReadySeconds:防止抖动就绪
该参数要求 Pod 在 Readiness 探测通过后,必须稳定运行 minReadySeconds 秒,控制器才将其计入“可用 Pod”。
- 典型场景:应用启动后需要预热缓存、加载模型或等待依赖服务。设置 30-60 秒可避免 Pod 刚 Ready 就因短暂抖动被替换。
- 与 ReadinessProbe 的关系:ReadinessProbe 决定 Pod 是否 Ready;minReadySeconds 决定 Ready 后是否“可信”。两者配合使用。
- 排查提示:如果滚动更新卡住,检查
kubectl describe deployment中OldReplicaSets和NewReplicaSet的Available字段,确认是否因 minReadySeconds 导致新 Pod 迟迟不被标记为可用。
3.5 progressDeadlineSeconds:更新超时与回滚触发
该参数定义了 Deployment 更新进度的“最大容忍时间”。如果在此时间内更新未完成,控制器会将 Deployment 的 Progressing 条件置为 False,并可能触发自动回滚(如果配置了回滚策略)。
| 状态 | 说明 | 常见原因 |
|---|---|---|
| Progressing=True | 更新正在进行中 | 正常滚动 |
| Progressing=False | 更新超时或失败 | 新 Pod 无法通过 Readiness、镜像拉取失败、资源不足 |
| Available=True | 有足够数量的 Pod 可用 | 更新成功或部分成功 |
| Available=False | 可用 Pod 不足 | maxUnavailable 设置过大、Pod 崩溃 |
避坑指南:
- 不要将 progressDeadlineSeconds 设置过小(如 60 秒),否则大型集群更新容易误报超时。
- 如果更新卡住,先检查
kubectl rollout status deployment/<name>的输出,再查看kubectl describe deployment中的 Conditions 字段。 - 配合
kubectl rollout undo使用,可在超时后快速回滚到上一版本。
3.6 参数组合实战示例
以下是一个生产级 Deployment 配置片段,展示了四个参数的典型设置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 3 # 允许最多 13 个 Pod 同时运行
maxUnavailable: 2 # 允许最多 2 个 Pod 不可用,至少保留 8 个可用
minReadySeconds: 30 # Pod Ready 后等待 30 秒才视为可用
progressDeadlineSeconds: 300 # 5 分钟内未完成更新则标记失败
template:
spec:
containers:
- name: app
image: nginx:1.25
readinessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 5
periodSeconds: 10
3.7 参数调优建议
| 场景 | maxSurge | maxUnavailable | minReadySeconds | progressDeadlineSeconds |
|---|---|---|---|---|
| 快速迭代、容忍短时抖动 | 25% | 25% | 0-10 | 600 |
| 高可用生产环境 | 10% 或 1 | 0 或 1 | 30-60 | 900 |
| 大集群批量更新(100+ Pod) | 10% | 5% | 15-30 | 1200 |
| 启动慢的应用(Java/ML) | 1-2 | 1 | 60-120 | 1800 |
3.8 常见滚动中断场景与参数关联
| 中断现象 | 可能原因 | 关联参数 | 排查命令 |
|---|---|---|---|
| 更新卡住,新 Pod 创建后一直 Pending | 资源不足、PVC 挂载失败 | maxSurge 过大导致资源争抢 | kubectl describe pod <new-pod> |
| 更新卡住,新 Pod 反复 CrashLoopBackOff | 应用启动失败、配置错误 | minReadySeconds 无法满足 | kubectl logs <new-pod> --previous |
| 更新超时,Progressing=False | 新 Pod 无法通过 Readiness | progressDeadlineSeconds 过短 | kubectl rollout status deployment/<name> |
| 更新期间服务中断 | maxUnavailable 设置过大 | maxUnavailable 超过安全阈值 | kubectl get pods -l app=<name> -o wide |
| 更新极慢,Pod 逐个替换 | maxSurge 和 maxUnavailable 都设为 1 | 并行度不足 | 检查 rollingUpdate 配置 |
最佳实践:
- 首次配置时,使用
kubectl rollout pause deployment/<name>暂停更新,逐步调整参数。 - 监控
kubectl get events --watch观察滚动过程中的事件。 - 设置合理的
progressDeadlineSeconds(建议 600-1200 秒),避免误超时。