CI/CD: 金丝雀发布 Argo Rollouts 用户指南

CI/CD: 金丝雀发布 Argo Rollouts 用户指南

🎯 让发布像"试吃"一样安全 ------ 金丝雀发布实战指南


一句话理解

金丝雀发布就像餐厅试菜:新菜品先让 10% 的顾客试吃,反馈好再扩大到 30%、50%,最后全面上架。如果有人说不好吃,立刻撤回,不影响其他顾客。


为什么需要金丝雀发布?

传统发布的痛点

复制代码
传统发布 = 一次性全量更新
         ↓
    出问题 = 全部用户受影响
         ↓
    回滚 = 手忙脚乱

金丝雀发布的优势

复制代码
金丝雀发布 = 逐步放量
         ↓
    出问题 = 只影响小部分用户
         ↓
    回滚 = 一键搞定,优雅从容

生活化比喻

  • 传统发布 = 新药直接全民推广(风险巨大)
  • 金丝雀发布 = 新药先临床试验,再小范围推广,最后全面上市(安全可控)

核心概念速查

概念 大白话解释 生活比喻
Rollout 替代 Deployment 的发布控制器 升级版的"发布管家"
Canary(金丝雀) 新版本的小规模测试 矿井里的金丝雀,先探路
Stable 当前稳定运行的版本 正在营业的老店
Promote 推进发布到下一阶段 给新菜品"转正"
Abort 中止发布,回滚到稳定版 紧急撤回问题菜品

环境信息

项目
K8s Master <MASTER_IP>
Argo Rollouts 版本 v1.8.3
命名空间 <NAMESPACE>
已配置 Rollout web-service, user-service

快速上手

场景 1:查看当前发布状态

需求:我想看看 web-service 现在是什么状态

bash 复制代码
kubectl argo rollouts get rollout web-service -n <NAMESPACE>

输出解读

复制代码
Name:            web-service
Status:          ✔ Healthy          # ✔ 表示健康,◌ 表示进行中,॥ 表示暂停
Strategy:        Canary             # 发布策略:金丝雀
  Step:          7/7                # 当前步骤/总步骤
  SetWeight:     100                # 设定的流量比例
  ActualWeight:  100                # 实际的流量比例
Images:          xxx:v1 (stable)    # 当前运行的镜像版本

# 下面是 Pod 树状图
⟳ web-service                       # Rollout 名称
└──# revision:1                     # 版本号
   └──⧉ web-service-xxx             # ReplicaSet
      ├──□ web-service-xxx-abc      # Pod 1
      ├──□ web-service-xxx-def      # Pod 2
      └──□ web-service-xxx-ghi      # Pod 3

场景 2:触发新版本发布

需求:我要发布 web-service 的新版本 v2

方式一:更新镜像(推荐)

bash 复制代码
kubectl argo rollouts set image web-service \
  web=<HARBOR_URL>/<PROJECT>/web-service:v2 \
  -n <NAMESPACE>

方式二:通过 patch 触发

bash 复制代码
kubectl patch rollout web-service -n <NAMESPACE> \
  --type=merge \
  -p '{"spec":{"template":{"metadata":{"annotations":{"release":"v2"}}}}}'

触发后会发生什么?

复制代码
1. 创建新的 ReplicaSet(canary)
2. 启动 1 个新版本 Pod
3. 10% 流量导向新版本
4. 暂停 2 分钟等待观察
5. 如果没问题,继续下一步...

场景 3:观察发布进度

需求:我想实时看发布进度

bash 复制代码
# 实时监控(按 Ctrl+C 退出)
kubectl argo rollouts get rollout web-service -n <NAMESPACE> --watch

发布阶段说明

复制代码
┌─────────────────────────────────────────────────────────────┐
│  10% 流量  →  暂停2min  →  30% 流量  →  暂停2min           │
│      ↓                         ↓                            │
│  50% 流量  →  暂停2min  →  100% 流量  →  完成!            │
└─────────────────────────────────────────────────────────────┘

场景 4:手动推进发布

需求:我不想等 2 分钟,想直接推进到下一步

bash 复制代码
# 推进一步
kubectl argo rollouts promote web-service -n <NAMESPACE>

# 直接全量发布(跳过所有暂停)
kubectl argo rollouts promote web-service -n <NAMESPACE> --full

什么时候用?

  • promote:测试环境快速验证
  • promote --full:紧急发布,确认没问题后快速上线

