金丝雀发布
将一小部分流量导向新版本,按指标阶梯放量或自动回滚;适合与功能开关、服务网格或 Ingress 权重配合,由 Agent 生成阶段化策略。
SKILL 应定义初始比例、每阶段最短观察时间与晋升条件(错误率、超时、业务转化),以及「一票否决」指标(如支付失败突增);并说明金丝雀实例或 Pod 的标识方式、日志与 trace 中的版本标签,便于对比基线。
与蓝绿区别:金丝雀强调渐进与可编程门禁;Agent 应提醒长连接、缓存命中偏差与地理流量不均对结论的干扰。回滚优先通过权重归零或开关,再考虑整包回退。
- 放量前确保监控与告警已按新版本打标或分桶。
- 人工批准节点:全量前需谁确认、依据哪些 dashboard。
金丝雀流水线(部署 → 切分 → 观察)
[ 构建 / 部署 canary 副本 ]
│
▼
┌─────────────┐ 初始权重:1%~5%(或按用户分桶)
│ 流量切分 │──── 基线 vs canary:同路由规则、可区分版本标签
└─────────────┘
│
▼
┌─────────────┐ 窗口:每阶最短观察时间 + SLO 对比
│ 指标门禁 │──── 晋升:阶梯提权;否决:自动回滚或权重归零
└─────────────┘
│
▼
┌─────────────┐ 全量前:人工批准 + 最终 dashboard 截图 / 记录
│ 全量或回滚 │──── Runbook:谁执行、如何验证恢复
└─────────────┘
每一阶结束前对比「同口径」指标:按版本、按路由、按租户分桶,避免把全局噪声当成 canary 信号。
流量切分与实现要点
切分可在七层(Ingress / API 网关权重)、数据面(服务网格 VirtualService)、或应用内(按 user id 哈希的稳定分桶)。Agent 应在 SKILL 中写明「单一控制面」,避免多处权重叠加导致实际比例不可预期。
常见实现
- Ingress / Gateway:按权重或 header 路由到 canary Service
- Mesh:subset + 百分比或匹配规则
- 特性开关:按 cohort 打开新逻辑,与部署 canary 可组合
一致性注意
- 粘性会话:同用户应落在同一版本,除非显式「打散」策略
- 长连接 / WebSocket:提权后旧连接可能仍走旧版,需单独策略
- CDN / 边缘缓存:静态资源版本号与 API 契约对齐
# Nginx Canary 流量分配配置(按百分比)
# /etc/nginx/conf.d/canary.conf
split_clients "${remote_addr}${http_user_agent}" $canary_backend {
5% canary; # 5% 流量路由到金丝雀
* stable; # 95% 保持稳定版本
}
upstream stable { server stable.internal:8080; }
upstream canary { server canary.internal:8080; }
server {
location /api/ {
proxy_pass http://$canary_backend;
}
}
# ─── 按 Header 路由(内测人员强制使用金丝雀)─────────────────────
# map $http_x_canary $canary_route {
# "true" canary;
# default $canary_backend; # 其余走百分比逻辑
# }
# curl -H 'X-Canary: true' https://api.example.com/api/v1/test
# 适合 QA / 内部测试人员强制体验新版本
指标门禁与回滚
为每一阶定义「晋升条件」与「立即回滚条件」。前者多为相对基线的变化(如错误率相对 uplift、P99 增幅上限);后者为绝对红线(支付失败率、致命日志条数、饱和度)。
- 相对门禁:canary 桶内错误率 ≤ 基线 + ε,或实验组转化率不低于对照 − δ。
- 绝对门禁:5xx 比例、超时率、队列积压、熔断次数低于阈值。
- 样本量:低流量服务需更长窗口或更大初始比例,避免方差误判。
- 自动化:分析服务或 Pipeline 读取指标 API,失败则调 API 将权重置 0 或触发 Argo Rollback。
# Prometheus 指标门禁查询示例(CI/CD Pipeline 中调用)
# 1. Canary 错误率 vs 基线(相对门禁)
CANARY_ERR=$(curl -sf "http://prometheus:9090/api/v1/query" \
--data-urlencode 'query=rate(http_requests_total{version="canary",status=~"5.."}[5m]) \
/ rate(http_requests_total{version="canary"}[5m])' \
| jq -r '.data.result[0].value[1]')
STABLE_ERR=$(curl -sf "http://prometheus:9090/api/v1/query" \
--data-urlencode 'query=rate(http_requests_total{version="stable",status=~"5.."}[5m]) \
/ rate(http_requests_total{version="stable"}[5m])' \
| jq -r '.data.result[0].value[1]')
# 门禁判断:Canary 错误率不得超过基线 1.5 倍
THRESHOLD=$(echo "$STABLE_ERR * 1.5" | bc -l)
if (( $(echo "$CANARY_ERR > $THRESHOLD" | bc -l) )); then
echo "门禁失败:Canary err=$CANARY_ERR > threshold=$THRESHOLD,触发自动回滚"
kubectl argo rollouts abort myapp-rollout
exit 1
fi
echo "门禁通过:Canary=$CANARY_ERR Stable=$STABLE_ERR ✓"
# Argo Rollouts Canary 配置示例(rollout.yaml)
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp-rollout
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 5 # 阶段 1:5%
- pause: {duration: 15m} # 观察 15 分钟
- analysis: # 自动指标分析
templates:
- templateName: success-rate
- setWeight: 25 # 阶段 2:25%
- pause: {duration: 30m}
- setWeight: 100 # 全量
canaryMetadata:
labels:
version: canary
stableMetadata:
labels:
version: stable
selector:
matchLabels:
app: myapp
「一票否决」指标应与业务共同定义;技术类 SLO 与业务类 KPI 同时异常时,默认优先保护收入与用户信任。
阶段占比计算器
根据起始比例、目标比例、阶段数与曲线类型,生成每阶的累计 canary 占比与本阶新增流量占比(相对总流量),便于写入 Runbook 或自动化提权脚本。
| 阶段 | 累计 canary % | 本阶新增 % |
|---|
数值保留一位小数;若起始 ≥ 目标将提示调整。指数曲线需起始 ≥ 0.01%,否则按线性计算。复制后可粘贴到表格或脚本;实际网格/Ingress 请再按厂商 API 换算为权重或副本比例。
---
name: canary-release
description: 金丝雀阶段化放量、指标门禁与自动回滚
version: 2.0
---
# 流量切分(单一控制面)
- Nginx split_clients:5% canary + 95% stable
- Header 路由:X-Canary: true 强制走金丝雀(内测)
- Argo Rollouts:setWeight 5 → 25 → 100
# 指标门禁(每阶晋升前检查)
- 晋升条件:canary 错误率 ≤ stable × 1.5,P99 ≤ stable × 1.2
- 一票否决:支付失败率 > 0.1%,或 FATAL 日志 > 5 条/min
- 样本窗口:至少 15 min 且请求量 > 1000 次
# Argo Rollouts 操作
- 推进:kubectl argo rollouts promote myapp-rollout
- 回滚:kubectl argo rollouts abort myapp-rollout
- 状态:kubectl argo rollouts get rollout myapp-rollout --watch
# A/B vs Canary 选择
- Canary:验证系统稳定性,关注错误率/延迟,渐进扩大
- A/B:验证用户行为假设,关注转化/留存,需统计显著性
- 可组合:用特性开关做 A/B 分桶,用 Canary 控制部署节奏