Kubernetes 部署与回滚策略
Kubernetes Deployment 是管理应用部署的核心资源,它支持声明式更新、滚动发布、版本回滚等功能,确保应用更新过程中的零停机。本文将详细讲解 Deployment 的各种更新策略、回滚操作,以及蓝绿部署和金丝雀发布的实现方法。
一、Deployment 基础配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web-app
spec:
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: web-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: web-app
version: v1
spec:
containers:
- name: web-app
image: myapp:1.0.0
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 15
periodSeconds: 20
二、更新策略
2.1 滚动更新(RollingUpdate)
默认策略,逐步替换旧版本 Pod:
- maxSurge:更新期间可以超出 replicas 的最大 Pod 数(可以是数字或百分比)。
- maxUnavailable:更新期间最大不可用 Pod 数。
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25% # 最多多出 25% 的 Pod
maxUnavailable: 25% # 最多 25% 的 Pod 不可用
设置 maxUnavailable: 0 可以保证更新期间始终有足够的 Pod 提供服务。
2.2 重建更新(Recreate)
先删除所有旧版本 Pod,再创建新版本。会造成短暂停机,适用于不支持同时运行多个版本的应用:
strategy:
type: Recreate
三、执行更新
3.1 更新镜像
# 命令行更新
kubectl set image deployment/web-app web-app=myapp:2.0.0
# 编辑 Deployment
kubectl edit deployment web-app
# 使用 YAML 文件更新
kubectl apply -f deployment-v2.yaml
3.2 记录更新原因
kubectl set image deployment/web-app web-app=myapp:2.0.0 --record
kubectl annotate deployment/web-app kubernetes.io/change-cause="升级到 v2.0.0,修复登录 bug"
3.3 监控更新过程
# 查看更新状态
kubectl rollout status deployment/web-app
# 实时监控 Pod 变化
kubectl get pods -l app=web-app -w
# 查看 ReplicaSet
kubectl get rs -l app=web-app
3.4 暂停和恢复更新
# 暂停更新
kubectl rollout pause deployment/web-app
# 进行多次修改...
kubectl set image deployment/web-app web-app=myapp:2.0.0
kubectl set resources deployment/web-app -c web-app --limits=cpu=300m,memory=512Mi
# 恢复更新(所有修改一次性生效)
kubectl rollout resume deployment/web-app
四、版本回滚
4.1 查看历史版本
kubectl rollout history deployment/web-app
kubectl rollout history deployment/web-app --revision=2
4.2 回滚操作
# 回滚到上一版本
kubectl rollout undo deployment/web-app
# 回滚到指定版本
kubectl rollout undo deployment/web-app --to-revision=3
4.3 保留历史版本数
spec:
revisionHistoryLimit: 10 # 保留最近 10 个版本
五、金丝雀发布
金丝雀发布(Canary Deployment)将少量流量引导到新版本,验证无误后再全量发布:
5.1 基于副本数的金丝雀
# 创建 Canary Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-canary
spec:
replicas: 1 # 1 个新版本副本
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
version: canary
spec:
containers:
- name: web-app
image: myapp:2.0.0
此时 Service 会将流量分配到旧版本的 3 个 Pod 和新版本的 1 个 Pod(约 25% 的流量到新版本)。
5.2 验证后全量发布
# 确认新版本正常后,更新主 Deployment
kubectl set image deployment/web-app web-app=myapp:2.0.0
# 删除 Canary Deployment
kubectl delete deployment web-app-canary
六、蓝绿部署
蓝绿部署同时运行两个完整的环境,通过切换 Service 的 selector 实现瞬间切换:
# Blue 环境(当前版本)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-blue
spec:
replicas: 3
selector:
matchLabels:
app: web-app
version: blue
template:
metadata:
labels:
app: web-app
version: blue
spec:
containers:
- name: web-app
image: myapp:1.0.0
---
# Green 环境(新版本)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-green
spec:
replicas: 3
selector:
matchLabels:
app: web-app
version: green
template:
metadata:
labels:
app: web-app
version: green
spec:
containers:
- name: web-app
image: myapp:2.0.0
---
# Service 指向 Blue
apiVersion: v1
kind: Service
metadata:
name: web-app
spec:
selector:
app: web-app
version: blue # 切换到 green 即完成发布
ports:
- port: 80
# 切换到 Green 环境
kubectl patch svc web-app -p '{"spec":{"selector":{"version":"green"}}}'
# 如需回滚,切回 Blue
kubectl patch svc web-app -p '{"spec":{"selector":{"version":"blue"}}}'
七、健康检查
健康检查是安全更新的关键,确保只有健康的 Pod 接收流量:
readinessProbe: # 就绪探针:决定 Pod 是否加入 Service
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
livenessProbe: # 存活探针:决定是否重启 Pod
httpGet:
path: /health
port: 80
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
startupProbe: # 启动探针:启动期间不执行其他探针
httpGet:
path: /health
port: 80
failureThreshold: 30
periodSeconds: 10
八、常见问题
更新卡住不动
kubectl rollout status deployment/web-app
kubectl describe deployment web-app
kubectl get events --sort-by='.lastTimestamp'
常见原因是新版本镜像拉取失败或健康检查不通过。
回滚后版本号混乱
每次回滚实际上会创建一个新的 revision,这是正常行为。使用 --record 或 annotation 记录每次变更原因有助于追踪。
Pod 一直处于 CrashLoopBackOff
kubectl logs deployment/web-app --previous
kubectl describe pod web-app-xxx
总结
合理的部署策略是保障应用稳定性的关键。滚动更新适合大多数场景,金丝雀和蓝绿部署适合对稳定性要求更高的生产环境。搭配 Ingress 控制器 和 ArgoCD 可以实现完整的自动化发布流程。选购搬瓦工 VPS 请参考 全部方案,使用优惠码 NODESEEK2026 享受 6.77% 折扣。