跳转至

0003-Rollouts-蓝绿部署

一、蓝绿发布原理

1. 蓝绿发布:零停机部署的核心范式

蓝绿发布(Blue-Green Deployment)是一种基于 “双版本环境并行部署 + 原子化流量切换” 的零停机更新策略,通过严格的环境隔离与瞬时流量调度,在保障业务连续性的同时,实现版本的安全迭代,其核心逻辑与技术价值如下:

2. 核心实现逻辑

1. 双环境独立共存,版本隔离部署

  • 蓝色环境(Blue):当前稳定运行的生产环境,承载全部用户真实流量,部署的是待更新的旧版本(如镜像版本 v1),作为业务连续性的 “基准保障”。
  • 绿色环境(Green):新版本预部署环境,部署目标更新版本(如镜像版本 v2),仅用于更新前的功能验证、性能测试,不承接生产流量,确保新版本与生产环境完全隔离。

2. 验证通过后,原子化切换流量

待绿色环境(v2 版本)完成功能、兼容性、性能等验证并确认可用后,通过路由配置(如 Ingress、Service selector 调整)瞬时将全部生产流量从蓝色环境切换至绿色环境,切换过程无感知,避免流量中断。

3. 异常快速回退,降低故障影响

若绿色环境(v2 版本)上线后出现异常(如功能 bug、性能瓶颈),无需重建旧版本实例,仅需反向切换流量至蓝色环境(v1 版本),秒级恢复业务,大幅缩短故障恢复时间(MTTR)。

3. 核心技术价值

  1. 零业务中断:规避滚动更新中 “新旧版本 Pod 共存、请求被混合处理” 的风险,流量切换过程瞬时完成,用户无感知,保障业务连续性。
  2. 版本强隔离:蓝色、绿色环境完全独立部署,不存在配置共享、依赖冲突等问题,避免新版本部署对生产环境的潜在干扰。
  3. 回滚效率高:无需重新拉取旧版本镜像、重建 Pod,仅通过流量路由调整即可完成回滚,操作简单、耗时短,降低故障扩散风险。

二、Argo Rollouts 简介

Argo Rollouts 是 Kubernetes 生态中专注于高级部署管理的自定义控制器(Custom Controller)。它在原生 Deployment 基础上扩展了核心能力,通过标准化的资源定义与自动化流程,解决了原生部署模式在 “可控性、可观测性、策略多样性” 上的不足,为 Kubernetes 环境下的版本迭代提供更安全、灵活的管理方案。

1. 核心能力

1. 多发布策略原生支持,适配多样业务需求

内建蓝绿发布、金丝雀发布(Canary)、A/B 测试等多种主流发布模式,无需额外开发自定义逻辑。用户可根据业务场景(如核心服务零停机要求、新功能灰度验证需求)灵活选择策略,降低高级部署的实现门槛。

2. 监控驱动的自动化决策,提升部署可靠性

支持与 Prometheus、Grafana 等监控系统无缝集成,可基于自定义指标(如服务响应时间、错误率、CPU 使用率)自动触发发布流程 —— 当指标符合预设阈值时自动推进发布,若指标异常则立即触发回滚,减少人工干预成本,降低故障风险。

3. 可视化 Dashboard,简化部署监控与管理

配套提供专属可视化界面(Argo Rollouts Dashboard),可实时展示发布进度(如 Pod 就绪状态、流量切换比例)、版本历史(如各版本镜像、配置差异)、流量分配情况(如金丝雀流量占比),直观呈现部署全链路状态,降低操作复杂度与人工误判概率。

4. CLI 插件高效赋能,优化命令行操作体验

提供 kubectl argo rollouts 命令行插件,将复杂的部署管理操作(如版本切换、发布暂停 / 恢复、强制回滚、查看发布日志)封装为简洁指令,无需手动修改 YAML 或调用 API,大幅提升命令行场景下的操作效率。

补充说明:Argo Rollouts Dashboard