场景 5:发现问题,紧急回滚

需求:新版本有 bug,需要立刻回滚!

bash 复制代码
# 中止发布,自动回滚到稳定版
kubectl argo rollouts abort web-service -n <NAMESPACE>

回滚后会发生什么?

复制代码
1. 新版本 Pod 被终止
2. 流量 100% 回到稳定版
3. 服务恢复正常
4. 状态变为 Degraded(降级)

如果想重新发布?

bash 复制代码
# 先重置状态
kubectl argo rollouts retry rollout web-service -n <NAMESPACE>

场景 6:回滚到上一个版本

需求:当前版本有问题,想回到上一个版本

bash 复制代码
kubectl argo rollouts undo web-service -n <NAMESPACE>

场景 7:查看发布历史

需求:我想看看之前发布过哪些版本

bash 复制代码
kubectl argo rollouts history web-service -n <NAMESPACE>

输出示例

复制代码
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>

完整发布流程

标准发布流程图

复制代码
┌──────────────────────────────────────────────────────────────────────┐
│                        金丝雀发布完整流程                              │
│                                                                      │
│  1. 触发发布                                                          │
│     kubectl argo rollouts set image web-service web=xxx:v2           │
│                              │                                        │
│                              ▼                                        │
│  2. 金丝雀阶段(10% 流量)                                             │
│     ┌─────────────────────────────────────────┐                      │
│     │  新版本 Pod 启动                          │                      │
│     │  10% 用户访问新版本                       │                      │
│     │  90% 用户访问旧版本                       │                      │
│     │  暂停 2 分钟观察                          │                      │
│     └─────────────────────────────────────────┘                      │
│                              │                                        │
│              ┌───────────────┼───────────────┐                        │
│              ▼               ▼               ▼                        │
│         [有问题]        [没问题]        [手动推进]                     │
│              │               │               │                        │
│              ▼               ▼               ▼                        │
│         abort 回滚      等待自动推进      promote                     │
│                              │               │                        │
│                              └───────┬───────┘                        │
│                                      ▼                                │
│  3. 扩大范围(30% → 50% → 100%)                                       │
│     重复上述观察过程                                                   │
│                              │                                        │
│                              ▼                                        │
│  4. 发布完成                                                          │
│     ┌─────────────────────────────────────────┐                      │
│     │  新版本成为 stable                        │                      │
│     │  旧版本 Pod 被清理                        │                      │
│     │  100% 用户访问新版本                      │                      │
│     └─────────────────────────────────────────┘                      │
└──────────────────────────────────────────────────────────────────────┘

发布检查清单

发布前

  • 新镜像已推送到镜像仓库
  • 在测试环境验证过新版本
  • 确认回滚方案

发布中

  • 观察 10% 阶段的错误率
  • 检查日志是否有异常
  • 监控响应时间

发布后

  • 确认所有 Pod 都是新版本
  • 验证核心功能正常
  • 通知相关人员

常用命令速查表

基础操作

操作 命令
查看状态 kubectl argo rollouts get rollout <name> -n <ns>
实时监控 kubectl argo rollouts get rollout <name> -n <ns> --watch
查看历史 kubectl argo rollouts history <name> -n <ns>
列出所有 Rollout kubectl get rollouts -n <ns>

发布控制

操作 命令
更新镜像 kubectl argo rollouts set image <name> <container>=<image> -n <ns>
推进一步 kubectl argo rollouts promote <name> -n <ns>
全量发布 kubectl argo rollouts promote <name> -n <ns> --full
中止回滚 kubectl argo rollouts abort <name> -n <ns>
回滚上一版 kubectl argo rollouts undo <name> -n <ns>
重试发布 kubectl argo rollouts retry rollout <name> -n <ns>
重启 Pod kubectl argo rollouts restart <name> -n <ns>

常见问题 FAQ

Q1: Rollout 和 Deployment 有什么区别?

A: Rollout 是 Deployment 的"增强版":

特性 Deployment Rollout
滚动更新
金丝雀发布
蓝绿部署
流量控制
自动回滚
发布暂停

Q2: 发布卡在 Paused 状态怎么办?

A: 这是正常的!金丝雀发布会在每个阶段暂停等待观察。

bash 复制代码
# 方式1:等待自动推进(默认 2 分钟)
# 方式2:手动推进
kubectl argo rollouts promote web-service -n <NAMESPACE>

