Argo Rollouts Canary 基础

Argo Rollouts Canary 概述

金丝雀部署是一种部署策略,将一小部分生产流量发布到新版本的应用程序。

Argo Rollouts Canary 完整配置

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: example-rollout-canary
spec:
  # 运行的Pod实例数量,默认为1.
  # Defaults to 1.
  replicas: 5
  analysis:
    # 保留成功的数量
    # Defaults to 5.
    successfulRunHistoryLimit: 10
    # 保留失败的数量 
    # Stages for unsuccessful: "Error", "Failed", "Inconclusive"
    # Defaults to 5.
    unsuccessfulRunHistoryLimit: 10

  # 筛选Pod对象的标签选择器.
  selector:
    matchLabels:
      app: guestbook

  # WorkloadRef holds a references to a workload that provides Pod template 
  # (e.g. Deployment). If used, then do not use Rollout template property.
  workloadRef: 
    apiVersion: apps/v1
    kind: Deployment
    name: rollout-ref-deployment
    # 指定迁移到 Rollout 后是否缩减工作负载(Deployment)
    # "never": Deployment 不会减少
    # "onsuccess": 在 Rollout 变得健康后,Deployment会减少
    # "progressively": 随着 Rollout 的增加,Deployment 也随之减少 
    # If the Rollout fails the Deployment will be scaled back up.
    scaleDown: never|onsuccess|progressively

  # Template describes the pods that will be created. Same as deployment.
  # If used, then do not use Rollout workloadRef property. 
  template:
    spec:
      containers:
      - name: guestbook
        image: argoproj/rollouts-demo:blue

  # 无容器crash的情况下,新建的Pod被视为可用的最短时长,默认为0,即立即转为Ready
  minReadySeconds: 30

  # 更新历史中保留的ReplicaSet Revision数量.
  # Defaults to 10
  revisionHistoryLimit: 3

  # 是否置为暂停状态
  paused: true

  # 更新过程中,更新步骤的最大等待时长,默认为600秒;
  # Defaults to 600s
  progressDeadlineSeconds: 600

  # 未使用analysis或experiment而progressDeadlineSeconds超时的情况下,是否中止更新过程,默认为false;
  progressDeadlineAbort: false

  # 重启Pod的时刻,其值为UTC时间戳格式;
  restartAt: "2020-03-30T21:19:35Z"

  # 回滚窗口
  rollbackWindow:
    revisions: 3

  # 更新策略,支持canary和blueGreen两种;
  strategy:  
    canary:

      # 由控制器用来匹配到Canary Pods上的Service,trafficRouting依赖于该字段;
      canaryService: canary-service

      # 由控制器用来匹配到Stable Pods上的Service, trafficRouting依赖于该字段;
      stableService: stable-service

      # 需要添加到Canary版本的Pod上的元数据,仅存于Canary更新期间,更新完成后即成为Stable;
      canaryMetadata:
        annotations:
          role: canary
        labels:
          role: canary

      # 需要添加到Stable版本的Pod上的元数据;
      stableMetadata:
        annotations:
          role: stable
        labels:
          role: stable

      # 更新期间最多允许处于不可用状态的Pod数量或百分比
      maxUnavailable: 1

      # maxSurge 定义了 rollout 可以创建的最大副本数,以移动到最后 setWeight 设置的正确比率。maxSurge可以是整数或字符串形式的百分比
      maxSurge: "20%"

      # 启用了trafficRouting时,缩容前一个ReplicaSet规模的延迟时长,默认为30s;
      scaleDownDelaySeconds: 30

      # The minimum number of pods that will be requested for each ReplicaSet
      # when using traffic routed canary. This is to ensure high availability
      # of each ReplicaSet. Defaults to 1. +optional
      minPodsPerReplicaSet: 2

      # 在旧RS上启动缩容之前,可运行着的旧RS的数量;
      scaleDownDelayRevisionLimit: 2

      # 在滚动更新期间于后台运行的analysis,可选;
      analysis:
        templates:
        - templateName: success-rate
        args:
        - name: service-name
          value: guestbook-svc.default.svc.cluster.local

        # valueFrom.podTemplateHashValue is a convenience to supply the
        # rollouts-pod-template-hash value of either the Stable ReplicaSet
        # or the Latest ReplicaSet
        - name: stable-hash
          valueFrom:
            podTemplateHashValue: Stable
        - name: latest-hash
          valueFrom:
            podTemplateHashValue: Latest

        # valueFrom.fieldRef allows metadata about the rollout to be
        # supplied as arguments to analysis.
        - name: region
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['region']

      # Canary更新期间要执行的步骤,可选;
      steps:

      # 设定Canary版本ReplicSet激活的Pod比例,以及调度至Canary版本的流量比例;
      - setWeight: 20

      # 暂停step. Supported units: s, m, h
      - pause:
          duration: 1h

      # Pauses indefinitely until manually resumed
      - pause: {}

      # 设定Canary扩容期间Pod扩增与流量扩增的对应关系
      # (supported only with trafficRouting)
      - setCanaryScale:
          replicas: 3       # 明确设定Canary RS的规模为该处指定的Pod数量,但不改变先前设定的流量比例;

      # 设定Canary扩容期间Pod扩增与流量扩增的对应关系
      # (supported only with trafficRouting)
      - setCanaryScale:
          weight: 25        # 明确设定Canary RS的规模为该处指定的比例,但不改变先前设定的流量比例;

      # 设定Canary扩容期间Pod扩增与流量扩增的对应关系
      - setCanaryScale:
          matchTrafficWeight: true  # 设定Canary的Pod规模与调度至这些Pod的流量同比例滚动;

      # Sets header based route with specified header values
      # Setting header based route will send all traffic to the canary for the requests 
      # with a specified header, in this case request header "version":"2"
      # (supported only with trafficRouting, for Istio only at the moment)
      - setHeaderRoute:
          # Name of the route that will be created by argo rollouts this must also be configured
          # in spec.strategy.canary.trafficRouting.managedRoutes
          name: "header-route-1"
          # The matching rules for the header route, if this is missing it acts as a removal of the route.
          match:
              # headerName The name of the header to apply the match rules to.
            - headerName: "version"
              # headerValue must contain exactly one field of exact, regex, or prefix. Not all traffic routers support 
              # all types
              headerValue:
                # Exact will only match if the header value is exactly the same
                exact: "2"
                # Will match the rule if the regular expression matches
                regex: "2.0.(.*)"
                # prefix will be a prefix match of the header value
                prefix: "2.0"

        # Sets up a mirror/shadow based route with the specified match rules
        # The traffic will be mirrored at the configured percentage to the canary service
        # during the rollout
        # (supported only with trafficRouting, for Istio only at the moment)
      - setMirrorRoute:
          # Name of the route that will be created by argo rollouts this must also be configured
          # in spec.strategy.canary.trafficRouting.managedRoutes
          name: "header-route-1"
          # The percentage of the matched traffic to mirror to the canary
          percentage: 100
          # The matching rules for the header route, if this is missing it acts as a removal of the route.
          # All conditions inside a single match block have AND semantics, while the list of match blocks have OR semantics.
          # Each type within a match (method, path, headers) must have one and only one match type (exact, regex, prefix)
          # Not all match types (exact, regex, prefix) will be supported by all traffic routers.
          match:
            - method: # What HTTP method to match
                exact: "GET"
                regex: "P.*"
                prefix: "POST"
              path: # What HTTP url paths to match.
                exact: "/test"
                regex: "/test/.*"
                prefix: "/"
              headers:
                agent-1b: # What HTTP header name to use in the match.
                  exact: "firefox"
                  regex: "firefox2(.*)"
                  prefix: "firefox"

      # 内联定义或调用的analysis step
      - analysis:
          templates:
          - templateName: success-rate

      # 内联定义或调用的experiment step;
      - experiment:
          duration: 1h
          templates:
          - name: baseline
            specRef: stable
            # optional, creates a service for the experiment if set
            service:
              # optional, service: {} is also acceptable if name is not included
              name: test-service
          - name: canary
            specRef: canary
            # optional, set the weight of traffic routed to this version
            weight: 10
          analyses:
          - name : mann-whitney
            templateName: mann-whitney
            # Metadata which will be attached to the AnalysisRun.
            analysisRunMetadata:
              labels:
                app.service.io/analysisType: smoke-test
              annotations:
                link.argocd.argoproj.io/external-link: http://my-loggin-platform.com/pre-generated-link

      # 定义Canary Pod与旧ReplicaSet Pod之间的反亲和关系;
      antiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution: {}
        preferredDuringSchedulingIgnoredDuringExecution:
          weight: 1 # Between 1 - 100

      # 设定Ingress Controller或ServiceMesh如何动态调整配置以完成精细化地流量分割和流量迁移;
      trafficRouting:
        # This is a list of routes that Argo Rollouts has the rights to manage it is currently only required for
        # setMirrorRoute and setHeaderRoute. The order of managedRoutes array also sets the precedence of the route
        # in the traffic router. Argo Rollouts will place these routes in the order specified above any routes already
        # defined in the used traffic router if something exists. The names here must match the names from the 
        # setHeaderRoute and setMirrorRoute steps.
        managedRoutes:
          - name: set-header
          - name: mirror-route
        # 与Istio协同完成流量迁移
        istio:
          # Canary期间要自动动态调整其配置以完成流量迁移的的VirtualService资源
          virtualService: 
            name: rollout-vsvc  # VirtualService资源的名称
            routes:             # 指定的VirtualService资源上要动态调整的路由条目的名称列表,仅有一个路由时可省略该字段
            - primary # optional if there is a single route in VirtualService, required otherwise         
          virtualServices:      # Canary期间要自动动态调整其配置以完成流量迁移的的VirtualService资源列表
          # One or more virtualServices can be configured
          - name: rollouts-vsvc1  # required
            routes:
              - primary # optional if there is a single route in VirtualService, required otherwise
          - name: rollouts-vsvc2  # required
            routes:
              - secondary # optional if there is a single route in VirtualService, required otherwise
          - name: rollout-vsvc   # required
            tcpRoutes:           # TCP 流量分割
              # Below fields are optional but if defined, they should match exactly with at least one of the TCP route match rules in your VirtualService
              - port: 3000 # Only required if you want to match any rule in your VirtualService which contains this port
          # Canary期间要自动动态调整其配置以完成流量迁移的DestinationRule资源
          destinationRule:
            name: rollout-destrule    # required,DestinationRule资源的名称
            canarySubsetName: canary  # required,DestinationRule中临时使用的Canary子集的名称
            stableSubsetName: stable  # required,DestinationRule中临时使用的Stable子集的名称

        # 与Ingress Nginx协同完成流量迁移
        nginx:
          # 要调整的Stable Ingress资源的名称
          stableIngress: primary-ingress
          stableIngresses:
            - primary-ingress
            - secondary-ingress
            - tertiary-ingress
          annotationPrefix: customingress.nginx.ingress.kubernetes.io # optional
          additionalIngressAnnotations:   # optional
            canary-by-header: X-Canary
            canary-by-header-value: iwantsit

        # ALB Ingress Controller routing configuration
        alb:
          ingress: ingress  # required
          servicePort: 443  # required
          annotationPrefix: custom.alb.ingress.kubernetes.io # optional

        # Service Mesh Interface routing configuration
        smi:
          rootService: root-svc # optional
          trafficSplitName: rollout-example-traffic-split # optional

      # 启用了trafficRouting时,因更新中止 而收缩Canary版本Pod数量之前的延迟时长,默认为30s;
      abortScaleDownDelaySeconds: 30