作为 Argo Rollouts 的配套可视化组件,Argo Rollouts Dashboard 不仅是 “状态展示工具”,更是 “部署管控辅助平台”:

  • 核心功能:实时呈现 Rollout 资源的运行状态(如当前活跃版本、新旧版本 Pod 数量)、历史版本记录(含版本切换时间、触发原因)、流量分布详情(如蓝绿环境流量占比、金丝雀流量路由规则);
  • 生态联动:常与 Prometheus(指标监控)、日志分析工具(如 Loki)联动,在 Dashboard 中直接关联 “发布状态” 与 “业务指标 / 日志”,帮助用户快速定位发布过程中的异常根因。

2. 架构简介

graph TD
    A[Argo Rollouts CRD<br/><small>(定义蓝绿/金丝雀等发布规则)</small>] --> B[Argo Rollouts 控制器<br/><small>(核心调度与决策组件)</small>]
    %% 控制器对 ReplicaSet 的管理链路
    B -->|1. 根据 CRD 配置<br/>创建/扩缩容实例| C[存量 ReplicaSet<br/><small>(承载当前生产流量,如蓝色环境)</small>]
    B -->|2. 新版本部署时<br/>创建新实例| F[新 ReplicaSet<br/><small>(待验证版本,如绿色环境)</small>]
    %% ReplicaSet 生成 Pod 链路
    C -->|管理 Pod 生命周期| D[存量 Pod 集群<br/><small>(运行旧版本镜像)</small>]
    F -->|管理 Pod 生命周期| H[新 Pod 集群<br/><small>(运行新版本镜像)</small>]
    %% 控制器对 Service 与监控的联动链路
    B -->|3. 流量切换时<br/>更新标签选择器| E[Service<br/><small>(生产流量入口)</small>]
    E -->|流量路由至存量实例| C
    E -->|验证通过后<br/>切换至新实例| F
    B -->|4. 实时拉取监控指标<br/>判断发布状态| G[Prometheus<br/><small>(提供错误率、响应时间等指标)</small>]
    G -->|反馈指标数据| B

三、基于 Argo Rollouts 蓝绿发布

argoproj/rollouts-demo:green 镜像 进行蓝绿发布。

1.项目结构

bluegreen-rollout/
├── 1-1-blue-rollout.yaml       # 蓝-Rollout 配置
├── 1-2-blue-service.yaml       # 蓝-Service 定义
├── 1-3-blue-ingress.yaml       # 蓝-Ingress 配置
├── 2-1-green-preview.yaml      # 绿-Service 定义
└── 2-2-green-ingress.yaml      # 绿-Ingress 配置
mkdir /argocd/rollout/blue-green && cd /argocd/rollout/blue-green

2. 编写配置文件

cat > 1-1-blue-rollout.yaml << "EOF"
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: bluegreen-demo
  labels:
    app: bluegreen-demo
spec:
  replicas: 3
  revisionHistoryLimit: 1
  selector:
    matchLabels:
      app: bluegreen-demo
  template:
    metadata:
      labels:
        app: bluegreen-demo
    spec:
      containers:
        - name: bluegreen-demo
          image: argoproj/rollouts-demo:blue  # 新版本镜像(绿色环境)
          imagePullPolicy: Always
          ports:
            - name: http
              containerPort: 8080
  strategy:
    blueGreen:
      autoPromotionEnabled: false  # 关键:禁用自动发布,需手动确认后才切换流量
      activeService: bluegreen-demo  # 生产流量入口服务(指向当前活跃版本)
      previewService: bluegreen-demo-preview  # 新增:预览服务(指向待验证的绿色环境)
EOF
cat > 1-2-blue-service.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
  name: bluegreen-demo
spec:
  selector:
    app: bluegreen-demo
  ports:
    - port: 80
      targetPort: http
      name: http
EOF
cat > 1-3-blue-ingress.yaml << "EOF"
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-blue
spec:
  ingressClassName: kubesphere-router-cluster
  tls:
    - hosts:
        - blue.k8s.example.cn
      secretName: 3-k8s
  rules:
  - host: blue.k8s.example.cn
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: bluegreen-demo
            port:
              number: 80
