讲解
更新应用的朴素做法是「全部停掉、换版本、全部启动」——中间有服务真空期。Deployment 的默认更新策略 RollingUpdate 解决这个:逐步用新版本 Pod 替换旧版本,全程保持服务可用。两个参数控制节奏:maxSurge(更新期间最多比期望副本多出几个,可以是数字或百分比,默认 25%)和 maxUnavailable(最多允许几个不可用,默认 25%)。以 4 副本默认值为例:先起 1 个新 Pod(surge),新 Pod 就绪后杀 1 个旧的,如此滚动,任何时刻可用副本不少于 3。
每次更新 Pod 模板,Deployment 生成一个新 ReplicaSet,旧的保留——这就是回滚的本钱。kubectl rollout history 看修订历史,kubectl rollout undo 一键回到上一版(实际是把旧 ReplicaSet 重新扩起来),加 --to-revision=N 回到指定版本。回滚不是什么特殊机制,就是「再滚动更新一次,目标是旧模板」,所以同样平滑。
更新的触发方式:声明式是改 YAML 里镜像再 apply(推荐,配置可入版本库);命令式是 kubectl set image deployment/xxx 容器名=新镜像,适合临时操作。发布卡住时 kubectl rollout status 看进度;新版有 bug 起不来时滚动会自动停住(新 Pod 不就绪就不杀旧的)——这是 RollingUpdate 自带的保险丝,配合 readiness 探针效果更佳。如需暂停发布验证,kubectl rollout pause/resume 可以冻结/恢复滚动过程。
示例
本章从一个全新部署开始(与上一章同名但独立重建,版本先固定在 nginx:1.27-alpine):
# wait: deploy/ohmydocs-verify-web
apiVersion: apps/v1
kind: Deployment
metadata:
name: ohmydocs-verify-web
spec:
replicas: 3
selector:
matchLabels:
app: ohmydocs-verify-web
template:
metadata:
labels:
app: ohmydocs-verify-web
spec:
containers:
- name: nginx
image: nginx:1.27-alpine
ports:
- containerPort: 80
命令式更新镜像到 1.28-alpine,观察滚动过程与 ReplicaSet 的更替(旧 RS 保留、缩到 0):
kubectl set image deploy/ohmydocs-verify-web nginx=nginx:1.28-alpine
kubectl rollout status deploy/ohmydocs-verify-web --timeout=180s
kubectl get rs -l app=ohmydocs-verify-web
kubectl get deploy ohmydocs-verify-web -o jsonpath='当前镜像: {.spec.template.spec.containers[0].image}'
echo
查看修订历史并一键回滚,确认镜像回到 1.27:
kubectl rollout history deploy/ohmydocs-verify-web
kubectl rollout undo deploy/ohmydocs-verify-web
kubectl rollout status deploy/ohmydocs-verify-web --timeout=180s
kubectl get deploy ohmydocs-verify-web -o jsonpath='回滚后镜像: {.spec.template.spec.containers[0].image}'
echo
常见坑
- 滚动更新卡死:新版本镜像拉不下来或探针不过,滚动会停在半途(这是保护,不是故障);rollout status 看卡在哪一步,describe pod 看具体原因。
- 回滚后 history 变化困惑:undo 本质是「把旧修订变成最新修订」,revision 编号会继续涨,别指望编号回退。
- 没有 readiness 探针的滚动:新 Pod 一起来就算「就绪」开始切流量,应用实际还没初始化完——滚动更新的安全性建立在 readiness 探针之上。
- maxUnavailable 设成 0 又没节点资源:maxSurge 0 + maxUnavailable 0 的组合需要节点有余量先起新 Pod,资源紧张时更新卡死。
小结
RollingUpdate 靠 maxSurge/maxUnavailable 平滑换版;每次模板变更生成新 ReplicaSet,rollout history/undo 实现秒级回滚;readiness 探针是滚动安全的前提。应用能多副本平滑跑了,下一章解决「怎么稳定访问这组 Pod」:Service。