滚动更新与回滚
上线新版本如果一次性替换所有 Pod,任何问题都会瞬间放大;直接停服升级更不可接受。Deployment 默认采用滚动更新(RollingUpdate):分批替换 Pod,边起新边删旧,整个过程服务不中断,出问题还能一键回滚到历史版本。
更新策略
Deployment 的 strategy 支持两种:
| 策略 | 行为 | 适用场景 |
|---|---|---|
| RollingUpdate | 逐步替换,先起新的再删旧的(默认) | 无状态服务、追求不中断 |
| Recreate | 先删光所有旧 Pod 再创建新的 | 必须一次性切换、可接受短暂中断 |
maxSurge 与 maxUnavailable
滚动更新的节奏由两个参数控制(默认都是 25%):
- maxSurge:更新期间允许超出期望副本数的最大 Pod 数,值越大新 Pod 起得越快。
- maxUnavailable:更新期间允许不可用的最大 Pod 数,控制旧 Pod 下线速度。
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多比期望多 1 个 Pod
maxUnavailable: 1 # 最多允许 1 个不可用
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: myapp:1.0 # 旧版本镜像
发起更新
改镜像或改配置后 apply,触发新 ReplicaSet 滚动替换:
kubectl set image deployment/myapp app=myapp:1.1 # 直接改镜像 tag
kubectl rollout status deployment/myapp # 等待完成
# 输出:deployment "myapp" successfully rolled out
kubectl rollout history deployment/myapp # 查看发布历史与版本号
回滚
新版有问题时立即回滚,无需手动改回镜像:
kubectl rollout undo deployment/myapp # 回滚到上一版本
kubectl rollout undo deployment/myapp --to-revision=1 # 回滚到指定版本
kubectl rollout history deployment/myapp --revision=1 # 查看某版本细节
暂停与恢复
用于金丝雀式发布:先暂停让部分新 Pod 接受验证,确认无误再继续:
kubectl rollout pause deployment/myapp # 暂停,后续变更不触发
kubectl rollout resume deployment/myapp # 恢复滚动
与就绪探针配合实现无损发布
滚动更新要「无损失」必须配合就绪探针:新 Pod 就绪后才进入 Service 收流量,未就绪的新 Pod 不会被打流,从而保证替换过程请求不中断。镜像版本回滚的完整步骤示例:
kubectl set image deployment/myapp app=myapp:1.2 # 发布 1.2
kubectl rollout status deployment/myapp
kubectl rollout undo deployment/myapp # 1.2 有问题,回滚到 1.1
kubectl rollout status deployment/myapp # 回滚完成即恢复服务
注意:readiness 探针没配好、镜像仓库拉取慢、新版本启动即崩溃,都会让滚动卡住或来回震荡;卡住时用 kubectl rollout status 观察,配合 describe 看事件定位。
小结:Deployment 默认 RollingUpdate,用 maxSurge/maxUnavailable 控制替换节奏;rollout status 看进度、history 查版本、undo 秒级回滚、pause/resume 掌控节奏;配上就绪探针即可实现不停服的无损发布。