本文边界:本文聚焦发布过程、
rollout操作与RollingUpdate策略的区别;Deployment 的资源模型及 Service/Deployment 的选型边界请阅读配套文章。推荐深读:Deployment 详解:Kubernetes 集群的"应用部署控制器" 与 什么时候用 Service,什么时候用 Deployment。
说明:本文由 Codex 根据作者提供的主题、素材与公开资料辅助生成,属于 AI 生成/整理内容,非作者原创。请读者自行甄别并交叉验证。
先说结论#
rollout 和 rolling update 不是同一层概念。
可以先这样记:
rolling update 是一种更新策略;
rollout 是一次发布过程,以及 kubectl 用来观察和管理这个过程的一组命令。在 Deployment 场景里:
修改 Deployment 的 Pod template
↓
触发一次 rollout
↓
Deployment 按 strategy 执行更新
↓
如果 strategy 是 RollingUpdate,就进行滚动更新所以 rolling update 是 rollout 过程中可能采用的一种方式。
rollout 是什么#
rollout 更像是“发布过程”。
当 Deployment 的 Pod 模板发生变化时,会触发一次新的 rollout。
常见会触发 rollout 的变化:
- 修改容器镜像。
- 修改容器启动参数。
- 修改环境变量。
- 修改 Pod template 下的 labels / annotations。
- 修改 readinessProbe / livenessProbe。
- 修改 resources。
不会触发 rollout 的变化:
- 只修改 Deployment 的副本数。
- 只修改不属于
.spec.template的字段。
核心判断标准是:
Deployment 的 .spec.template 是否变化。例如:
kubectl set image deployment/web web=nginx:1.27这会修改 Pod template 里的镜像,因此触发 rollout。
再比如:
kubectl scale deployment/web --replicas=5这只是修改副本数,不会创建新的 Deployment revision。
kubectl rollout 命令#
kubectl rollout 是管理 rollout 的命令入口。
常见子命令:
kubectl rollout status deployment/web
kubectl rollout history deployment/web
kubectl rollout undo deployment/web
kubectl rollout pause deployment/web
kubectl rollout resume deployment/web
kubectl rollout restart deployment/web这些命令不是更新策略本身,而是观察和操作发布过程。
| 命令 | 作用 |
|---|---|
status | 查看 rollout 是否完成 |
history | 查看 revision 历史 |
undo | 回滚到上一个或指定 revision |
pause | 暂停 rollout |
resume | 恢复 rollout |
restart | 触发一次重启式 rollout |
kubectl rollout 可以用于 Deployment、DaemonSet、StatefulSet 等资源,但不同资源的更新语义会有差异。
rolling update 是什么#
rolling update 是滚动更新。
它的目标是:
不要一次性杀掉所有旧 Pod;
逐步创建新 Pod;
逐步删除旧 Pod;
尽量保持服务可用。Deployment 默认更新策略就是 RollingUpdate。
示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80这里的意思是:
- 期望副本数是 4。
- 更新过程中最多允许 1 个 Pod 不可用。
- 更新过程中最多允许额外多创建 1 个 Pod。
滚动过程大致是:
旧 RS: 4, 新 RS: 0
旧 RS: 4, 新 RS: 1
旧 RS: 3, 新 RS: 1
旧 RS: 3, 新 RS: 2
旧 RS: 2, 新 RS: 2
...
旧 RS: 0, 新 RS: 4Deployment Controller 会根据 maxUnavailable 和 maxSurge 控制这个节奏。
Deployment、ReplicaSet 和 revision#
Deployment 并不直接管理每个 Pod。
它通过 ReplicaSet 来管理不同版本的 Pod 模板。
一次 rollout 通常对应一个新的 ReplicaSet:
Deployment
├── ReplicaSet old: nginx:1.26
└── ReplicaSet new: nginx:1.27当镜像从 nginx:1.26 改到 nginx:1.27:
1. Deployment 发现 Pod template 变化
2. 创建新的 ReplicaSet
3. 按 rolling update 策略放大新 ReplicaSet
4. 按 rolling update 策略缩小旧 ReplicaSet
5. rollout 完成后,新 ReplicaSet 达到期望副本数查看 ReplicaSet:
kubectl get rs -l app=web查看 revision:
kubectl rollout history deployment/web
kubectl describe deployment webrevision 只在 Pod template 变化时创建。
另一个策略:Recreate#
Deployment 还有另一种策略:Recreate。
spec:
strategy:
type: Recreate它的行为更直接:
先删除所有旧 Pod;
再创建新 Pod。这会带来停机窗口,但有些场景反而需要这样:
- 应用不支持新旧版本同时运行。
- 多副本同时写同一份状态会出问题。
- 旧版本必须完全退出后,新版本才能启动。
- 开发测试环境不关心短暂停机。
所以 rollout 不一定总是 rolling update。
rollout 是发布过程;
RollingUpdate / Recreate 是 Deployment 执行发布的策略。rollout restart 是什么#
kubectl rollout restart deployment/web 经常被误解。
它不是把 Deployment “重启”成一个特殊状态,而是通过修改 Pod template 的 annotation 来触发一次新的 rollout。
效果类似:
Deployment Pod template 变化
↓
创建新 revision
↓
旧 Pod 逐步被新 Pod 替换常见用途:
- 重新读取 ConfigMap 或 Secret。
- 重新拉取同 tag 镜像。
- 让 Pod 重新建立连接。
- 触发应用进程重启。
示例:
kubectl rollout restart deployment/web
kubectl rollout status deployment/web如果应用需要优雅退出,仍然要配合:
- readinessProbe。
- preStop。
- SIGTERM 处理。
- terminationGracePeriodSeconds。
- PodDisruptionBudget。
rollout restart 只负责触发替换,不保证应用层 shutdown 一定正确。
回滚怎么理解#
回滚是 rollout 管理的一部分。
kubectl rollout undo deployment/web默认回滚到上一个 revision。
也可以指定 revision:
kubectl rollout undo deployment/web --to-revision=2回滚的本质通常是:
把 Deployment 的 Pod template 改回历史 revision 对应的模板;
再触发一次新的 rollout。注意:
- 只有保留了旧 ReplicaSet,才有回滚基础。
revisionHistoryLimit会影响可回滚历史数量。- 如果镜像 tag 是可变 tag,例如
latest,回滚不一定真的回到旧镜像内容。
生产环境建议使用不可变镜像 tag 或 digest。
排查 rollout#
常用命令:
kubectl rollout status deployment/web
kubectl rollout history deployment/web
kubectl describe deployment web
kubectl get rs -l app=web
kubectl get pod -l app=web -o wide
kubectl get events --sort-by=.metadata.creationTimestamp看 Deployment 状态:
kubectl get deployment web常见字段:
| 字段 | 含义 |
|---|---|
READY | 当前 Ready Pod 数 / 期望 Pod 数 |
UP-TO-DATE | 已经更新到新模板的 Pod 数 |
AVAILABLE | 可用 Pod 数 |
AGE | 资源存在时间 |
如果 rollout 卡住,常见原因是:
- 新镜像拉取失败。
- readinessProbe 不通过。
- 资源不足,Pod Pending。
- Deployment selector 和 template labels 不匹配。
- 应用启动失败或 CrashLoopBackOff。
- PDB、调度约束、节点资源导致替换困难。
progressDeadlineSeconds超时。
常见误区#
rolling update 等于 rollout#
不等于。
rolling update 是策略;rollout 是发布过程和管理入口。
只要 scale 就会产生 revision#
不会。
副本数变化不改变 Pod template,因此通常不产生新的 revision。
rollout restart 一定会拉新镜像#
不一定。
是否拉取镜像取决于镜像 tag、imagePullPolicy、节点缓存和运行时行为。更可靠的做法是使用明确的新 tag 或 digest。
undo 就一定安全#
不一定。
回滚只处理 Kubernetes 对象层面的模板回退。数据库 schema、外部依赖、配置变更、消息格式兼容性仍然需要应用自己保证。
小结#
可以用三句话收束:
rollout 是一次发布过程;
rolling update 是 Deployment 默认的滚动更新策略;
kubectl rollout 是观察、暂停、恢复、重启、回滚发布过程的命令集合。排查时先问:
有没有触发 rollout?
使用的是什么 strategy?
新 ReplicaSet 是否正常变大?
旧 ReplicaSet 是否正常缩小?
新 Pod 为什么没有 Ready?这样就能把“发布没成功”拆成更可定位的问题。