Skip to content

部署策略

目录


部署策略概览

┌──────────────────────────────────────────────────────┐
│          部署策略对比                                │
├──────────────┬────────┬─────────┬───────────────────┤
│  策略        │  风险  │  速度   │  成本              │
├──────────────┼────────┼─────────┼───────────────────┤
│ 重建(Recreate)│  高    │  快     │  低               │
│ 滚动(Rolling) │  中    │  中     │  低               │
│ 蓝绿(Blue/Green)│ 低   │  快     │  高(双倍资源)     │
│ 金丝雀(Canary)│  低    │  慢     │  中               │
│ A/B测试      │  低    │  慢     │  中               │
└──────────────┴────────┴─────────┴───────────────────┘

蓝绿部署

┌────────────────────────────────────────────────────┐
│              蓝绿部署流程                          │
├────────────────────────────────────────────────────┤
│                                                    │
│  步骤1: 初始状态                                   │
│  ┌──────────┐                                     │
│  │ 负载均衡 │ ──100%──▶ 蓝环境 (v1.0)            │
│  └──────────┘                                     │
│                                                    │
│  步骤2: 部署新版本                                 │
│  ┌──────────┐                                     │
│  │ 负载均衡 │ ──100%──▶ 蓝环境 (v1.0)            │
│  └──────────┘                                     │
│                        绿环境 (v2.0) 部署中...     │
│                                                    │
│  步骤3: 切换流量                                   │
│  ┌──────────┐                                     │
│  │ 负载均衡 │ ───0%───▶ 蓝环境 (v1.0)            │
│  └──────────┘                                     │
│              └─100%──▶ 绿环境 (v2.0) ✅           │
│                                                    │
│  步骤4: 回滚 (如果需要)                            │
│  ┌──────────┐                                     │
│  │ 负载均衡 │ ──100%──▶ 蓝环境 (v1.0) ◀回滚      │
│  └──────────┘                                     │
└────────────────────────────────────────────────────┘

Kubernetes实现

yaml
# blue-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-blue
  labels:
    app: myapp
    version: blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: blue
  template:
    metadata:
      labels:
        app: myapp
        version: blue
    spec:
      containers:
      - name: app
        image: myapp:1.0
        ports:
        - containerPort: 8080

---
# green-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-green
  labels:
    app: myapp
    version: green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: green
  template:
    metadata:
      labels:
        app: myapp
        version: green
    spec:
      containers:
      - name: app
        image: myapp:2.0
        ports:
        - containerPort: 8080

---
# service.yaml - 切换版本只需修改selector
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
    version: green  # 修改这里实现切换
  ports:
  - port: 80
    targetPort: 8080

切换脚本

bash
#!/bin/bash
# blue-green-deploy.sh

# 部署绿环境
kubectl apply -f green-deployment.yaml

# 等待绿环境就绪
kubectl rollout status deployment/myapp-green

# 运行烟雾测试
curl http://myapp-green-service/health

# 切换流量到绿环境
kubectl patch service myapp -p '{"spec":{"selector":{"version":"green"}}}'

echo "✅ 部署完成!蓝环境保留10分钟以备回滚"

# 10分钟后删除蓝环境
sleep 600
kubectl delete deployment myapp-blue

金丝雀发布

┌────────────────────────────────────────────────────┐
│              金丝雀发布流程                        │
├────────────────────────────────────────────────────┤
│                                                    │
│  阶段1: 5% 流量                                    │
│  ┌──────────┐                                     │
│  │ 负载均衡 │ ── 95% ──▶ v1.0 (稳定版)           │
│  └──────────┘                                     │
│              └─  5% ──▶ v2.0 (金丝雀) 🐤          │
│                                                    │
│  阶段2: 观察指标,逐步增加                          │
│  ┌──────────┐                                     │
│  │ 负载均衡 │ ── 50% ──▶ v1.0                    │
│  └──────────┘                                     │
│              └─ 50% ──▶ v2.0                      │
│                                                    │
│  阶段3: 全量切换                                   │
│  ┌──────────┐                                     │
│  │ 负载均衡 │ ──100% ──▶ v2.0 ✅                 │
│  └──────────┘                                     │
└────────────────────────────────────────────────────┘

Istio实现

yaml
# virtualservice.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: myapp
spec:
  hosts:
  - myapp
  http:
  - match:
    - headers:
        canary:
          exact: "true"
    route:
    - destination:
        host: myapp
        subset: v2
      weight: 100
  - route:
    - destination:
        host: myapp
        subset: v1
      weight: 95
    - destination:
        host: myapp
        subset: v2
      weight: 5  # 金丝雀流量

---
# destinationrule.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: myapp
spec:
  host: myapp
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

自动化金丝雀

python
# canary_controller.py
import time
import requests
from kubernetes import client, config

class CanaryController:
    def __init__(self):
        config.load_kube_config()
        self.api = client.CustomObjectsApi()

    def promote_canary(self, stages=[5, 25, 50, 100]):
        """渐进式金丝雀发布"""

        for weight in stages:
            # 更新流量权重
            self.update_traffic_weight(weight)

            # 观察10分钟
            time.sleep(600)

            # 检查指标
            metrics = self.check_metrics()

            if not metrics['healthy']:
                print(f"❌ 指标异常,回滚到0%")
                self.update_traffic_weight(0)
                return False

            print(f"✅ {weight}% 流量健康,继续推进")

        print("🎉 金丝雀发布完成!")
        return True

    def check_metrics(self):
        """检查关键指标"""
        # 错误率
        error_rate = self.query_prometheus(
            'sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))'
        )

        # 延迟
        p99_latency = self.query_prometheus(
            'histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))'
        )

        return {
            'healthy': error_rate < 0.01 and p99_latency < 1.0
        }

总结

选择部署策略考虑因素:

  1. 风险容忍度
  2. 资源成本
  3. 回滚速度
  4. 业务影响

推荐:生产环境使用蓝绿或金丝雀

💬 讨论

使用 GitHub 账号登录后即可参与讨论

基于 MIT 许可发布