目标
裸的 rollout undo 只会回到“上一个修订”,事故慌乱中你未必清楚那是不是你想要的那个。正确做法是先列出修订历史、核对候选修订的镜像、按明确编号回滚,然后查询线上 Pod 的实际镜像与监控指标完成闭环验证,杜绝“以为回滚了其实没有”的二次事故。
步骤要点
- 先 rollout history 列出修订与 change-cause 注解,确认哪个编号对应最后已知好版本。
- 用 –revision=N 查看候选修订的容器镜像,确认它确实是你要回滚到的那个版本。
- 用 rollout undo –to-revision=10 显式回滚,再用 rollout status 等待滚动更新真正完成。
- 用 jsonpath 查询带 app 标签的线上 Pod 镜像并 uniq -c,确认只剩旧镜像、没有混版本窗口。
- 用触发回滚的监控信号(错误率、延迟)复查恢复情况,形成从发现到验证恢复的完整闭环。
排错提示
历史只剩一条说明 revisionHistoryLimit 被调成 1 或 0,旧 ReplicaSet 已删,只能从 Git 重新部署已知好清单;回滚卡住 Pod pending 是资源配额或节点压力挡住了旧 ReplicaSet 扩容,先看事件释放余量;undo 成功但错误依旧,说明回归不是镜像而是同车的配置或 schema 变更,undo 只回滚 Pod 模板,其他要单独回退或前进修复。
适用边界
rollout undo 只回滚 Pod 模板,ConfigMap、Secret 与数据库 schema 都在其范围外需单独处理;Git 才是真正的真源,集群修订历史只是便利,回滚后必须立即对账仓库。
代码示例
kubectl rollout history deployment/web -n prod
# REVISION CHANGE-CAUSE
# 10 deploy 1.4.1
# 11 deploy 1.4.2 <-- bad
kubectl rollout undo deployment/web -n prod --to-revision=10
kubectl rollout status deployment/web -n prod --timeout=180s
# Prove what production runs now
kubectl get pods -n prod -l app=web \
-o jsonpath="{.items[*].spec.containers[0].image}"
# registry/web:1.4.1