本节摘要:Deployment 的滚动更新通过新旧两个 ReplicaSet 的此消彼长完成换苗,maxSurge 与 maxUnavailable 两个参数控制换茬节奏,保证更新期间服务不断流。rollout 命令族(status、history、undo、pause、resume)是全程的观察与干预手段。本节完整走一遍书屋网页的版本升级与一次教科书式回滚。
书屋网页要发新版:0.9.1 换 1.0.0,新增了"续借"按钮。传统做法是停服、换包、起服,夜里干活白天不敢碰。滚动更新的思路完全不同:不腾田,站在原地分批换茬——先让一株新苗入列、确认能接客,再收走一株旧苗,如此往复,任何时刻在岗的苗数不减。
还记得 3.2 埋的伏笔吗?Deployment 不直接动苗,它每次换版本就新建一个 ReplicaSet,让新旧两个数苗员一涨一消。此刻这层设计的红利正式兑现:新旧两组各自有保底株数,切换永远有兜底。

# 触发换茬:把镜像版本改成 1.0.0 kubectl set image deployment/greenlib-web web=greenlib/web:1.0.0 -n greenlib-prod # deployment.apps/greenlib-web image updated # 盯着换茬现场(新开一个终端跑这条,看它逐行生长) kubectl rollout status deployment/greenlib-web -n greenlib-prod # Waiting for deployment "greenlib-web" rollout to finish: 2 of 3 updated replicas are available # Waiting for deployment "greenlib-web" rollout to finish: 2 of 3 updated replicas are available # deployment "greenlib-web" successfully rolled out # 换茬的账目:新旧两个数苗员的一涨一消 kubectl get rs -n greenlib-prod -l app=greenlib-web # NAME DESIRED CURRENT READY # greenlib-web-5c8d9b7f4 0 0 0 旧数苗员 已缩到零(账还留着) # greenlib-web-7d9b6c5f4 3 3 3 新数苗员 接管全部
发布完成不等于发布成功——真正的验收在业务侧(续借按钮点得动)。假设十几分钟后客服炸了:部分读者反馈"续借后书单乱序"。经典时刻,回滚登场:
# 看版本账本:每次换茬都有存档 kubectl rollout history deployment/greenlib-web -n greenlib-prod # deployment.apps/greenlib-web # REVISION CHANGE-CAUSE # 3 <none> 当前 1.0.0 # 2 <none> 0.9.1 # 1 <none> 初始 # 一条命令回到上一版 kubectl rollout undo deployment/greenlib-web -n greenlib-prod # deployment.apps/greenlib-web rolled back kubectl rollout status deployment/greenlib-web -n greenlib-prod # deployment "greenlib-web" successfully rolled out kubectl get rs -n greenlib-prod -l app=greenlib-web # greenlib-web-5c8d9b7f4 0 0 0 又缩回零 # greenlib-web-7d9b6c5f4 3 3 3 旧版数苗员官复原职
回滚不是恢复备份,是把历史版本按同样的滚动流程再滚一遍。旧 ReplicaSet 的账本一直留着(revisionHistoryLimit 控制留几份,默认十),所以"退回去"只需把旧数苗员的期望从零改回三。整套动作和正向发布走的是同一条机械传送带,这正是 3.2 那句"隔代管理的红利"的全部含义。
图里的 maxSurge 与 maxUnavailable 写进 Deployment 即可定制节奏:
spec: strategy: rollingUpdate: maxSurge: 1 # 最多临时多一株(可以是整数或百分比) maxUnavailable: 0 # 一株都不许缺
两个旋钮一张表说清取舍:
| 配置 | 效果 | 适合 |
|---|---|---|
| 加一 缺零 | 任何时刻在岗不减少,机器要有余量 | 书屋这类面向读者的服务(本例) |
| 加零 缺一 | 不占额外资源,短暂少一株扛量 | 内部低峰服务、资源紧张时 |
| 默认两成五加两成五 | 均衡 | 大株数场景的常规选择 |
注意"缺零"成立的前提:新苗能通过就绪检查(第八章探针)才会进水闸名单,坏苗永远挡在门外——所以没有像样探针的滚动更新是假滚动,旧苗照收、新苗是坏的,服务照样瘫。第八章会把这块短板补上,两章合起来才是完整的发布安全学。
⚠️ 常见坑:发布中途发现问题想暂停观察,别用中断命令硬停,用
kubectl rollout pause与kubectl rollout resume这对开关。暂停期间可以改配置、查现场,恢复后接着滚。另记住:undo 之后想再前进,得重新 set image,历史账本不是任意跳的时光机。
Deployment 默认保留十个历史版本(revisionHistoryLimit 可调),超出的旧 ReplicaSet 会被清账。回滚依赖历史账本,改小之前先想清楚你的后悔药要留几份。另一个建议:每次发布带上 change-cause 注解,rollout history 的账本才可读——否则满眼空值,出了问题只能靠猜。