滚动更新与回滚
本教程共 65 篇 · 第 19 篇 · 更新于 2026-08-14 · 约 11 分钟阅读
本节目标:学完你能用滚动更新平滑换版本,调 maxSurge/maxUnavailable 控制节奏,并在出问题时一行命令回滚到上一个稳定版。
换版本最怕”一刀切”:旧的全停、新的全上,中间那段服务直接断。滚动更新(Rolling Update)的做法是一边起新的、一边退旧的,让流量始终有人接。
19-1 滚动更新原理
你还记得第 18 章说的三层吗?Deployment → ReplicaSet → Pod。
滚动更新时,Deployment 新建一个 ReplicaSet(新版),让它慢慢起新 Pod。同时旧 ReplicaSet 慢慢减副本。新旧交替期间,服务一直有 Pod 在跑。
等新的副本全部就绪,旧 ReplicaSet 缩到 0,更新完成。整个过程用户几乎无感。
kubectl set image deployment/nginx nginx=nginx:1.28
这条命令触发滚动更新。Deployment 据此创建新 RS,开始交替替换。
19-2 两个节奏旋钮
更新策略写在 spec.strategy.rollingUpdate 里,两个关键参数。
maxSurge:最多比期望副本数多几个。比如 replicas: 3、maxSurge: 1,更新时最多同时有 4 个 Pod。
maxUnavailable:更新期间最多允许几个不可用。设为 1,表示可以容忍 1 个旧 Pod 先退、新的还没补上。
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
上面这组是”稳妥型”:maxUnavailable: 0 保证任何时刻 3 个都在岗,maxSurge: 1 最多多起 1 个。代价是更新稍慢、占资源多一点。
Tip想更新更快,把
maxSurge调大;想绝对不中断,把maxUnavailable设 0。两者是”速度”和”资源/可用度”的取舍。
19-3 查看更新进度
发起更新后,先看它走到哪了:
kubectl rollout status deployment/nginx
kubectl get rs
rollout status 会阻塞到完成或失败。get rs 能看到新旧两个 RS 并存、副本此消彼长。
如果卡住,看事件找原因:
kubectl describe deployment nginx
新镜像拉不下来、探针一直不过,都会让更新停在一半。这时候别慌,先回滚。
19-4 回滚到上一版
换坏了?一行回退:
kubectl rollout undo deployment/nginx
它就回到”上一个成功的 ReplicaSet”。用户侧基本无感知,比手动修快得多。
也可以指定回某个具体版本:
kubectl rollout undo deployment/nginx --to-revision=2
19-5 翻历史版本
Deployment 默认保留最近 10 个 ReplicaSet(即版本历史)。先看都有啥:
kubectl rollout history deployment/nginx
kubectl rollout history deployment/nginx --revision=3
第二条能看某个版本的详细配置。配合 --to-revision 就能精准跳回那版。
kubectl rollout history deployment/nginx
# REVISION CHANGE-CAUSE
# 1 kubectl apply --filename=deploy.yaml
# 2 kubectl set image deployment/nginx nginx=nginx:1.28
# 3 kubectl set image deployment/nginx nginx=nginx:1.29
Note想让历史里显示”谁改的”,可以在注解
kubectl.kubernetes.io/change-cause里写明变更原因(旧版--record已弃用)。否则CHANGE-CAUSE一列是空的,回滚时只能靠猜。
19-6 暂停与继续
大版本更新想一步步确认?可以先暂停:
kubectl rollout pause deployment/nginx
kubectl set image deployment/nginx nginx=nginx:1.29
kubectl rollout resume deployment/nginx
pause 后改配置不会触发更新,resume 才真正开跑。适合要分批、人工把关的发布。
19-7 常见坑
一是更新卡住不结束。多半是新 Pod 就绪探针一直失败,Deployment 不敢把旧的退光。先看日志再决定回滚还是修探针。
二是 maxUnavailable: 0 且节点资源不够扩 maxSurge,更新会死锁。留点余量。
三是忘了保留历史。revisionHistoryLimit 默认 10,想多留可调大;不想留可设小省空间。
Warning回滚救的是”配置/镜像问题”。如果新版本把数据库表结构改坏了,回滚镜像并不能自动还原数据。这种得靠迁移脚本兜底。
滚动更新搞定无状态应用。但数据库、中间件这类”有身份、有存储”的应用,Deployment 扛不住。第 20 章讲 StatefulSet。