1. Blog
  2. Golang
  3. kubernetes
  4. Rust
  5. 关于作者

argo-rollouts 浅析

蓝绿发布:

灰度发布:

rollouts

argo rollouts 定义了一种新的资源Rollout,旨在代替 Deployment 功能,通过控制不同版本 replicasets 副本数量来实现策略化更新。

其定义和 Deployment 极为相似,仅区别于strategy字段,可以理解为 Rollout 对 Deployment 的 strategy 功能进行了扩展。

apiVersion: argoproj.io/v1alpha1 # Changed from apps/v1
kind: Rollout # Changed from Deployment
metadata:
  name: rollouts-demo
spec:
  selector:
    matchLabels:
      app: rollouts-demo
  template:
    metadata:
      labels:
        app: rollouts-demo
    spec:
      containers:
        - name: rollouts-demo
          image: argoproj/rollouts-demo:blue
          ports:
            - containerPort: 8080
  strategy:
    canary: # Changed from rollingUpdate or recreate
      steps:
        - setWeight: 20
        - pause: {}

https://argoproj.github.io/argo-rollouts/migrating/#convert-deployment-to-rollout

argo rollout 支持从现有 Deployment 引用定义,以方便快速集成至 Rolllout。

https://argoproj.github.io/argo-rollouts/migrating/#reference-deployment-from-rollout

与 Deployment 相同 Rollout 借用了 kubernetes 原生资源 Service 来完成版本更新。

在 argo rollout 中策略设置为蓝绿发布时:

在策略设置为灰度发布时:

除了上述的策略外,argo rollout 还提供了基于监控反馈的灰度更新等其他辅助功能。

实现方式

argo rollout 使用两类方式来完成灰度更新:

  1. 应用级别流量分割,即在一个 service 下实现灰度。支持的后端有 istio。
  2. 服务级别流量分割,使用两个不同的 services 实现灰度。支持 nginx ingres,istio。

有关于 argo rollout 与 istio,argo CD 共同使用的内容以及优劣在官方文档上已经有了清楚完备的描述了traffic-management/istio

应用级别流量分割

istio/#subset-level-traffic-splitting

以 istio 为后端举例,rollout 在 subset 级别进行灰度发布时,会动态的修改 virtualservice 中对应的 subsets,不同的 subset 对应不同的版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
spec:
  http:
    - name: primary # referenced in canary.trafficRouting.istio.virtualService.routes
      route:
        - destination:
            host: rollout-example
            subset: stable # referenced in canary.trafficRouting.istio.destinationRule.stableSubsetName
          weight: 100
        - destination:
            host: rollout-example
            subset: canary # referenced in canary.trafficRouting.istio.destinationRule.canarySubsetName
          weight: 0
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
spec:
  host: rollout-example
  subsets:
    - name: canary # referenced in canary.trafficRouting.istio.destinationRule.canarySubsetName
      labels: # labels will be injected with canary rollouts-pod-template-hash value
        app: rollout-example
    - name: stable # referenced in canary.trafficRouting.istio.destinationRule.stableSubsetName
      labels: # labels will be injected with stable rollouts-pod-template-hash value
        app: rollout-example

根据 rollout 版本创建 subset; 根据 rollout 中配置的比例调整 virtualservice 中 service subset 流量权重。

argo rollout 还提供了配置支持在 rollout 过程中进行 preview,即提供 preview service 对新版本进行访问以进行监控采样等工作。

服务级别流量分割

istio/#host-level-traffic-splitting

nginx/#integration-with-argo-rollouts

以 istio 为后端举例,rollout 在 service 级别进行灰度发布时,会动态修改 virtualservice 中对应的 service,不同的 service 对应不同版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
spec:
  http:
    - name: primary # referenced in canary.trafficRouting.istio.virtualService.routes
      route:
        - destination:
            host: stable-svc # referenced in canary.stableService
          weight: 100
        - destination:
            host: canary-svc # referenced in canary.canaryService
          weight: 0
---
apiVersion: v1
kind: Service
metadata:
  name: canary-svc
spec:
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: rollouts-demo
    # This selector will be updated with the pod-template-hash of the canary ReplicaSet. e.g.:
    # rollouts-pod-template-hash: 7bf84f9696
---
apiVersion: v1
kind: Service
metadata:
  name: stable-svc
spec:
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: rollouts-demo
    # This selector will be updated with the pod-template-hash of the stable ReplicaSet. e.g.:
    # rollouts-pod-template-hash: 123746c88d

根据 rollout 中的版本修改 service 的 labelselector 以匹配不同版本的 endpoint,根据 rollout 中配置的比例调整 virtualservice 中 service 流量权重。

监控反馈的灰度发布

analysis 为 argo rollout 提供了高级特性。可以在灰度过程中根据 analysis 指标的成功或者失败以决定继续执行灰度发布还是终止该次发布。

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
    - name: service-name
  metrics:
    - name: success-rate
      interval: 5m
      # NOTE: prometheus queries return results in the form of a vector.
      # So it is common to access the index 0 of the returned array to obtain the value
      successCondition: result[0] >= 0.95
      failureLimit: 3
      provider:
        prometheus:
          address: http://prometheus.example.com:9090
          query: |
            sum(irate(
              istio_requests_total{reporter="source",destination_service=~"",response_code!~"5.*"}[5m]
            )) / 
            sum(irate(
              istio_requests_total{reporter="source",destination_service=~""}[5m]
            ))

上述模板表示在灰度发布过程中,每 5Min 执行一次成功率分析,若分析结果 >= 0.95 则为成功,可以继续灰度发布。若失败,则主动终止 argo rollout 本次灰度发布。

参考