Q3: 发布失败,状态是 Degraded 怎么办?

A: Degraded 表示发布被中止或失败。

bash 复制代码
# 1. 查看详细状态
kubectl argo rollouts get rollout web-service -n <NAMESPACE>

# 2. 如果要重新发布
kubectl argo rollouts retry rollout web-service -n <NAMESPACE>

# 3. 如果要回到稳定版
kubectl argo rollouts undo web-service -n <NAMESPACE>

Q4: 如何修改金丝雀发布的步骤?

A: 修改 Rollout 的 strategy.canary.steps:

yaml 复制代码
strategy:
  canary:
    steps:
    - setWeight: 10      # 第1步:10% 流量
    - pause: {duration: 2m}
    - setWeight: 30      # 第2步:30% 流量
    - pause: {duration: 2m}
    - setWeight: 50      # 第3步:50% 流量
    - pause: {duration: 2m}
    - setWeight: 100     # 第4步:全量

Q5: 如何实现自动回滚?

A: 集成 Prometheus 分析,当错误率超过阈值时自动回滚(高级功能,需要额外配置 AnalysisTemplate)。


最佳实践

1. 发布时间选择

复制代码
✅ 推荐:工作日上午 10:00-11:00,下午 14:00-16:00
❌ 避免:周五下午、节假日前、深夜

2. 流量比例建议

复制代码
低风险变更:10% → 50% → 100%
中风险变更:10% → 30% → 50% → 100%
高风险变更:5% → 10% → 30% → 50% → 100%

3. 观察时间建议

复制代码
简单变更:每阶段 2-5 分钟
复杂变更:每阶段 10-30 分钟
核心服务:每阶段 30-60 分钟

4. 回滚决策

复制代码
立即回滚的情况:
- 错误率明显上升
- 响应时间大幅增加
- 核心功能异常
- 用户投诉增多

继续观察的情况:
- 指标波动在正常范围
- 只有非核心功能受影响
- 问题可以快速修复

Rollout 配置示例

yaml 复制代码
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: web-service
  namespace: <NAMESPACE>
spec:
  replicas: 3
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      app: web-service
  strategy:
    canary:
      steps:
      - setWeight: 10
      - pause: {duration: 2m}
      - setWeight: 30
      - pause: {duration: 2m}
      - setWeight: 50
      - pause: {duration: 2m}
      - setWeight: 100
  template:
    metadata:
      labels:
        app: web-service
    spec:
      containers:
      - name: web
        image: <HARBOR_URL>/<PROJECT>/web-service:v1
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "500m"

总结

金丝雀发布三步曲

复制代码
1. 触发:set image 或 patch
2. 观察:get rollout --watch
3. 决策:promote(继续)或 abort(回滚)

记住这三个命令就够了

bash 复制代码
# 发布
kubectl argo rollouts set image <name> <container>=<image> -n <ns>

# 推进
kubectl argo rollouts promote <name> -n <ns>

# 回滚
kubectl argo rollouts abort <name> -n <ns>

相关链接


📝 本文基于 Argo Rollouts v1.8.3 编写,如有问题欢迎留言讨论!

相关推荐
夜来小雨2 小时前
SRv6知识点
运维·网络
阿巴~阿巴~2 小时前
深入UDP与sk_buff:掌握Linux网络协议栈的核心机制
网络·网络协议·http·udp·无连接·sk_buff·无状态
航Hang*2 小时前
第十三章:网络系统建设与运维(高级)—— 路由控制和策略路由
运维·服务器·网络·笔记·ensp
white-persist3 小时前
【内网运维】Netstat与Wireshark:内网运维溯源实战解析
运维·网络·数据结构·测试工具·算法·网络安全·wireshark
人生匆匆3 小时前
免费 SSL 证书申请流程
网络·网络协议·ssl
じ☆冷颜〃3 小时前
二分查找的推广及其在排序与链表结构中的关联
网络·windows·经验分享·笔记·算法·链表
航Hang*3 小时前
第十章:网络系统建设与运维(高级)—— 网络系统安全
网络·华为·ensp·期末·复习
jiecy3 小时前
IPv6 过渡 - 隧道技术
运维·网络·信息与通信
QT 小鲜肉4 小时前
【Linux命令大全】001.文件管理之whereis命令(实操篇)
linux·运维·服务器·网络·笔记