
持续交付:蓝绿部署、金丝雀发布与滚动更新
零停机部署可最小化风险并实现快速交付。
蓝绿部署
维护两个相同的生产环境;在它们之间切换流量。
# Kubernetes 蓝绿部署与服务选择器
# 蓝色部署(当前活跃)
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-blue
spec:
replicas: 3
selector:
matchLabels:
app: api
version: blue
template:
metadata:
labels:
app: api
version: blue
spec:
containers:
- name: api
image: myapp:1.0.0
# 绿色部署(新版本)
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-green
spec:
replicas: 3
selector:
matchLabels:
app: api
version: green
template:
metadata:
labels:
app: api
version: green
spec:
containers:
- name: api
image: myapp:2.0.0
---
# 服务 - 通过更新选择器切换
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector:
app: api
version: blue # 改为 'green' 以切换
ports:
- port: 80
targetPort: 3000
# 将流量切换到绿色环境
kubectl patch service api-service -p '{"spec":{"selector":{"version":"green"}}}'
# 如果出现问题,立即回滚
kubectl patch service api-service -p '{"spec":{"selector":{"version":"blue"}}}'

金丝雀发布
逐步将流量切换到新版本。
# Argo Rollouts 金丝雀
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api-rollout
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 10 # 10% 流量到新版本
- pause: { duration: 10m }
- setWeight: 30
- pause: { duration: 10m }
- setWeight: 50
- pause: { duration: 10m }
- setWeight: 100
analysis:
templates:
- templateName: success-rate
startingStep: 1

滚动更新(Kubernetes 默认)
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 更新期间最大不可用 Pod 数
maxSurge: 1 # 更新期间最大额外 Pod 数

零停机数据库迁移
扩展-收缩模式:
1. 扩展:添加新列(可空或带默认值)
2. 部署同时写入旧列和新列的新应用版本
3. 回填:迁移现有数据
4. 收缩:删除旧列
5. 部署清理后的应用版本
-- 步骤 1:添加新列(向后兼容)
ALTER TABLE users ADD COLUMN email_normalized VARCHAR(255);
-- 步骤 3:回填
UPDATE users SET email_normalized = LOWER(email);
ALTER TABLE users ALTER COLUMN email_normalized SET NOT NULL;
-- 步骤 5:应用不再使用旧列后删除
ALTER TABLE users DROP COLUMN email;
部署健康检查
// 就绪探针 - 应用是否准备好接收流量?
app.get('/ready', async (req, res) => {
try {
await db.query('SELECT 1');
await redis.ping();
res.status(200).json({ status: 'ready' });
} catch (error) {
res.status(503).json({ status: 'not ready', error: error.message });
}
});
// 存活探针 - 应用是否存活?
app.get('/live', (req, res) => {
res.status(200).json({ status: 'alive' });
});
正确的部署策略让您自信交付——知道可以立即回滚。