EOF

3. 部署与验证

1. 部署蓝资源

kubectl apply -f 1-1-blue-rollout.yaml  
kubectl apply -f 1-2-blue-service.yaml
kubectl apply -f 1-3-blue-ingress.yaml

2. 访问蓝应用和rollouts的页面

应用截图查看都是蓝版本 rollout 截图查看当前是蓝版本
image-20250828111153885 image-20250828111242459

3. 触发绿发布

修改 blue-green-rollout.yaml文件中的镜像版本为 green并创建预览 serviceingress

cat > 2-1-green-preview.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
  name: bluegreen-demo-preview  # 需与 Rollout 中 previewService 名称一致
spec:
  selector:
    app: bluegreen-demo  # 标签需与 Rollout 中 Pod 模板一致
  ports:
    - port: 80
      targetPort: http
      name: http
EOF
cat > 2-2-green-ingress.yaml << "EOF"
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-green
spec:
  ingressClassName: kubesphere-router-cluster
  tls:
    - hosts:
        - green.k8s.example.cn
      secretName: 3-k8s
  rules:
  - host: green.k8s.example.cn
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: bluegreen-demo-preview
            port:
              number: 80
EOF
# 1. 修改镜像,并发布绿应用
sed -i 's|image: argoproj/rollouts-demo:blue|image: argoproj/rollouts-demo:green|g' 1-1-blue-rollout.yaml
kubectl apply -f 1-1-blue-rollout.yaml


# 2. 新建绿应用部署,创建新的 service 和 ingress
kubectl apply -f 2-1-green-preview.yaml
kubectl apply -f 2-2-green-ingress.yaml

4. 查看绿版本发布效果

查看应用界面

查看生产版本还是蓝版本 新建的预览版本已经有了绿版本
image-20250828140943068 image-20250828112401705

查看 rollout 界面

发现预览版本是绿版本 验证完成后点击发版将蓝更新至绿
image-20250828140707744 image-20250828141113966
查看生产已经更新到了绿色版本
image-20250828141340738

5. 把绿回滚到蓝版本

rollout 界面上手动回滚至蓝版本 应用界面查看预览版本蓝版本
image-20250828112930990 image-20250828113009357
查看预览版本蓝版本没问题后、点击推进将蓝版本回滚至绿版本 查看生产已经回滚至蓝色版本
image-20250828141630562 image-20250828141737678

6. 多环境配置可使用helm或Kustomize

blue-green-demo/
├── base/                     # 基础配置
│   ├── rollout.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── kustomization.yaml    # 聚合资源
└── overlays/
    ├── dev/                  # 开发环境
    │   ├── kustomization.yaml
    │   └── replica-patch.yaml  # 调整副本数等
    └── prod/                 # 生产环境
        ├── kustomization.yaml
        └── resource-patch.yaml  # 调整资源限制

四、Argo Rollouts 原理解析

1. 流量切换原理详解

Argo Rollouts 借助动态变更 Service 标签选择器(Label Selector),配合多 ReplicaSet 生命周期管理,实现蓝绿发布的流量精准切换,以下拆解完整流程:

1. 初始状态(蓝色环境:稳定生产阶段)

  • Rollout 定义:配置镜像为 argoproj/rollouts-demo:blue,作为生产环境基准版本。

  • 蓝色 ReplicaSet:控制器创建 bluegreen-demo-abc123 ReplicaSet,Pod 携带双标签:

labels:
  app: bluegreen-demo          # 业务标识标签
  rollouts-pod-template-hash: abc123  # Argo 自动生成的唯一版本哈希
  • Service 路由:Service 的 selector 精准匹配蓝色 Pod 的哈希标签,确保流量定向:
selector:
  app: bluegreen-demo
  rollouts-pod-template-hash: abc123
  • 流量链路:全链路承载生产流量。
