发布系统:滚动发布(Rolling Update)
滚动发布:
在 不停止整体服务 的情况下,逐个或分批替换旧版本实例为新版本,始终保证系统中有可用实例对外服务。
一句话:
不停机、分批换版本
- 零停机(或感知极低)
- 风险可控
- 自动回滚
- 服务连续可用
旧版本实例 × N 正常服务
↓
下线 1~K 个旧实例(摘流量)
↓
启动新版本实例
↓
健康检查通过
↓
加入负载均衡
↓
重复以上步骤
↓
所有实例完成升级
关键点:
- 先摘流量,再升级
- 新实例健康后才接流量
- Session 不存本地
- 文件不写本地
- 状态放在 DB / Redis / 对象存储
❌ 有状态服务直接滚动 = 灾难
- HTTP health check
- TCP 探测
- 应用级自检
- 收到 SIGTERM 后:
- 停止接新请求
- 等待正在处理的请求完成
- 再退出
- 一次下线几个实例?
- 建议:
- 小集群:1 台
- 大集群:5%~20%
- 每批间隔时间
- 是否等待监控稳定
- 成功率
- 延迟
- 错误率
Deployment 核心参数
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
含义:
- maxUnavailable:升级过程中,最多允许不可用的 Pod 数
- maxSurge:最多允许额外创建的 Pod 数
示例:
- 5 副本
- maxUnavailable=1
- maxSurge=1
-> 最多 6 个 Pod,至少 4 个可用
发布过程
- 创建新 Pod
- 新 Pod Ready
- 老 Pod 进入 Terminating
- 执行优雅关闭
- 逐个替换完成
原因:
- 没有优雅关闭
- LB 未摘流量
- readinessProbe 配置错误
解决:
- 正确配置 readiness / liveness
- 增加 terminationGracePeriodSeconds
滚动发布 ≠ 灰度
-> 全量仍然会被逐步影响
解决:
- 结合 金丝雀发布
- 或发布前压测 / 回滚机制
- 新版本依赖新字段
- 老版本仍在跑
解决:
- 数据库 向前兼容
- 两阶段发布(先 DB,后代码)
| 发布方式 | 停机 | 风险 | 回滚速度 | 复杂度 |
|---|---|---|---|---|
| 滚动发布 | 无 | 中 | 中 | 低 |
| 蓝绿发布 | 无 | 低 | 极快 | 中 |
| 金丝雀 | 无 | 极低 | 快 | 高 |
- 必须无状态
- readinessProbe 决定是否接流量
- livenessProbe 决定是否重启
- 优雅关闭 ≥ 30s
- 每一批都观察监控
- 失败立即暂停发布
- 结合限流、熔断
- 发布窗口选低峰期
- 有状态服务(如单实例数据库)
- 强一致性写入服务
- 大版本破坏性变更
- 无法向前兼容的协议
滚动发布是默认方案,但不是万能方案。
它解决“不停机”,但不解决“新版本一定正确”。