18.5.1 发布策略类型:蓝绿、金丝雀、滚动与灰度

发布策略决定了版本在生产环境中的切换方式与风险控制。常见策略包括蓝绿、金丝雀、滚动与灰度。选择策略时需综合考虑业务可用性、回滚成本、资源占用与发布窗口。

文章图片

蓝绿发布(Blue/Green)
同时维护两套等价环境:蓝色(当前生产)与绿色(新版本)。新版本在绿色完成验证后,通过切换流量入口完成整体切换。
- 优点:切换迅速、回滚简单、验证充分
- 缺点:资源成本高、数据一致性需重点设计
- 适用:核心业务、变更风险高、对可用性要求极高的场景

示例:Nginx 切流(蓝绿)
文件:/etc/nginx/conf.d/app.conf

upstream app_blue {
    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
}
upstream app_green {
    server 10.0.2.10:8080;
    server 10.0.2.11:8080;
}
server {
    listen 80;
    location / {
        # 默认蓝环境
        proxy_pass http://app_blue;
    }
}

切换到绿环境(命令解释:修改代理目标并平滑重载):

sudo sed -i 's/app_blue/app_green/' /etc/nginx/conf.d/app.conf
sudo nginx -t                 # 检查配置语法
sudo systemctl reload nginx   # 平滑切换流量

回滚到蓝环境:

sudo sed -i 's/app_green/app_blue/' /etc/nginx/conf.d/app.conf
sudo systemctl reload nginx

排错要点
- nginx -t 报错:检查 upstream 名称是否匹配
- 切换后 502:检查后端端口与防火墙策略 ss -lntp | grep 8080


金丝雀发布(Canary)
先将少量流量导入新版本,观察关键指标与错误率,逐步扩大比例直至全量。
- 优点:风险可控、逐步验证
- 缺点:需要精细流量分配与监控体系
- 实现:网关/Ingress 按比例或按用户标签分流

示例:Nginx 按比例分流(简化)

upstream app {
    server 10.0.1.10:8080 weight=9;  # v1 90%
    server 10.0.2.10:8080 weight=1;  # v2 10%
}
server {
    listen 80;
    location / {
        proxy_pass http://app;
    }
}

命令解释
- weight 控制权重分配,9:1 表示约 90%:10%
- systemctl reload nginx 可热加载不丢连接

排错要点
- 分流比例不生效:检查是否启用了 ip_hash 等固定会话算法
- 指标异常:对接 Prometheus/日志告警触发回滚


滚动发布(Rolling)
分批替换实例,新旧版本共存,逐步替换至全部完成。
- 优点:资源占用较低、持续可用
- 缺点:发布期间版本共存,需考虑兼容性
- 关键:无状态设计、向后兼容、数据库变更分步执行

示例:Kubernetes 滚动更新
文件:deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1      # 允许多启动1个新实例
      maxUnavailable: 1 # 最多1个不可用
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: registry.local/web:v2
        ports:
        - containerPort: 8080

更新与观察(命令解释写在注释):

kubectl apply -f deploy.yaml                 # 应用新版本
kubectl rollout status deploy/web            # 观察滚动进度
kubectl get pods -l app=web -o wide           # 查看新旧实例

回滚:

kubectl rollout undo deploy/web              # 回滚到上个版本

排错要点
- 滚动卡住:kubectl describe deploy/web 查看事件
- 新版本启动失败:kubectl logs pod_name 分析启动日志


灰度发布(Gray Release)
按特定用户群或业务维度发布新版本,强调用户策略(VIP、地区、租户)。
- 优点:精准控制影响范围
- 缺点:需要完善的用户路由与版本标识机制
- 实现:用户标签、租户隔离、功能开关(Feature Flag)

示例:基于 Header 灰度路由(Nginx)

map $http_x_user_group $backend {
    default     app_blue;
    canary      app_green;
}
upstream app_blue { server 10.0.1.10:8080; }
upstream app_green { server 10.0.2.10:8080; }

server {
    listen 80;
    location / {
        proxy_pass http://$backend;
    }
}

测试:

curl -H "X-User-Group: canary" http://example.com/health

Jenkins 中的落地要点(示例 Pipeline)

pipeline {
  agent any
  stages {
    stage('Deploy to Green') {
      steps {
        sh 'kubectl apply -f deploy-green.yaml'
        sh 'kubectl rollout status deploy/web-green'
      }
    }
    stage('Smoke Test') {
      steps {
        sh 'curl -f http://green.example.com/health'
      }
    }
    stage('Switch Traffic') {
      steps {
        input message: '是否切换到绿环境?'
        sh "ssh nginx 'sudo sed -i s/app_blue/app_green/ /etc/nginx/conf.d/app.conf && sudo systemctl reload nginx'"
      }
    }
  }
  post {
    failure {
      sh "ssh nginx 'sudo sed -i s/app_green/app_blue/ /etc/nginx/conf.d/app.conf && sudo systemctl reload nginx'"
    }
  }
}

命令解释
- kubectl rollout status:确认滚动过程是否完成
- input:人工审批,控制切流
- post failure:失败自动回滚


策略选择与组合建议
- 低风险、小变更:滚动发布
- 高风险、大变更:蓝绿或金丝雀
- 精细化控制:灰度 + 金丝雀
- 可观测性要求:必须具备实时监控、日志与告警联动


练习
1. 使用 Nginx 配置蓝绿切换,验证切流前后 /health 返回版本号不同。
2. 在 Kubernetes 中设置 maxSurge=1maxUnavailable=0,观察滚动过程。
3. 实现 Header 灰度路由,并通过 curl 验证不同用户组命中不同版本。