gitlab ci灰度发布核心是环境感知、部署路由与流量控制联动,需结合ci变量、环境标识、灰度tag、k8s标签及ingress权重,并配套可观测性与原子回滚。

GitLab CI 实现复杂环境的灰度发布,核心不在分支命名,而在流水线阶段的环境感知、部署目标路由与流量控制三者的联动。它不是“发到哪个分支就灰度”,而是“在哪个环境、对哪类流量、按什么规则分发”。
绑定明确的环境上下文,而非仅靠分支名
很多团队误以为把代码推到 canary 分支就算灰度——实际并非如此。GitLab CI 的 only 或 rules 必须结合 CI 变量 和 环境标识 来触发对应行为:
- 用
environment:name显式声明 job 所属环境(如staging、prod-canary、prod-stable) - 通过
variables注入灰度参数,例如:DEPLOY_TYPE: "canary"、TRAFFIC_WEIGHT: "10" - 禁止仅靠
only: - main区分生产部署;应配合rules判断变量:if: $CI_PIPELINE_SOURCE == "merge_request_event" && $DEPLOY_ENV == "prod-canary"
用 Git tag 标记灰度版本,解耦代码与部署状态
合并进 main 不代表可灰度,只有经过预发验证、打上特定 tag 的构建产物才具备灰度资格:
- 推荐格式:
v2.3.0-rc1(候选发布)、v2.3.0-canary1(灰度批次) - CI 流水线中用
git describe --tags --exact-match检查当前提交是否带有效灰度 tag - 构建产物镜像或包名嵌入该 tag(如
myapp:v2.3.0-canary1),后续部署严格按 tag 拉取,避免“同分支不同 commit”的歧义
通过 Kubernetes label + Ingress 控制真实流量分发
GitLab 自身不转发流量,它驱动 K8s 集群完成灰度——关键在于部署资源的元数据与 Ingress 配置协同:
- Deployment 中为灰度版本打标:
track: canary,稳定版为track: stable(极狐 GitLab 默认识别此约定) - 使用支持权重的 Ingress(如 NGINX Ingress Controller 或 Argo Rollouts):将
canaryService 的流量权重设为 5%~30%,其余指向stable - GitLab CI 中通过 API 或 kubectl patch 更新 Ingress 的
canary-weight字段(注意:GitLab 14.5+ 已弃用 UI 权重操作,需走 GraphQL 或 kubectl)
配套可观测性与原子回滚机制
灰度不是“发出去就行”,必须能快速验证、及时止损:
- 每个灰度 job 成功后,自动调用健康检查接口并写入
deploy.log(含时间、tag、节点列表、HTTP 状态码) - 回滚脚本不依赖 git checkout,而是基于已存的稳定镜像 tag 或部署目录做原子切换(如
ln -sfn /opt/app-v2.2.0 /opt/current) - 集成 Prometheus + Grafana,在流水线页面嵌入关键指标卡片(错误率、P95 延迟),失败自动触发 rollback job











