在 Kubernetes 中,Deployment 是最常用的无状态工作负载控制器。它通过管理 ReplicaSet 来实现 Pod 的副本数量与滚动更新,同时记录每次模板变更产生的 Revision。如果对部署策略理解不足,很容易在升级过程中出现服务中断、流量不一致或回滚失败。本文会从原生策略、Revision 生成机制、回滚操作以及生产建议几个维度展开。

Kubernetes 原生部署策略:Recreate 与 RollingUpdate
Deployment 的 spec.strategy.type 字段支持两种原生策略:Recreate 和 RollingUpdate。前者先删除所有旧 Pod,再创建新 Pod,优点是数据不会同时被两个版本写入,但会造成明显的停机窗口,适合允许短暂中断的批处理或数据库类应用。后者则是默认策略,通过逐步替换 Pod 来保持服务可用,升级过程中新旧版本会短暂共存,因此要求应用具备向后兼容的接口和数据格式。
RollingUpdate 的行为由 maxUnavailable 和 maxSurge 两个参数控制。maxUnavailable 指定更新过程中最多允许不可用的 Pod 数量或比例,maxSurge 指定最多允许超出期望副本数的临时 Pod 数量。例如一个副本数为 5 的 Deployment,设置 maxUnavailable 为 1、maxSurge 为 1 时,更新会先多创建一个新 Pod,再删一个旧 Pod,使总 Pod 数在 5 到 6 之间波动。下面是一个常见的滚动更新配置。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: nginx
image: nginx:1.24.0
ports:
- containerPort: 80
需要注意的是,maxUnavailable 和 maxSurge 不能同时为 0,否则控制器无法进行任何替换操作。在可用性要求较高的场景,可适当增大 maxSurge,让新 Pod 先就绪并接入流量后再逐步下线旧 Pod;在资源紧张时,则可降低 maxSurge 并允许部分不可用,用较小的资源消耗完成更新。
如果应用无法容忍新旧版本同时存在,例如写入了不兼容的数据结构,使用 Recreate 会比强行滚动更新更安全。但这并不意味着 Recreate 毫无风险,删除所有旧 Pod 后,新镜像若启动失败,整个服务将不可用。因此选择策略前应结合启动时间、健康检查、资源配额和回滚需求综合判断。
Revision 的生成机制与历史保留
每次修改 Deployment 的 spec.template 字段(例如更换镜像 tag、调整环境变量或资源限制)时,控制平面都会生成一个新的 ReplicaSet,并赋予一个递增的整数 Revision。这个 Revision 不是随机字符串,而是 Deployment 用来追踪发布历史的内部版本号。即使这次修改没有真正改变 Pod 行为,只要 template 发生变化,就会产生新的 Revision。
默认情况下,Deployment 保留最近 10 个 Revision 对应的 ReplicaSet,这个数量由 spec.revisionHistoryLimit 控制。保留的历史 ReplicaSet 本身并不会继续运行 Pod,它们只用于保存旧版本的 Pod 模板,以便回滚时快速恢复。若历史数量超过限制,最旧的 ReplicaSet 会被清理。下例将历史保留数量调整为 5。
spec:
replicas: 3
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: nginx
image: nginx:1.25.3
要查看当前 Deployment 的发布历史,可以使用命令 kubectl rollout history deployment/web-app。输出会按序号列出 Revision,并附带 CHANGE-CAUSE 信息。如果希望每次变更都能看到原因,需要在创建或更新 Deployment 时加上 kubernetes.io/change-cause 注解,例如 kubectl annotate deployment/web-app kubernetes.io/change-cause="update to nginx 1.25.3"。不过该注解在较新版本中可能不会自动记录,更适合把变更原因写进 Git 提交信息或 CI/CD 系统。
Revision 的生成并不会因为暂停更新而停止。使用 kubectl rollout pause deployment/web-app 后继续修改 template,虽然滚动过程被挂起,但新的 ReplicaSet 和 Revision 仍然会创建。恢复后,控制器会根据最新模板继续推进。这个机制可以用于批量修改多个字段后再一次性发布,但也要注意暂停期间历史数量可能快速增长。
版本回滚操作与常见故障排查
当新版本出现问题时,最简单的回滚方式是执行 kubectl rollout undo deployment/web-app。这条命令会把 Deployment 回退到上一个 Revision,并触发一次新的滚动更新。这里有一个容易误解的点:回滚并不会把 Revision 号拨回旧值,而是基于历史模板生成一个新的 Revision 继续递增。例如当前 Revision 为 8,执行 undo 后可能得到 Revision 9,但 Pod 模板已恢复为 Revision 7 的内容。
如果需要回滚到指定版本,可以使用 --to-revision 参数,例如 kubectl rollout undo deployment/web-app --to-revision=6。在执行前建议先通过 kubectl rollout history deployment/web-app --revision=6 查看该版本对应的镜像和环境变量,避免恢复到错误状态。同时要注意,如果指定的 Revision 因为 revisionHistoryLimit 过小或手动清理 ReplicaSet 而丢失,回滚会直接报错。此时只能重新创建 Deployment 或从外部配置仓库恢复模板。
# 查看发布历史 kubectl rollout history deployment/web-app # 查看指定 Revision 的详细 Pod 模板 kubectl rollout history deployment/web-app --revision=6 # 回滚到上一个版本 kubectl rollout undo deployment/web-app # 回滚到指定 Revision kubectl rollout undo deployment/web-app --to-revision=6 # 查看回滚后的状态 kubectl rollout status deployment/web-app
回滚失败通常有三个原因:历史 ReplicaSet 被删除、当前集群资源不足以启动回滚所需的新 Pod、或者回滚后的模板与现有 Service 选择器不匹配导致流量无法路由。排查时可以先执行 kubectl describe deployment/web-app 查看事件,再检查 kubectl get rs -l app=web-app 确认历史 ReplicaSet 是否存在。如果新 Pod 一直处于 Pending 或 CrashLoopBackOff,需要结合资源配额、镜像拉取权限和健康检查配置进一步定位。
另外,不要直接编辑某个旧的 ReplicaSet 来试图“修复”版本。Deployment 控制器会按当前 template 维护期望状态,手动修改 ReplicaSet 的 Pod 模板不会同步回 Deployment,反而会造成实际运行的 Pod 与声明式配置不一致,影响后续更新和回滚判断。所有版本变更都应通过修改 Deployment 或使用 rollout 命令完成。
蓝绿发布与金丝雀发布的 Revision 管理思路
原生 Deployment 的 RollingUpdate 虽然能平滑出行,但无法做到按权重将流量逐步切换给新版本。蓝绿发布通常需要准备两个独立 Deployment,例如 web-app-blue 和 web-app-green,每个 Deployment 有自己的 Revision 历史。切换时修改 Service 的 selector 指向新版本的标签,流量会一次性从旧环境切到新环境。这种方式回滚快速,但需要两倍的资源预算。
金丝雀发布则可以通过 Ingress 或服务网格实现更细粒度的流量分配。例如创建两个 Deployment 分别对应稳定版和金丝雀版,再让 Ingress 根据权重把 10% 的请求转发给金丝雀 Pod。此时两个 Deployment 各自维护 Revision,回滚金丝雀版本不会影响稳定版。对于更复杂的灰度策略,通常会引入 Argo Rollouts、Flagger 等工具,它们在底层仍然基于 ReplicaSet 和 Revision 机制,但提供了自动分析、流量调度和一键回滚能力。
无论采用哪种策略,Revision 管理的关键点是一致的:保留足够的历史记录、命名规范清晰、变更可追踪、回滚动作可重复。生产环境中建议将 revisionHistoryLimit 设置为一个平衡值,例如 10 到 20,既能覆盖近期发布历史,又不会积累过多 ReplicaSet。如果使用 GitOps 或 Helm,应优先通过修改仓库中的声明式配置并重新部署来实现回滚,而不是依赖 kubectl 命令临时修补,这样可以保证集群状态与代码仓库一致。
部署策略没有绝对的最佳方案,需要根据应用状态、流量特征和团队运维能力来选择。理解 Deployment 如何生成和管理 Revision,是避免发布事故、快速恢复服务的核心基础。
Kubernetes部署策略Revision管理滚动更新修改时间:2026-09-29 12:58:12