零停机部署策略
零停机部署策略
部署策略对比
| 策略 | 停机时间 | 风险 | 复杂度 |
|---|---|---|---|
| 滚动更新 | 无 | 中 | 低 |
| 蓝绿部署 | 无 | 低 | 中 |
| 金丝雀发布 | 无 | 低 | 高 |
| A/B测试 | 无 | 低 | 高 |
Kubernetes滚动更新
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多多出1个Pod
maxUnavailable: 0 # 不允许不可用
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
terminationGracePeriodSeconds: 60
containers:
- name: myapp
image: myapp:v2
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 15"]
蓝绿部署
# 蓝色版本(当前)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: myapp
image: myapp:v1
---
# 绿色版本(新)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: myapp
image: myapp:v2
---
# 服务
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
version: blue # 切换到green进行部署
ports:
- port: 80
targetPort: 8080
切换脚本
#!/bin/bash
CURRENT_VERSION=$1
NEW_VERSION=$2
echo "切换从 $CURRENT_VERSION 到 $NEW_VERSION"
# 更新Service
kubectl patch service myapp -p "{\"spec\":{\"selector\":{\"version\":\"$NEW_VERSION\"}}}"
# 等待新版本就绪
kubectl rollout status deployment/myapp-$NEW_VERSION
# 验证健康
kubectl exec -it deploy/myapp-$NEW_VERSION -- curl -f http://localhost:8080/health
# 如果失败,回滚
if [ $? -ne 0 ]; then
echo "健康检查失败,回滚..."
kubectl patch service myapp -p "{\"spec\":{\"selector\":{\"version\":\"$CURRENT_VERSION\"}}}"
fi
金丝雀发布
# Istio金丝雀配置
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp
http:
- route:
- destination:
host: myapp
subset: v1
weight: 90
- destination:
host: myapp
subset: v2
weight: 10
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: myapp
spec:
host: myapp
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
实践:Flagger金丝雀
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: myapp
namespace: production
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
progressDeadlineSeconds: 600
service:
port: 80
targetPort: 8080
analysis:
interval: 1m
threshold: 5
maxWeight: 50
stepWeight: 10
metrics:
- name: request-success-rate
thresholdRange:
min: 99
interval: 1m
- name: request-duration
thresholdRange:
max: 500
interval: 30s
webhooks:
- name: load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 1m -q 10 -c 2 http://myapp-canary.test/"
优雅终止
# Python示例
import signal
import sys
from flask import Flask
app = Flask(__name__)
def shutdown(signum, frame):
# 完成正在处理的请求
# 关闭数据库连接
# 通知负载均衡器
sys.exit(0)
signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)
@app.route('/healthz')
def healthz():
return 'OK', 200
最佳实践
- 配置健康检查
- 实现优雅终止
- 渐进式发布
- 监控关键指标
- 准备回滚方案
总结
零停机部署是现代应用的必备能力。通过滚动更新、蓝绿部署和金丝雀发布等策略,可以实现安全、可靠的应用更新。