Argo Rollouts - 渐进式交付 Kubernetes 控制器

项目标题与描述

Argo Rollouts 是一个 Kubernetes 控制器和一组 CRD,提供高级部署能力,如蓝绿部署、金丝雀部署、金丝雀分析、实验和渐进式交付功能。它可以与入口控制器和服务网格集成,利用其流量整形能力在更新期间逐步将流量转移到新版本。

功能特性

  • 多种部署策略

    • 蓝绿部署
    • 金丝雀部署
    • 渐进式交付
  • 高级流量管理

    • 与 Istio、ALB、SMI 等集成
    • 动态调整稳定 ReplicaSet 规模
    • 多集群支持
  • 自动化分析

    • 支持 Prometheus、Datadog、Wavefront 等多种指标提供者
    • 自动回滚机制
    • 实验和分析运行
  • 可观测性

    • Rollout Dashboard 服务
    • 丰富的指标和状态监控
  • 扩展性

    • 插件系统支持自定义指标提供者
    • 通知系统

安装指南

标准安装

kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

命名空间级别安装

kubectl apply -k https://github.com/argoproj/argo-rollouts/manifests/crds\?ref\=stable
kubectl apply -f https://github.com/argoproj/argo-rollouts/releases/latest/download/namespace-install.yaml

使用说明

基本使用示例

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: example-rollout
spec:
  replicas: 5
  strategy:
    canary:
      steps:
      - setWeight: 20
      - pause: {}
      - setWeight: 40
      - pause: {duration: 10m}
      - setWeight: 60
      - pause: {}
      - setWeight: 100
  selector:
    matchLabels:
      app: example
  template:
    metadata:
      labels:
        app: example
    spec:
      containers:
      - name: example
        image: nginx:1.19

典型使用场景

  1. 金丝雀发布:逐步将流量从旧版本转移到新版本
  2. 蓝绿部署:快速切换全部流量到新版本
  3. 自动化分析:基于指标自动决定是否继续发布或回滚

核心代码

控制器主循环

func (c *Controller) reconcileAnalysisRun(origRun *v1alpha1.AnalysisRun) *v1alpha1.AnalysisRun {
    logger := logutil.WithAnalysisRun(origRun)
    if origRun.Status.Phase.Completed() {
        err := c.maybeGarbageCollectAnalysisRun(origRun, logger)
        if err != nil {
            logger.Warnf("Failed to garbage collect analysis run: %v", err)
        }
        return origRun
    }
    run := origRun.DeepCopy()

    if run.Status.MetricResults == nil {
        run.Status.MetricResults = make([]v1alpha1.MetricResult, 0)
    }
    // ...省略后续处理逻辑...
}

指标提供者接口

type Provider interface {
    Run(*v1alpha1.AnalysisRun, v1alpha1.Metric) v1alpha1.Measurement
    Resume(*v1alpha1.AnalysisRun, v1alpha1.Metric, v1alpha1.Measurement) v1alpha1.Measurement
    Terminate(*v1alpha1.AnalysisRun, v1alpha1.Metric, v1alpha1.Measurement) v1alpha1.Measurement
    GarbageCollect(*v1alpha1.AnalysisRun, v1alpha1.Metric, int) error
    Type() string
    GetMetadata(metric v1alpha1.Metric) map[string]string
}

Prometheus 指标提供者实现

func (p *Provider) Run(run *v1alpha1.AnalysisRun, metric v1alpha1.Metric) v1alpha1.Measurement {
    startTime := timeutil.MetaNow()
    newMeasurement := v1alpha1.Measurement{
        StartedAt: &startTime,
    }

    ctx, cancel := context.WithTimeout(context.Background(), p.timeout)
    defer cancel()
    
    value, warnings, err := p.executeQuery(ctx, metric)
    if err != nil {
        return metricutil.MarkMeasurementError(newMeasurement, err)
    }
    
    // ...处理查询结果...
    return newMeasurement
}

更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
公众号二维码

posted @ 2025-07-04 18:01  qife  阅读(14)  评论(0)    收藏  举报