蓝绿部署和金丝雀发布是现代DevOps流程中实现零停机发布的两种核心策略。蓝绿部署通过维护两套完整环境切换流量,金丝雀发布则逐步将流量导入新版本。两者可以组合使用,在不同发布场景中平衡速度与风险。
蓝绿部署架构设计
蓝绿部署的核心思路是准备两套完全对等的生产环境——蓝色环境(当前版本)和绿色环境(新版本)。发布时将流量从蓝色环境切换到绿色环境,如果新版本出现问题,立即切回蓝色环境实现秒级回滚。
这种模式要求两套环境共享同一个数据库和存储后端,否则数据不一致会导致切换后功能异常。数据库变更需要向前兼容,新版本部署时执行的DDL不应破坏旧版本的正常运行。
蓝绿部署适用于无状态服务,有状态服务(如消息队列、缓存)需要额外的数据同步机制。
Nginx蓝绿部署配置
使用Nginx upstream实现蓝绿部署是最轻量的方案。通过修改upstream配置指向不同后端组,然后reload Nginx完成流量切换。
# /etc/nginx/conf.d/upstream-blue.conf
upstream backend_blue {
server 10.0.1.10:8080 weight=100;
server 10.0.1.11:8080 weight=100;
}
# /etc/nginx/conf.d/upstream-green.conf
upstream backend_green {
server 10.0.2.10:8080 weight=100;
server 10.0.2.11:8080 weight=100;
}
# /etc/nginx/conf.d/main.conf
# 当前指向蓝色环境
set $active_upstream backend_blue;
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://$active_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 健康检查端点
location /health {
proxy_pass http://$active_upstream/health;
}
}
切换操作脚本:
#!/bin/bash
# blue_green_switch.sh
# 用法: ./blue_green_switch.sh blue|green
TARGET=$1
CONF_FILE="/etc/nginx/conf.d/main.conf"
if [ "$TARGET" = "green" ]; then
sed -i 's/set $active_upstream backend_blue/set $active_upstream backend_green/' $CONF_FILE
elif [ "$TARGET" = "blue" ]; then
sed -i 's/set $active_upstream backend_green/set $active_upstream backend_blue/' $CONF_FILE
else
echo "Usage: $0 blue|green"
exit 1
fi
# 验证配置语法
nginx -t && nginx -s reload
# 切换后健康检查
sleep 2
curl -sf http://localhost/health || {
echo "Health check failed, rolling back..."
if [ "$TARGET" = "green" ]; then
sed -i 's/set $active_upstream backend_green/set $active_upstream backend_blue/' $CONF_FILE
else
sed -i 's/set $active_upstream backend_blue/set $active_upstream backend_green/' $CONF_FILE
fi
nginx -s reload
echo "Rolled back to previous environment"
exit 1
}
echo "Switched to $TARGET environment successfully"
金丝雀发布流量灰度
金丝雀发布的核心是逐步增加新版本的流量比例,从小范围验证到全量切换。相比蓝绿部署的”一刀切”切换,金丝雀发布提供更细粒度的流量控制,能在早期发现影响范围有限的问题。
Nginx通过upstream的weight参数实现权重灰度:
# 初始状态:100%流量到旧版本
upstream backend {
server 10.0.1.10:8080 weight=100; # 旧版本
server 10.0.2.10:8080 weight=0; # 新版本
}
# 第一步:5%流量到新版本
upstream backend {
server 10.0.1.10:8080 weight=95;
server 10.0.2.10:8080 weight=5;
}
# 第二步:20%流量
upstream backend {
server 10.0.1.10:8080 weight=80;
server 10.0.2.10:8080 weight=20;
}
# 最终:100%切换
upstream backend {
server 10.0.2.10:8080 weight=100;
}
Kubernetes金丝雀发布配置
Kubernetes环境下推荐使用Argo Rollouts或Flagger实现自动化金丝雀发布。这些工具支持基于指标自动推进或回滚,无需手动调整权重。
# argo-rollout-canary.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api-server
spec:
replicas: 10
strategy:
canary:
canaryService: api-canary
stableService: api-stable
trafficRouting:
nginx:
stableIngress: api-ingress
steps:
- setWeight: 5
- pause: { duration: 5m }
- setWeight: 20
- pause: { duration: 5m }
- setWeight: 50
- pause: { duration: 10m }
- setWeight: 80
- pause: { duration: 5m }
analysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: api-canary
selector:
matchLabels:
app: api-server
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api
image: registry.example.com/api:v2.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 1m
successCondition: result[0] >= 0.99
failureLimit: 2
provider:
prometheus:
address: http://prometheus:9090
query: |
sum(rate(http_requests_total{
service="{{args.service-name}}",
status!~"5.."
}[2m]))
/
sum(rate(http_requests_total{
service="{{args.service-name}}"
}[2m]))
蓝绿部署和金丝雀发布的选择取决于团队成熟度和业务容错能力。小团队或发布频率低的场景适合蓝绿部署,操作简单回滚快速。高频发布、大规模微服务架构适合金丝雀发布,配合自动化指标分析实现无人值守的渐进式发布。数据库变更需要单独管理,采用扩展-收缩模式(先添加新字段和新逻辑,验证无误后再删除旧字段),避免发布过程中数据库结构不一致。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/lan-lyu-bu-shu-yu-jin-si-que-fa-bu-shi-zhan-ling-ting-ji-fa/