K8S - 金丝雀发布实战 - Argo Rollouts 流量控制解析

一、金丝雀发布概述

1.1 什么是金丝雀发布?

金丝雀发布(Canary Release)是一种渐进式部署策略,通过逐步将生产流量从旧版本迁移至新版本,结合实时指标验证,在最小化风险的前提下完成版本迭代。其核心逻辑如下:

  • 流量分层:初始阶段仅将小比例流量(如 5%)路由至新版本,剩余流量仍由旧版本处理。

  • 指标验证:监控新版本的关键指标(成功率、延迟、错误率),确认符合预期后逐步扩大流量比例。

  • 自动化决策:基于预设阈值自动推进或回滚,降低人工干预成本。

技术价值:

  • 风险可控:异常仅影响部分用户,快速隔离问题。

  • 精准验证:结合业务指标(如交易成功率)而非单纯基础设施健康状态。

  • 资源高效:无需双版本全量部署,节省计算资源。

1.2 金丝雀发布与蓝绿发布的差异
在这里插入图片描述
金丝雀发布适合高风险迭代、核心业务认证。蓝绿发布适合简单应用快速全量发布。

二、Argo Rollouts 能力解析

接下来我们聚焦 Argo Rollouts,是如何落地金丝雀发布策略并提供增强能力的。
2.1 核心能力

1.精细化流量控制

  • 百分比权重控制:支持渐进式流量分配(如 5% → 50% → 100%),确保发布过程平滑过渡。

  • 基于请求头的精准路由:可按特定 Header(如 X-User: beta)实现灰度测试,满足特定用户群验证需求。

2.多维监控与自动化决策

  • 内置监控集成:支持与 Prometheus、Datadog 等主流监控系统无缝集成。

  • 指标阈值配置:可定义关键业务指标,(如错误率 < 1%、响应时间 < 500ms)

  • 自动回滚机制:当指标超出阈值时,自动触发回滚。

3.分阶段发布策略

可配置多步骤验证流程(示例):

steps:
  - setWeight: 20     # 第一阶段:20%流量
  - pause: {}         # 手动确认后继续
  - setWeight: 50     # 第二阶段:50%流量
  - pause: {duration: 30s}  # 自动暂停监控
  - setWeight: 100    # 全量发布

2.2 与原生 Deployment 的差异
在这里插入图片描述

三、金丝雀发布实战

使用 Argo Rollouts 搭配 Ingress-NGINX 实现金丝雀发布,实现流量按比例逐步迁移、暂停验证、自动推进的渐进式发布策略。

多维度验证目标

  • 流量按照预设比例,逐步分流至新旧版本

  • 支持通过请求 Header 实现精准流量控制

  • 通过可视化 Dashboard 实时跟踪发布状态

环境准备 可以看其他K8S基础介绍的相关文章

3.1 项目结构

canary-deploy/
├── canary-rollout.yaml # 定义金丝雀策略
├── service-stable.yaml # 稳定版 Service(全流量入口)
├── service-canary.yaml # 金丝雀版 Service(灰度流量入口)
└── ingress-nginx.yaml  # Ingress 权重路由配置

文件说明:

canary-rollout.yaml

使用 Argo Rollouts 定义金丝雀发布流程,包括流量权重控制、阶段发布和暂停机制。

service-stable.yaml

稳定版服务,默认承载全流量。

service-canary.yaml

金丝雀版服务,按权重接收灰度流量。

ingress-nginx.yaml

定义入口规则,配合 Argo Rollouts 实现流量路由与控制。

3.2 配置文件
1.Rollout 配置

canary-rollout.yaml 
核心作用:定义金丝雀发布的阶段策略、流量权重等,及与 Ingress 的联动配置。是实现渐进式流量控制的核心资源对象。
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: canary-demo
  labels:
    app: canary-demo
