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
K8s 原生回滚流程(Rollout Undo) 当前 Deployment Revision 历史 rollout undo 查看历史 指定版本 旧 ReplicaSet 新 ReplicaSet Pod 滚动迁移 目标指向旧版本 扩容旧 Pod / 缩容新 Pod 关键说明: • 回滚不删除新 ReplicaSet,仅调整副本数,便于再次回滚。 • 回滚操作本身也会产生一个新的 Revision(Revision +1),保留操作记录。 • 回滚过程中遵循 Deployment 的 maxSurge 和 maxUnavailable 策略。

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
回滚策略配置决策树 选择回滚策略 高可用优先 快速回滚优先 资源节约优先 配置: maxUnavailable=0% minReadySeconds=30 配置: maxSurge=50% revisionHistoryLimit=5 配置: revisionHistoryLimit=3 maxSurge=25% 💡 建议:生产环境优先使用高可用配置(maxUnavailable=0%),确保回滚期间不中断服务。 GitOps 场景下,revisionHistoryLimit 建议保留 5-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 回正确状态。