graph LR
    A[Ingress<br/><small>流量入口</small>] --> B[Service<br/><small>流量路由</small>]
    B --> C[Green ReplicaSet<br/><small>蓝色副本集</small>]
    C --> D[Green Pod<br/><small>蓝色容器</small>]

2. 触发更新(绿色环境:新版本部署阶段)

当修改 Rollout 镜像为 argoproj/rollouts-demo:green 并应用后:

  • 绿色 ReplicaSet 创建:控制器新建 bluegreen-demo-def456 ReplicaSet,Pod 标签更新为:
labels:
  app: bluegreen-demo          
  rollouts-pod-template-hash: def456  # 新哈希标识新版本
  • 双环境并行状态

  • 蓝色 Pod:继续承载生产流量,保障业务不中断;

  • 绿色 Pod:启动并完成初始化(如容器启动、健康检查),但因 Service 未更新,暂不接收流量。

3. 流量切换(绿色就绪:生产流量迁移阶段)

绿色 Pod 就绪后,Argo Rollouts 执行流量切换:

  • Service 选择器更新:控制器修改 Service 的 selector,指向绿色 Pod 的哈希标签:
selector:
  app: bluegreen-demo
  rollouts-pod-template-hash: def456  # 切换到绿色版本哈希
  • ReplicaSet 生命周期调整

  • 蓝色 ReplicaSet:逐步缩容至 0 副本(保留历史记录,支持快速回滚);

  • 绿色 ReplicaSet:扩容至目标副本数(如 spec.replicas: 3),全量承接生产流量。

  • 新流量链路:完成版本迭代。

graph LR
    A[Ingress<br/><small>流量入口</small>] --> B[Service<br/><small>流量路由</small>]
    B --> C[Green ReplicaSet<br/><small>绿色副本集</small>]
    C --> D[Green Pod<br/><small>绿色容器</small>]

4. 回滚机制(秒级恢复:异常场景补偿)

若绿色版本验证异常,执行 kubectl argo rollouts undo 触发回滚:

  • Service 回退:控制器将 Service 的 selector 切回旧哈希(如 abc123),流量瞬时回归蓝色环境;

  • ReplicaSet 状态重置

  • 蓝色 ReplicaSet:快速扩容至目标副本数,恢复生产;

  • 绿色 ReplicaSet:缩容至 0 副本,终止新版本流量。

2. 动态流量切换示意图(Mermaid 可视化)

通过标签选择器动态变更ReplicaSet 生命周期管理,Argo Rollouts 实现了 “双环境并行、流量瞬时切换、故障秒级回滚” 的蓝绿发布能力,既保障业务连续性,又简化复杂部署流程。

sequenceDiagram
    title Argo Rollouts 蓝绿发布流量切换流程
    participant Ingress as Ingress(流量入口)
    participant Service as Service(流量路由)
    participant Blue_RS as 蓝色 ReplicaSet(旧版本)
    participant Green_RS as 绿色 ReplicaSet(新版本)
    participant Blue_Pod as 蓝色 Pod(旧版本容器)
    participant Green_Pod as 绿色 Pod(新版本容器)

    Note over Ingress,Blue_Pod: 初始状态(蓝色版本承载生产流量)
    Ingress->>Service: 用户请求
    Service->>Blue_RS: 路由到蓝色 ReplicaSet
    Blue_RS->>Blue_Pod: 分发请求到蓝色 Pod

    Note over Ingress,Green_Pod: 触发更新(镜像改为 green)
    Green_RS->>Green_Pod: 启动绿色 Pod(初始化中)
    Green_Pod-->>Green_RS: 绿色 Pod 就绪
    Green_RS-->>Service: 通知控制器新版本就绪

    Note over Ingress,Green_Pod: 流量切换(绿色版本承接流量)
    Service->>Green_RS: 更新 selector 指向绿色哈希
    Ingress->>Service: 新用户请求
    Service->>Green_RS: 路由到绿色 ReplicaSet
    Green_RS->>Green_Pod: 分发请求到绿色 Pod
    Blue_RS->>Blue_Pod: 蓝色 ReplicaSet 缩容至 0 副本(保留)