2. Deployment滚动更新与回滚实战
Deployment 滚动更新与回滚实战
本案例使用一个可观测版本的 Web 应用镜像,通过 Deployment 的 strategy.rollingUpdate 控制替换节奏,触发一次镜像升级,观察 Pod 的替换过程,再用 kubectl rollout undo 回滚到上一版本并验证服务恢复。
1. 准备 Deployment 与滚动更新策略
先创建一个 4 副本的 Deployment,镜像使用 nginx:1.24-alpine,并显式声明滚动更新参数:maxSurge: 1 表示更新期间最多超出期望副本数 1 个 Pod,maxUnavailable: 0 表示更新期间不允许出现不可用 Pod,从而保证服务容量不下降。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-demo
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: web-demo
template:
metadata:
labels:
app: web-demo
spec:
containers:
- name: web
image: nginx:1.24-alpine
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 2
periodSeconds: 3
应用并确认初始状态:
kubectl apply -f web-demo.yaml
kubectl get deploy web-demo
kubectl get pods -l app=web-demo -o wide
此时应看到 4 个 Running 且 Ready 的 Pod,Deployment 的 READY 为 4/4,UP-TO-DATE 为 4。
2. 滚动更新过程与参数关系
滚动更新的核心是 ReplicaSet 的扩缩容接力:新版本 ReplicaSet 逐步扩容,旧版本 ReplicaSet 逐步缩容,受 maxSurge 与 maxUnavailable 约束。下图展示 4 副本、maxSurge=1、maxUnavailable=0 时的替换节奏与 Pod 数量变化。
3. 触发镜像版本更新
将镜像从 nginx:1.24-alpine 更新为 nginx:1.25-alpine,触发一次滚动更新:
kubectl set image deployment/web-demo web=nginx:1.25-alpine
kubectl rollout status deployment/web-demo
在另一个终端持续观察 Pod 替换过程:
kubectl get pods -l app=web-demo -w
预期现象:新 Pod 先创建并进入 Running/Ready,随后旧 Pod 被终止;由于 maxUnavailable=0,任意时刻 Ready 的 Pod 数不会低于 4。更新完成后,kubectl get deploy web-demo 的 UP-TO-DATE 与 AVAILABLE 均为 4。
4. 查看版本历史与回滚
查看 ReplicaSet 与 rollout 历史,确认新旧版本共存关系:
kubectl get rs -l app=web-demo
kubectl rollout history deployment/web-demo
执行回滚到上一版本:
kubectl rollout undo deployment/web-demo
kubectl rollout status deployment/web-demo
回滚后再次检查 Pod 镜像与 ReplicaSet 状态:
kubectl get pods -l app=web-demo -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
kubectl get rs -l app=web-demo
预期结果:所有 Pod 的镜像恢复为 nginx:1.24-alpine,旧 ReplicaSet 重新扩容到 4,新 ReplicaSet 缩容到 0,Deployment 的 READY 回到 4/4。
5. 验证服务恢复
由于本例尚未创建 Service,可通过临时端口转发验证应用可访问:
kubectl port-forward deployment/web-demo 8080:80
curl -I http://127.0.0.1:8080/
预期返回 HTTP/1.1 200 OK,说明回滚后的 Pod 已正常提供 HTTP 服务。若返回 502/503,应检查 Pod 是否 Ready、readinessProbe 是否通过、镜像是否拉取成功。
revisionHistoryLimit 为 10,若历史被清理或使用 kubectl apply 覆盖式更新导致模板未变化,可能无法回滚到预期版本。生产环境建议保留足够历史并记录每次变更的镜像 tag。
maxUnavailable=0 会要求集群有额外资源容纳 surge Pod;若节点资源不足,新 Pod 可能一直 Pending,滚动更新卡住。此时可适当调大 maxUnavailable 或先扩容节点。