spec:
  replicas: 1  # 启动一个副本用于测试
  selector:
    matchLabels:
      app: canary-demo
  template:
    metadata:
      labels:
        app: canary-demo
    spec:
      containers:
        - name: canary-demo
          image: argoproj/rollouts-demo:blue  # 示例镜像,可替换为业务镜像
          imagePullPolicy: Always
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          resources:
            requests:
              memory: 32Mi
              cpu: 5m
  strategy:
    canary:                              # 金丝雀发布策略
      canaryService: service-canary      # 金丝雀服务
      stableService: service-stable      # 稳定服务
      canaryMetadata:
        labels:
          deployment: canary             # 金丝雀版本的标签
      stableMetadata:
        labels:
          deployment: stable             # 稳定版本的标签
      trafficRouting:
        nginx:
          stableIngress: canary-demo     # 关联 ingress-nginx.yaml 中的 Ingress
          additionalIngressAnnotations:
            canary-by-header: X-Canary   # 支持按 Header 精准控制流量
      steps:                             # 金丝雀发布阶段控制
        - setWeight: 20                  # 第一阶段:20% 流量进入金丝雀
        - pause: {}                      # 暂停,需要手动操作继续
        - setWeight: 50                  # 第二阶段:50% 流量
        - pause:
            duration: 30s                # 暂停 30 秒进行监控验证
        - setWeight: 100                  # 第三阶段:100% 流量
        - pause:
            duration: 30s                # 最后验证后全量切换

说明:

通过 Argo Rollouts 定义了金丝雀发布流程,包括:

每个阶段的流量比例,如 20%、50%。

阶段性暂停(手动或定时)用于人工确认或指标验证。

配置 canaryService 和 stable-Service,结合 Ingress 控制流量分流。

启用 Header(如 X-Canary)进行精细化流量控制。

2.Service 配置

设计逻辑:通过独立 Service 隔离新旧版本流量,结合 Ingress 权重控制实现渐进式迁移。

稳定版 Service
service-stable.yaml
apiVersion: v1
kind: Service
metadata:
  name: service-stable
  labels:
    app: canary-demo
spec:
  selector:
    app: canary-demo
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
金丝雀版 Service
service-canary.yaml
apiVersion: v1
kind: Service
metadata:
  name: service-canary
  labels:
    app: canary-demo
spec:
  selector:
    app: canary-demo
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http

3.Ingress 配置

ingress-nginx.yaml

核心作用:负责入口流量的转发配置,并配合 Argo Rollouts 实现动态流量切分。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-demo
  labels:
    app: canary-demo
  annotations:
    kubernetes.io/ingress.class: nginx   # 指定使用 nginx ingress
spec:
  rules:
    - host: canary.auto   # 访问域名
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service-stable   # 默认指向稳定版 Service
                port:
                  name: http

3.3 部署与验证
步骤1:初始版本部署
1.创建命名空间并进入目录

# 创建独立命名空间
kubectl create ns canary-test
cd canary-deploy/  # 进入项目目录

2.应用资源配置

# 批量应用所有配置文件(Service/Ingress/Rollout)
kubectl apply -f . -n canary-test

步骤2:验证初始部署状态

# 检查资源创建状态(确保所有资源 READY)
kubectl get rollout,svc,ingress,pods -n canary-test
输出: 资源已被正确创建

NAME                                      STATUS    AVAILABLE   AGE
rollout.argoproj.io/canary-demo          ✔ Healthy   1/1         2m

NAME                    TYPE        CLUSTER-IP      PORT(S)   AGE
service/service-canary  ClusterIP   10.96.132.45   80/TCP    2m
service/service-stable  ClusterIP   10.96.131.207  80/TCP    2m

NAME                          CLASS   HOSTS          ADDRESS        PORTS   AGE
ingress.networking.k8s.io/canary-demo   nginx   canary.auto   192.168.49.2   80      2m

NAME                              READY   STATUS    RESTARTS   AGE
pod/canary-demo-7d5f8c6c9d-abcde   1/1     Running   0          2m

步骤3:浏览器验证初始版本

