2. K8s回滚基础:K8s原生回滚机制
Kubernetes 原生回滚机制是 GitOps 流水线中故障恢复的底层保障。理解 Deployment rollout undo 的工作原理、历史查看方式以及策略配置,是构建可靠回滚能力的前提。本章从这三个维度展开,帮助你在 GitOps 场景中精准调用 K8s 原生能力。
2.1 Deployment Rollout Undo 核心机制
kubectl rollout undo 是 Kubernetes 提供的原生回滚命令,其本质是将 Deployment 的 PodTemplate 恢复到历史版本中的某个修订版(Revision)。K8s 通过 ReplicaSet 记录每次变更的快照,回滚时只需调整控制器指向的目标 ReplicaSet。
核心原理: 每次对 Deployment 的 .spec.template 进行修改,K8s 都会创建一个新的 ReplicaSet,并递增 Revision 编号。回滚操作即是将当前控制器指向旧的 ReplicaSet,并逐步缩容新版本 Pod、扩容旧版本 Pod。
# 回滚到上一个版本(默认)
kubectl rollout undo deployment/nginx-deployment
# 回滚到指定 Revision
kubectl rollout undo deployment/nginx-deployment --to-revision=3
# 查看回滚状态
kubectl rollout status deployment/nginx-deployment
2.2 回滚历史查看与 Revision 管理
K8s 默认保留 10 个历史 Revision,可通过 revisionHistoryLimit 调整。查看历史记录是回滚决策的关键步骤。
| 命令 | 作用 | 输出关键字段 |
|---|---|---|
kubectl rollout history deployment/<name> |
列出所有 Revision 编号和变更原因 | REVISION、CHANGE-CAUSE |
kubectl rollout history deployment/<name> --revision=3 |
查看指定 Revision 的完整 PodTemplate 细节 | 镜像版本、环境变量、资源限制等 |
kubectl describe deployment/<name> |
查看当前 Deployment 状态及新旧 ReplicaSet 分布 | OldReplicaSets、NewReplicaSet |
最佳实践: 在 GitOps 场景中,建议在 Deployment 的 annotation 中设置
kubernetes.io/change-cause,记录本次变更的 Git Commit ID 或变更描述,使历史记录可追溯。
# 查看历史版本列表
kubectl rollout history deployment/nginx-deployment
# 输出示例:
# REVISION CHANGE-CAUSE
# 1 kubectl apply --record=true
# 2 kubectl set image deployment/nginx nginx=nginx:1.21
# 3 kubectl set image deployment/nginx nginx=nginx:1.22
# 查看 Revision 3 的完整配置
kubectl rollout history deployment/nginx-deployment --revision=3
2.3 回滚策略配置与参数详解
Deployment 的回滚行为受 .spec.strategy 和 .spec.revisionHistoryLimit 控制。合理配置这些参数,可以平衡回滚速度、稳定性和历史保留深度。
2.3.1 revisionHistoryLimit
控制保留的 ReplicaSet 数量,默认值为 10。设置为 0 将关闭历史记录,导致无法回滚。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
revisionHistoryLimit: 5 # 只保留最近 5 个版本
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
template:
# ... Pod 模板
2.3.2 回滚过程中的滚动更新参数
回滚本质是一次滚动更新,因此 maxSurge 和 maxUnavailable 同样生效。
| 参数 | 默认值 | 回滚影响 | 推荐 GitOps 场景值 |
|---|---|---|---|
maxSurge |
25% | 回滚时可临时超出期望副本数的比例,加速扩容旧 Pod | 10% 或 1(保守) |
maxUnavailable |
25% | 回滚时可允许的最大不可用 Pod 比例,影响服务中断窗口 | 0%(零停机回滚) |
minReadySeconds |
0 | 回滚后 Pod 就绪等待时间,避免快速回滚导致波动 | 30-60(生产环境) |
注意: 在 GitOps 流水线中,如果使用
kubectl rollout undo 直接回滚,会导致集群状态与 Git 仓库状态不一致。建议仅在紧急故障时使用原生回滚作为第一响应,后续仍需通过 Git 提交修复版本进行 reconcile。
2.4 回滚策略配置对比
根据业务场景选择合适的回滚策略配置,以下为三种典型配置模板:
| 场景 | revisionHistoryLimit | maxSurge | maxUnavailable | minReadySeconds |
|---|---|---|---|---|
| 开发/测试环境 | 3 | 25% | 25% | 0 |
| 生产环境(高可用) | 10 | 10% | 0% | 30 |
| 生产环境(快速回滚) | 5 | 50% | 25% | 10 |
2.5 回滚操作的实际影响
- Revision 递增: 每次
rollout undo都会产生一个新的 Revision,历史版本链持续增长。 - Pod 重建: 回滚会导致旧版本 Pod 重新创建,而非原地恢复,因此会触发新一轮 Readiness 探针检查。
- 事件记录: 回滚操作会在 Deployment 的 Events 中记录,可通过
kubectl describe deployment查看。 - 与 HPA 的交互: 回滚期间如果 HPA 正在扩缩容,可能出现短暂的副本数冲突,建议回滚前暂停 HPA。
GitOps 集成要点: 原生回滚是应急手段,不应作为 GitOps 的常规操作。在 ArgoCD 或 Flux 管理的集群中,直接执行
kubectl rollout undo 会导致集群状态与 Git 仓库出现偏差(OutOfSync)。正确的做法是:紧急回滚后,立即在 Git 仓库中 revert 对应 commit,让 GitOps 控制器自动 reconcile 回正确状态。