Blue-Green和Canary deploy
蓝绿色和金丝雀
1)挑战和关键想法
Blue-Green和Canary是不间断发布的策略,可降低实施风险:- Blue-Green:保持两个并行版本(Blue-active,Green-new),以原子方式切换流量。快速回滚→立即返回Blue。
- 金丝雀:分阶段包括新版本(1%→ 5%→ 25%→ 50%→ 100%),监视SLO度量标准,并在降解时停止/回滚。
一般原则:将"人工制品交付"与"交通启用"分开,并使观察力+回滚自动化。
2)什么时候选择
Blue-Green适合以下情况:- 需要即时切换(刚性RTO),简单的无状态服务;
- 有严格的发布/冻结窗口和可理解的烟雾检查;
- 保持长期双容量非常昂贵-但可以短暂地保持。
- 复杂的变化,需要对实际流量进行分阶段验证;
- 有成熟的遥测(SLO,业务指标),自动启动的可能性;
- 限制病变半径(fintech/iGaming流)是至关重要的。
组合模式:通过金丝雀阶段推出绿色并切换到绿色(蓝绿色作为框架,金丝雀作为交通运输方法)。
3)流量路由体系结构
开关/分流选项:1.L4/L7平衡器(ALB/NLB,Cloud Load Balancer)是加权目标组。
2.API 网关/WAF是跨版本,标题,Cookie,地区的路线/重量。
3.Service Mesh (Istio/Linkerd/Consul)-分布百分比,断线注射,定时器/中继器/限制。
4.Ingress/NGINX/Envoy-上游权重和属性路由。
5.Argo Rollouts/Flagger是操作员-控制器,自动进展,与Prometheus/New Relic/Datadog集成。
4) Kubernetes: 实用模板
4.1 Blue-Green(通过服务选择器)
Два Deployment: `app-blue` и `app-green`.
一个带有选择器的Service 'app-svc'到所需的"版本"。
yaml apiVersion: apps/v1 kind: Deployment metadata: { name: app-green, labels: { app: app, version: green } }
spec:
replicas: 4 selector: { matchLabels: { app: app, version: green } }
template:
metadata: { labels: { app: app, version: green } }
spec:
containers:
- name: app image: ghcr. io/org/app:1. 8. 0 apiVersion: v1 kind: Service metadata: { name: app-svc }
spec:
selector: {app: app, version: blue} # ← switch to green - change ports: [{port: 80, targetPort: 8080}]
切换-选择器(或标签)与受控排版的原子交换。
4.2 Canary (Istio VirtualService)
yaml apiVersion: networking. istio. io/v1beta1 kind: VirtualService metadata: { name: app }
spec:
hosts: ["app. example. com"]
http:
- route:
- destination: { host: app. blue. svc. cluster. local, subset: v1 }
weight: 90
- destination: { host: app. green. svc. cluster. local, subset: v2 }
weight: 10
在台阶上改变"重量";在DestinationRule上添加retry, timeout, outlier检测器。
4.3 Argo Rollouts(自动金丝雀运行)
yaml apiVersion: argoproj. io/v1alpha1 kind: Rollout metadata: { name: app }
spec:
replicas: 6 strategy:
canary:
canaryService: app-canary stableService: app-stable steps:
- setWeight: 5
- pause: {duration: 300} # 5 min observation
- analysis:
templates:
- templateName: slo-guard
- setWeight: 25
- pause: { duration: 600 }
- analysis:
templates: [{ templateName: slo-guard }]
- setWeight: 50
- pause: {}
trafficRouting:
istio:
virtualService:
name: app routes: ["http-route"]
模板分析与度量相关(请参见下文)。
5)SLO门和自动回滚
受保护的度量(示例):- 技术:"p95_latency","5xx_rate","error_budget_burn","CPU/Memory throttling"。
- 杂货店:"CR(存款)","付款成功","评分","ARPPU"(在冷窗上)。
- 如果"5xx_rate"是新版本>0。5%在10分钟内-pause和rollback。
- 如果"p95_latency" ↑>基本后退的20%。
- 如果金丝雀促销活动正在进行,但预算SLO被烧毁>2%/小时-保持。
yaml apiVersion: argoproj. io/v1alpha1 kind: AnalysisTemplate metadata: { name: slo-guard }
spec:
metrics:
- name: http_5xx_rate interval: 1m successCondition: result < 0. 005 provider:
prometheus:
address: http://prometheus. monitoring:9090 query:
sum(rate(http_requests_total{app="app",status=~"5.."}[5m])) /
sum(rate(http_requests_total{app="app"}[5m]))
6)数据和兼容性(疼痛的最常见原因)
使用expand → migrate → contract策略:- Expand:添加新的无效列/索引,支持这两个方桉。
- Migrate:双重写作/阅读,后退。
- 合同:100%流量退出后删除旧字段/代码。
- 事件/队列:翻转付费负载(v1/v2),支持idempotency。
- 缓存/会话:验证密钥;确保格式兼容性。
7)与CI/CD和GitOps的集成
CI:组装单个工件(构建一个),映像签名,SBOM,测试。
CD:通过周围环境宣传文物;蓝绿色/金丝雀由宣言管理。
GitOps: merge MR →控制器(Argo CD/Flux)应用权重/选择器。
Environments/Approvals: for prod steps-手动门+审核解决方桉。
8)NGINX/Envoy和云LB: 快速示例
8.1 NGINX (apstrim重量)
nginx upstream app_upstream {
server app-blue:8080 weight=90;
server app-green:8080 weight=10;
}
server {
location / { proxy_pass http://app_upstream; }
}
8.2 AWS ALB (Weighted Target Groups)
TG-Blue: 90, TG-Green: 10 →通过IaC/CLI改变重量。
将CloudWatch-alerts引入自动滚装脚本(重量变化为0/100)。
9)安全性和合规性
版本之间的零信任:区分秘密/滚动加密密钥。
Policy-as-Code:禁止丢弃未签名的图像,"不最新"。
秘密和伪装作为版本文物;回滚包括configs回滚。
审计:谁在举重/切换选择器时,用什么滴答声。
10)成本和容量
Blue-Green在发布期间需要双重动力→计划一个窗口。
金丝雀可以延伸更长的时间→遥测/监视的成本,两个版本的并行内容。
优化:通过HPA/VPA自动计算,Blue-Green短窗口,"重型"服务的夜间发布。
11)回滚(runbook)
1.冻结推广(pause)。
2.将绿色重量减至0%(金丝雀)/将选择器返回蓝色(蓝色绿色)。
3.检查:错误/潜伏期恢复为基线,排水化合物。
4.打开事件,收集文物(标志,路线,指标比较)。
5.舞台上的fix/reprode,赶走烟雾,重新开始进度。
12)反模式
在stage和prod之间重新组合工件(违反"build once")。
没有SLO/度量的"聋人"金丝雀是形式而不是防御。
没有幻灯片:发布被迫立即包括100%的行为。
不良的健康检查/生活→"扎根"的垫子和虚假的稳定性。
DB的"向前"兼容性:转换时合同中断。
可变图像标签/"最新"。
13)实施清单(0-45天)
0-10天
选择服务策略:B/G、Canary或组合。
启用映像签名,健康检查,就绪样本,"no latest"。
准备SLO(latency/error rate/业务指标)行列板。
11-25天
自动化重量(Istio/Argo Rollouts/ALB重量)。
配置分析模板、异形和自动滚回。
将清单模板化(Helm/Kustomize),与GitOps集成。
26-45天
为DB实施expand-migrate-contract策略。
用旗帜覆盖关键的杀手开关浮动。
举行"游戏日":模拟回滚和事件。
14)成熟度量
通过Blue-Green/Canary发行的%(目标>90%)。
平均切换/回滚时间(目标<3分钟)。
在SLO上自动停止发布的份额(并且没有事件)。
遥测(traces/logs/metrics)服务覆盖率>95%。
根据expand-migrate-Contract模式的DB迁移比例超过90%。
15)应用程序: 策略模板和piplines
OPA(禁止未签名的图像)
rego package admission. image
deny[msg] {
input. request. kind. kind == "Deployment"
some c img:= input. request. object. spec. template. spec. containers[c].image not startswith(img, "ghcr. io/org/")
msg:= sprintf("Image not from trusted registry: %v", [img])
}
金丝雀的Helm-values(简化)
yaml canary:
enabled: true steps:
- weight: 5 pause: 300
- weight: 25 pause: 600
- weight: 50 pause: 900 sloGuards:
max5xxPct: 0. 5 maxP95IncreasePct: 20
GitHub Actions-重量推广(伪)
yaml
- name: Promote canary to 25%
run: kubectl patch virtualservice app \
--type=json \
-p='[{"op":"replace","path":"/spec/http/0/route/1/weight","value":25}]'
16)结论
蓝绿色和金丝雀不是相互排斥的,而是互补的策略。将它们构建在签名工件、SLO可观察性、自动门和GitOps控制之上。将交付与启用分开,保持快速回滚和迁移纪律-发布将变得可预测、安全和快速。