回滚
学习目标
- 掌握查看更新历史的方法
- 掌握回滚到上一版本
- 掌握回滚到指定版本
核心概念
为什么需要回滚
更新后发现问题:
- 新版本有 Bug
- 性能下降
- 依赖服务不兼容
回滚:快速恢复到之前的稳定版本
查看更新历史
# 查看历史记录
$ kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
# 查看某个版本的详情
$ kubectl rollout history deployment/nginx-deployment --revision=2
# 查看当前版本
$ kubectl get deployment nginx-deployment -o jsonpath='{.metadata.annotations.deployment\.kubernetes\.io/revision}'
记录更新原因
# 使用 --record 记录命令
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.25 --record
# 查看历史
$ kubectl rollout history deployment/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.25 --record=true
# 注意:--record 已被废弃,推荐使用注解
$ kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="Update to nginx:1.25"
回滚到上一版本
# 回滚到上一个版本
$ kubectl rollout undo deployment/nginx-deployment
# 查看回滚状态
$ kubectl rollout status deployment/nginx-deployment
# 查看历史(新版本会变成最新 revision)
$ kubectl rollout history deployment/nginx-deployment
回滚到指定版本
# 回滚到指定版本
$ kubectl rollout undo deployment/nginx-deployment --to-revision=2
# 查看版本详情
$ kubectl rollout history deployment/nginx-deployment --revision=2
回滚过程
当前状态:v3(有问题)
目标状态:v1(稳定)
步骤:
1. Deployment 更新 spec.template 到 v1 配置
2. 创建新的 ReplicaSet (v1)
3. 逐步用 v1 Pod 替换 v3 Pod
4. 旧 ReplicaSet (v3) 保留,副本数为 0
回滚本质上是一次新的滚动更新
查看回滚过程
# 实时查看
$ kubectl get pods -w
# 查看 Deployment 状态
$ kubectl get deployment nginx-deployment
# 查看 ReplicaSet
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5d8f4c4c5 3 3 3 5m # v1(回滚目标)
nginx-deployment-6d8f4c4c6 0 0 0 3m # v2
nginx-deployment-7d8f4c4c7 0 0 0 1m # v3(之前版本)
revisionHistoryLimit
spec:
revisionHistoryLimit: 10 # 保留多少个旧 ReplicaSet(默认 10)
# 查看配置
$ kubectl get deployment nginx-deployment -o jsonpath='{.spec.revisionHistoryLimit}'
实践练习
练习 1:执行回滚
# 1. 创建 Deployment
$ kubectl create deployment web --image=nginx:1.24 --replicas=3
# 2. 记录初始版本
$ kubectl annotate deployment web kubernetes.io/change-cause="Initial version: nginx:1.24"
# 3. 更新到 1.25
$ kubectl set image deployment web nginx=nginx:1.25
$ kubectl annotate deployment web kubernetes.io/change-cause="Update to nginx:1.25" --overwrite
# 4. 更新到 1.26
$ kubectl set image deployment web nginx=nginx:1.26
$ kubectl annotate deployment web kubernetes.io/change-cause="Update to nginx:1.26" --overwrite
# 5. 查看历史
$ kubectl rollout history deployment/web
# 6. 回滚到上一版本(1.25)
$ kubectl rollout undo deployment/web
# 7. 验证
$ kubectl get deployment web -o jsonpath='{.spec.template.spec.containers[0].image}'
练习 2:回滚到指定版本
# 1. 查看历史
$ kubectl rollout history deployment/web
# 2. 查看版本详情
$ kubectl rollout history deployment/web --revision=1
# 3. 回滚到版本 1
$ kubectl rollout undo deployment/web --to-revision=1
# 4. 验证
$ kubectl get deployment web -o jsonpath='{.spec.template.spec.containers[0].image}'
练习 3:理解 ReplicaSet
# 1. 查看所有 ReplicaSet
$ kubectl get rs
# 2. 观察回滚前后变化
$ kubectl get rs -w
# 3. 理解 DESIRED=0 的 ReplicaSet
# 这些是历史版本,可用于回滚
常见问题
1. 回滚失败
# 查看状态
$ kubectl rollout status deployment/web
# 查看事件
$ kubectl describe deployment/web
# 可能原因:
# - 旧版本配置有问题
# - 资源不足
# - 镜像不存在
2. 想要回滚但历史被清理
# 检查 revisionHistoryLimit
$ kubectl get deployment web -o jsonpath='{.spec.revisionHistoryLimit}'
# 如果太小,增加限制
$ kubectl patch deployment web -p '{"spec":{"revisionHistoryLimit":20}}'
3. 回滚后又想恢复到新版本
# 回滚本质上是新的更新
# 可以再次回滚到之前的版本
$ kubectl rollout undo deployment/web
小结
| 要点 | 说明 |
|---|---|
| 查看历史 | kubectl rollout history |
| 回滚上一版 | kubectl rollout undo |
| 回滚指定版 | kubectl rollout undo --to-revision=N |
| 记录原因 | kubectl annotate kubernetes.io/change-cause |
| 历史保留 | revisionHistoryLimit(默认 10) |
| 回滚本质 | 是一次新的滚动更新 |
练习编辑器
bash
Loading...