Skip to content

蓝绿与金丝雀发布

Deployment 原生滚动更新适合常规发布,但它不等于蓝绿部署,也不等于金丝雀发布。蓝绿强调两套完整版本快速切流,金丝雀强调按比例放小流量并观察指标。

三种发布方式的本质区别

方式核心动作适合场景
滚动更新新旧 Pod 分批替换常规无状态服务
蓝绿部署两套环境并存,Service 或入口一次切换需要秒级回退的服务
金丝雀发布小比例流量进新版本,观察后逐步放大风险较高、需要灰度验证的发布

Deployment rolling update 适合做默认发布方式。涉及接口改动、依赖变更、核心链路时,金丝雀或蓝绿更安全。

Service selector 蓝绿

蓝绿部署可以用两套 Deployment,Service 通过 label 控制指向哪套:

yaml
# blue Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-blue
  namespace: demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
      color: blue
  template:
    metadata:
      labels:
        app: web
        color: blue
    spec:
      containers:
        - name: web
          image: harbor.example.com/demo/web:v1.0.0
---
# green Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-green
  namespace: demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
      color: green
  template:
    metadata:
      labels:
        app: web
        color: green
    spec:
      containers:
        - name: web
          image: harbor.example.com/demo/web:v1.1.0

Service 初始指向 blue:

yaml
apiVersion: v1
kind: Service
metadata:
  name: web
  namespace: demo
spec:
  selector:
    app: web
    color: blue  # 切换时改成 green
  ports:
    - port: 80
      targetPort: 8080

切流和回滚只是修改 Service selector,速度很快:

bash
kubectl -n demo patch svc web \
  -p '{"spec":{"selector":{"app":"web","color":"green"}}}'

# 回滚
kubectl -n demo patch svc web \
  -p '{"spec":{"selector":{"app":"web","color":"blue"}}}'

切流是瞬间的——新版本容量、缓存是否预热、数据库是否兼容、长连接如何处理,切换前就要确认好。

Gateway API 金丝雀

Gateway API 的 HTTPRoute 支持权重转发,金丝雀发布可以按比例切流:

yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: web
  namespace: demo
spec:
  parentRefs:
    - name: main-gateway
      namespace: gateway-system
  hostnames:
    - web.example.com
  rules:
    - backendRefs:
        - name: web-v1
          port: 80
          weight: 90  # 90% 流量到旧版本
        - name: web-v2
          port: 80
          weight: 10  # 10% 流量到新版本

逐步放量时调整 weight 的值。观察窗口里至少看:5xx 比例、P95/P99 延迟、业务错误日志、下游数据库和缓存连接数。

Ingress 注解灰度

一些 Ingress Controller 支持金丝雀注解,比如 ingress-nginx 的 canary annotation。这套方式依赖控制器私有实现,迁移成本高:

yaml
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"

Ingress API 已经 frozen,新功能进入 Gateway API。社区维护的 ingress-nginx 已于 2026 年 3 月退役。旧集群如果依赖大量 Nginx 注解,迁移前先列出注解清单,再找 Gateway API 或目标控制器的对应能力。

Argo Rollouts

Argo Rollouts 把蓝绿、金丝雀、暂停、自动分析做成控制器,发布过程可声明、可暂停、可回滚、可接指标分析:

yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: web
  namespace: demo
spec:
  replicas: 4
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: harbor.example.com/demo/web:v1.1.0
  strategy:
    canary:
      steps:
        - setWeight: 10
        - pause: {duration: 5m}
        - setWeight: 50
        - pause: {duration: 10m}
        - setWeight: 100
bash
kubectl argo rollouts get rollout web -n demo -w
kubectl argo rollouts promote web -n demo
kubectl argo rollouts abort web -n demo

核心服务做灰度时,Argo Rollouts 比手工改 Service 或 HTTPRoute 权重更稳——发布过程受控制器约束,不是操作者每次看情况手动调。

金丝雀发布的观察指标

指标说明
5xx 比例新版本是否产生服务端错误
4xx 异常变化路由、鉴权、参数兼容问题
P95/P99 延迟性能回退
Pod 重启和 OOM运行时稳定性
应用错误日志业务异常
下游连接数MySQL、Redis、MQ 是否被新版本打满

发布复盘里要写清楚镜像 tag、流量比例、观察时间、指标变化、是否回滚。"灰度正常"四个字没有排查价值。