Argo Rollouts Canary 示例

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollouts-nginx-with-analysis
  namespace: argo-demo
spec:
  replicas: 10 
  strategy:
    canary:
      trafficRouting:
        istio:
          virtualService: 
            name: nginx-rollout-vsvc
            routes:
            - primary
          destinationRule:
            name: nginx-rollout-destrule
            canarySubsetName: canary
            stableSubsetName: stable
      analysis:
        templates:
        - templateName: success-rate
        args:
        - name: service-name
          # change this value to your service name
          value: nginx.argo-demo.svc.wgs.local
        startingStep: 2
      steps:
      - setWeight: 5
      - pause: {duration: 1m}
      - setWeight: 10
      - pause: {duration: 1m}
      - setWeight: 30
      - pause: {duration: 1m}
      - setWeight: 60
      - pause: {duration: 1m}
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.24-alpine
        ports:
        - name: http
          containerPort: 80
          protocol: TCP
        resources:
          requests:
            memory: 32Mi
            cpu: 50m
        livenessProbe:
          httpGet:
            path: '/'
            port: 80
            scheme: HTTP
        readinessProbe:
          httpGet:
            path: '/'
            port: 80
            scheme: HTTP
          initialDelaySeconds: 5

参考文档

https://argoproj.github.io/argo-rollouts/features/canary/

posted @ 2023-12-15 19:48  小吉猫  阅读(53)  评论(0编辑  收藏  举报