金丝雀发布(Canary Release)是一种渐进式发布策略,它允许我们将新版本应用逐步推向用户,在全面推广前及时发现潜在问题。在 Kubernetes 中,我们可以通过多种方式实现金丝雀发布,本文将重点介绍基于 Ingress 流量权重 的金丝雀发布方案,并与传统的 Deployment 滚动更新 方案进行对比。

🔄 两种金丝雀发布的区别

Deployment 滚动更新金丝雀

# 通过 Deployment 的滚动更新策略控制
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 逐步增加新版本 Pod
      maxUnavailable: 0   # 保证零宕机时间

Ingress 流量权重金丝雀

# 通过 Ingress 注解实现流量控制
annotations:
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-weight: "10"  # 10% 流量到新版本

📊 两种方案对比

特性Deployment 滚动更新Ingress 流量权重
控制维度Pod 副本数量请求流量百分比
发布粒度实例级别请求级别
回滚速度较慢(需要重建Pod)快速(修改注解即可)
适用场景版本兼容性要求高A/B测试、灰度发布
资源占用同时运行两套Pod同时运行两套Pod

🏗️ 架构设计

用户访问 svc.xinxianghf.com
    ↓
Ingress Controller (流量调度中心)
    ↓ 流量按权重分配
90% → v1-svc → v1-deploy (v1.0版本)
10% → v2-svc → v2-deploy (v2.0版本)  ← 金丝雀

⚡ 实践步骤

步骤 1:创建 v1 版本应用(主版本)

[root@k8s-master01 10]# cat 18.deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 labels:
   app: v1
 name: v1-deploy
spec:
 replicas: 10
 selector:
   matchLabels:
     app: v1
 template:
   metadata:
     labels:
       app: v1
   spec:
     containers:
     - image: wangyanglinux/myapp:v1.0
       name: myapp
---
apiVersion: v1
kind: Service
metadata:
 labels:
   app: v1
 name: v1-svc
spec:
 ports:
 - name: 80-80
   port: 80
   protocol: TCP
   targetPort: 80
 selector:
   app: v1
 type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: v1.xinxianghf.com
 namespace: default
spec:
 rules:
 - host: svc.xinxianghf.com
   http:
     paths:
     - pathType: Prefix
       path: "/"
       backend:
         service:
           name: v1-svc
           port:
             number: 80

部署 v1 版本:

[root@k8s-master01 10]# kubectl apply -f 18.deployment.yaml

配置本地 DNS:

[root@k8s-master01 10]# echo "192.168.175.12 svc.xinxianghf.com" >> /etc/hosts

验证访问:
[root@k8s-master01 10]# curl svc.xinxianghf.com
# 输出:www.xinxianghf.com | hello MyAPP | version v1.0

------------------------------------------------------------------------------------------------------------------------

步骤 2:创建 v2 版本应用(金丝雀版本)

[root@k8s-master01 10]# cat 19.deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 labels:
   app: v2
 name: v2-deploy
spec:
 replicas: 10
 selector:
   matchLabels:
     app: v2
 template:
   metadata:
     labels:
       app: v2
   spec:
     containers:
     - image: wangyanglinux/myapp:v2.0
       name: myapp
---
apiVersion: v1
kind: Service
metadata:
 labels:
   app: v2
 name: v2-svc
spec:
 ports:
 - name: 80-80
   port: 80
   protocol: TCP
   targetPort: 80
 selector:
   app: v2
 type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: v2.xinxianghf.com
 namespace: default
 annotations:
   nginx.ingress.kubernetes.io/canary: "true"
   nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
 rules:
 - host: svc.xinxianghf.com
   http:
     paths:
     - pathType: Prefix
       path: "/"
       backend:
         service:
           name: v2-svc
           port:
             number: 80

部署金丝雀版本:
[root@k8s-master01 10]# kubectl apply -f 19.deployment.yaml

此时,Ingress Nginx 控制器会将 10% 的流量 路由到 v2 版本。

🧪 流量分配验证

测试方法

发送 100 个请求并统计各版本响应次数:

# 发送 100 个请求
for i in {1..100}; do curl svc.xinxianghf.com >> sum; done

# 统计结果
cat sum | sort | uniq -c

命令解析

  • for i in {1..100}; do curl svc.xinxianghf.com >> sum; done

    • 循环 100 次,发送请求并将响应内容追加到 sum 文件

  • cat sum | sort | uniq -c

    • cat sum:读取文件内容

    • sort:按字母顺序排序(相同内容排在一起)

    • uniq -c:统计相邻重复行的数量

结果说明

  • 约 90% 流量(90 次请求)路由到 v1.0 版本

  • 约 10% 流量(10 次请求)路由到 v2.0 版本

  • 符合 canary-weight: "10" 的配置预期

📊 方案优势对比

特性Deployment 滚动更新Ingress 流量权重
控制精度实例级别请求级别
回滚速度分钟级秒级
资源占用逐步替换,资源占用平稳同时运行两套副本
监控粒度实例健康度请求成功率、性能指标
适用阶段版本发布A/B 测试、灰度发布

🎯 适用场景

适合 Ingress 流量权重金丝雀的场景:

  1. A/B 测试:对比不同版本的功能效果

  2. 用户体验测试:小范围验证新界面/功能

  3. 性能验证:监控新版本在真实流量下的表现

  4. 渐进式发布:从 1% → 5% → 20% → 50% → 100% 逐步放量

适合 Deployment 滚动更新的场景:

  1. 兼容性升级:数据库迁移、API 重大变更

  2. 基础设施升级:运行环境、依赖库更新

  3. 强制更新:安全补丁、紧急修复

🔧 高级配置选项

除了权重控制,Ingress 金丝雀还支持更多精细控制:

yaml

annotations:
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-weight: "10"
  # 基于 Header 的金丝雀
  nginx.ingress.kubernetes.io/canary-by-header: "canary"
  nginx.ingress.kubernetes.io/canary-by-header-value: "true"
  # 基于 Cookie 的金丝雀
  nginx.ingress.kubernetes.io/canary-by-cookie: "canary"

💡 最佳实践

  1. 监控告警:设置关键指标监控,如错误率、延迟等

  2. 渐进放量:从较小流量开始,逐步增加

  3. 快速回滚:准备好一键回滚方案

  4. 用户反馈:结合用户反馈系统,及时收集问题

  5. 多维度验证:结合日志、监控、链路追踪进行全面验证

🏁 总结

Ingress 流量权重金丝雀发布提供了精准的流量控制能力,特别适合需要精细控制发布节奏的场景。相比传统的 Deployment 滚动更新,它具有以下优势:

  • 1. 请求级别控制:精确到百分比级别的流量分配

  • 2. 快速回滚:修改注解即可完成回滚

  • 3. 灵活组合:支持权重、Header、Cookie 等多种控制方式

  • 4. 实时调整:无需重启服务即可调整流量比例

通过本文的实践,您可以轻松地在自己的 Kubernetes 集群中实现精准的金丝雀发布,为业务迭代提供更安全、更可控的发布能力。

更多推荐