获取访问入口信息
# 获取 Ingress 对外 IP 和端口(如果是云环境,使用 EXTERNAL-IP;本地集群如 minikube 使用 IP)
INGRESS_IP=$(kubectl get ingress canary-demo -n canary-test -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "访问地址: http://$INGRESS_IP"
访问网页

配置本地 hosts 文件:
127.0.0.1 canary.auto
浏览器访问:

http://canary.auto
初始页面为蓝色版本。类似如下

在这里插入图片描述

步骤4:触发金丝雀发布

模拟版本更新
# 通过镜像更新触发发布流程(从 blue 切换到 green 版本)
kubectl argo rollouts set image canary-demo \
  canary-demo=argoproj/rollouts-demo:green -n canary-test
也可直接修改 canary-rollout.yaml 中镜像版本从blue 到 green,之后通过apply命令应用到集群。

步骤5:验证金丝雀发布(第一阶段 )

1.使用 Argo Rollouts CLI 观察部署过程

# 实时观察发布状态(新开终端执行)
kubectl argo rollouts get rollout canary-demo -n canary-test --watch
输出(第一阶段暂停时):

Name:            canary-demo
Namespace:       canary-test
Status:Paused
Message:         CanaryPauseStep
Strategy:        Canary
  Step:          1/6
  SetWeight:     20
  ActualWeight:  20
Images:          argoproj/rollouts-demo:green (canary)
                 argoproj/rollouts-demo:blue (stable)

2.浏览器流量验证(第一阶段 20% 流量)

操作 1:批量请求测试分流比例

# 发送 20 次请求统计版本分布(Linux/MacOS 环境)
for i in {1..20}; do
  curl -s "http://$INGRESS_IP" -H "Host: canary.auto" | grep "Pod Image"
done | sort | uniq -c
输出: 

 16 Pod Image: argoproj/rollouts-demo:blue (stable)
  4 Pod Image: argoproj/rollouts-demo:green (canary)  # 约 20% 流量

操作2:浏览器访问 http://canary.auto

页面呈现 80% blue 方格 ,20% green 方块(新版本),类似下图:
在这里插入图片描述

操作 3:Dashboard 观测

# 启动 Argo Rollouts Dashboard(新终端执行)
kubectl argo rollouts dashboard -n canary-test
浏览器访问:http://localhost:3100,查看以下关键信息:

金丝雀发布的完整步骤以及 当前所在阶段
版本健康状态指示等

类似下图:
在这里插入图片描述

操作 4:Header 强制路由验证

# 通过 X-Canary 头强制路由到金丝雀版本
curl -s "http://$INGRESS_IP" -H "Host: canary.auto" -H "X-Canary: always" | grep "Pod Image"
输出:

Pod Image: argoproj/rollouts-demo:green (canary)

操作5:浏览器访问 http://canary.auto

页面 100% green 方块(新版本)

步骤 5:手动推进发布流程

方法1:命令
# 继续执行下一阶段(从 20% 提升至 50%)
kubectl argo rollouts promote canary-demo -n canary-test

# 观察自动执行后续步骤(30秒后进入100%阶段)
方法2Dashboard 上操作

按下 Promote 按钮,Argo Rollouts 会根据策略自动执行后续步骤,即开始进入 50%70% 流量切换等。

注:仅当 Rollout 处于 Paused 状态时,Promote 按钮才激活。

步骤 6:全量发布完成验证

流程执行到最终阶段:

# 检查最终版本状态
kubectl argo rollouts get rollout canary-demo -n canary-test
输出:全部切换到新版本 green

Name:            canary-demo
Namespace:       canary-test
Status:Healthy
Strategy:        Canary
  Step:          6/6
  SetWeight:     100
  ActualWeight:  100
Images:          argoproj/rollouts-demo:green (stable)

最终流量验证

# 发送 10 次请求确认全量切换
for i in {1..10}; do
  curl -s "http://$INGRESS_IP" -H "Host: canary.auto" | grep "Pod Image"
done
输出:

Pod Image: argoproj/rollouts-demo:green (stable)  # 全部请求

关键流程示意图

graph TD
  A[创建初始资源] --> B[触发金丝雀发布]
  B --> C{阶段1:20%流量}
  C -->|手动验证| D[人工确认后推进]
  D --> E{阶段2:50%流量}
  E -->|自动暂停30| F[监控指标检查]
  F --> G{阶段3:100%流量}
  G -->|自动暂停30| H[最终验证]
  H --> I[全量发布完成]

部署验证清单
在这里插入图片描述

步骤7:手动回滚操作

在 Dashboard 中找到目标 Rollout 资源。

点击 Actions 下拉菜单,选择 Abort and Rollback。

效果:当前的发布进程终止,并将流量切回旧版本。

四、金丝雀发布底层原理

4.1 核心机制:组件协作与流量控制
金丝雀发布的本质是由 Argo Rollouts 控制器动态协调 Ingress、Service 和 ReplicaSet 等 Kubernetes 原生资源,实现从旧版本到新版本的渐进式流量切换与灰度控制。整个过程无需手动干预,所有操作均由控制器按策略自动执行。
1.组件角色与交互
在这里插入图片描述

2.分阶段解析原理

下文以第三章 实例 为例 进行解析。

如下操作均由Argo Rollouts 控制器按策略文件自动执行,无需人为干预。

阶段1:初始状态(全流量稳定版)

  A[用户请求] --> B[Ingress]
  B --> C[service-stable]
  C --> D[旧版本Pod]

原理解析:

service-stable通过标签(如 rollouts-pod-templatehash=6f8b8d584)选择旧版本 Pod。

Ingress 默认路由规则指向 service-stable,承载 100% 流量。

阶段2:金丝雀阶段(流量渐进切换)
首先环境准备:

创建新版本 ReplicaSet(如 canary-demo-67fc7c4899)。

生成 service-canary,标签选择器指向新版本 Pod。

Ingress 动态分流 ( 如下是分流示意图)

  A[用户请求] --> B[Ingress]
  B -->|80%流量| C[service-stable]
  B -->|20%流量| D[service-canary]
  C --> E[旧版本Pod]
  D --> F[新版本Pod]

分阶段推进:

权重控制:通过调整新版本 Pod 的副本比例(如 1:4 → 20%流量)。

暂停机制:每个阶段可配置人工确认或自动等待(如 pause:{duration: 30m})。

阶段3:最终切换(全量发布)
原子化操作:

更新 service-stable的标签选择器,指向新版本 Pod。

缩容旧版本 ReplicaSet 至 0 副本。

最终状态:

  A[用户请求] --> B[Ingress]
  B --> C[service-stable]
  C --> D[新版本Pod]

4.2 流量控制的两种模式

模式 1:按权重分配(副本比例控制)

实现原理:Argo Rollouts 动态调整新版本 Pod 的副本数,Ingress 根据副本比例自动分配流量。

示例:旧版本 4 副本 + 新版本 1 副本 → 新版本接收约 20% 流量。

优势:无需侵入式修改 Ingress 配置,适配 Kubernetes 原生负载均衡逻辑。

模式 2:按请求特征匹配(精准路由)

实现方式:在 Ingress 中配置 Header 匹配规则,实现定向灰度测试:

annotations:
  nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
  nginx.ingress.kubernetes.io/canary-by-header-value: "beta"

典型场景:

定向邀请内测用户(如 X-Canary: beta)

A/B 测试新功能(如 X-Experiment: new-ui)

4.3 Argo Rollouts 协调逻辑流图

participant 用户
  participant ArgoRollouts
  participant K8sAPI
  participant Ingress
  用户->>ArgoRollouts: 触发发布(修改镜像)
  ArgoRollouts->>K8sAPI: 创建新ReplicaSet
  K8sAPI-->>ArgoRollouts:Pod就绪
  ArgoRollouts->>K8sAPI: 调整副本比例(如20%Ingress->>K8sAPI: 监听Endpoint变化
  Ingress->>Ingress: 按副本比例分配流量

  loop 分阶段推进
  ArgoRollouts->>ArgoRollouts: 等待人工确认/定时器
  ArgoRollouts->>K8sAPI: 提升副本比例(如50%)
  end

  ArgoRollouts->>K8sAPI: 缩容旧ReplicaSet

4.4 资源生命周期管理

1.Service 管理

稳定版 Service:全程存在,发布后切换至新版本 Pod,保持服务入口稳定性。

金丝雀 Service:发布完成后闲置,需手动清理或标记为临时资源(如 env: canary-temp)。

2.ReplicaSet 管理

旧版本:缩容至 0 副本,保留配置以支持秒级回滚。

新版本:长期保留,直至下次更新。

3.最佳实践

自动化清理:

# 清理7天前的临时资源
kubectl delete rs,svc -l env=canary-temp --field-selector="metadata.creationTimestamp<$(date -d '7 days ago' +%s)"
快速回滚:

kubectl argo rollouts undo <ROLLOUT_NAME>

4.5 金丝雀原理总结

1.核心原理

动态副本控制:通过调整 Pod 副本比例实现流量权重分配。

原子化切换:最终通过更新 Service 选择器和缩容旧版本完成全量发布。

2.技术优势

精准可控:支持流量比例与用户特征双重策略。

无缝切换:旧版本保留至最终阶段,确保回滚能力。

五、总结

5.1 核心总结

本文聚焦基于 Argo Rollouts 的金丝雀发布实战,通过精细化流量控制、阶段性发布策略和 Ingress 权重路由,构建了一个可操作、可观测的渐进式发布流程。

我们深入解析了 Argo Rollouts 的底层原理,包括:

流量权重分配与阶段推进;

Header 精准路由的灰度测试;

与 Ingress-NGINX 联动,实现流量控制与流量转发的分离。

在实战中,我们构建了从配置到上线的自动化金丝雀发布全过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小马不敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值