• Kruise Rollout: 让所有应用负载都能使用渐进式交付


    作者:赵明山(立衡)

    前言

    OpenKruise [1]  是阿里云开源的云原生应用自动化管理套件,也是当前托管在 Cloud Native Computing Foundation (CNCF) 下的 Sandbox 项目。它来自阿里巴巴多年来容器化、云原生的技术沉淀,是阿里内部生产环境大规模应用的基于 Kubernetes 之上的标准扩展组件,也是紧贴上游社区标准、适应互联网规模化场景的技术理念与最佳实践。在原有的工作负载、sidecar 管理等领域外,Kruise 目前正在渐进式交付领域进行尝试。

    什么是渐进式交付?

    “渐进式交付” 一词最早起源于大型、复杂的工业化项目,它试图将复杂的项目进行分阶段拆解,通过持续进行小型闭环迭代降低交付成本和时间。随着 Kubernetes 及云原生理念被普及之后,尤其是在持续部署流水线出现后,渐进式交付为互联网应用提供了基础设施和实现方法。

    在产品的迭代过程中,可以将渐进式交付的具体行为附着在流水线中,将整条交付流水线看作产品迭代的一个过程和一次渐进式交付周期。渐进式交付在实践中是以 A/B 测试、金丝雀/灰度发布等技术手段落地的。以 淘宝商品推荐 为例,其每次发布重大功能,都会经历一次典型的渐进式交付过程,从而通过渐进式交付提高交付的稳定性和效率

    1.png

    为什么要 Kruise Rollout

    Kubernetes 只提供了应用交付的 Deployment 控制器,以及针对流量的 Ingress、Service 抽象,但是如何将上述实现组合成开箱即用的渐进式交付方案,Kubernetes 并没有出标准的定义。Argo-rollout 与 Flagger 是社区目前比较流行的渐进式交付方案,但是它们在一些能力和理念上跟我们的设想不太一样。首先,它们仅支持 Deployment, 不支持 Statefulset、Daemonset,更不用说自定义的 operator 了;其次,它们不是“非侵入式的渐进式发布方式” ,例如:Argo-rollout 不能支持社区 K8S Native Deployment、Flagger 对业务创建的 Deployment 进行了拷贝导致 Name 改变而与 Gitops 或自建 Paas 存在一些兼容性的问题。

    另外,百花齐放是云原生的一大特点。阿里云容器团队负责整个容器平台云原生架构的演进,在应用渐进式交付领域也有强烈的需求,因此在参考社区方案以及考虑阿里内部场景的基础上,我们在设计 Rollout 过程中有以下几个目标:

    1. 无侵入性:对原生的 Workload 控制器以及用户定义的 Application Yaml 定义不进行任何修改,保证原生资源的干净、一致

    2. 可扩展性:通过可扩展的方式,支持 K8S Native Workload、自定义 Workload 以及 Nginx、Isito 等多种 Traffic 调度方式

    3. 易用性:对用户而言开箱即用,能够非常方便的与社区 Gitops 或自建 Paas 结合使用

    Kruise Rollout:旁路的渐进式交付能力

    Kruise Rollout [2] 是 Kruise 针对渐进式交付抽象的定义模型,完整的 Rollout 定义:满足配合应用流量和实际部署实例的金丝雀发布、蓝绿发布、A/B Testing 发布,以及发布过程能够基于 Prometheus Metrics 指标自动化分批与暂停,并能提供旁路的无感对接、兼容已有的多种工作负载(Deployment、CloneSet、DaemonSet),架构如下:

    2.png

    流量调度(金丝雀、A/B Test、蓝绿)与分批发布

    金丝雀与分批发布是渐进式交付实践中最常用的发布方式,如下所示:

    1. workloadRef 旁路式的选择需要 Rollout 的 Workload(Deployment、CloneSet、DaemonSet)。
    2. canary.Steps 定义了整个 Rollout 过程一共分为五批,其中第一批只灰度一个新版本 Pod,并且 routing 5% 流量到新版本 Pod,并且需要人工确认是否继续发布。
    3. 第二批发布 40% 新版本 Pod,以及 Routing 40% 流量到新版本 Pod,且发布完成后 sleep 10m,自动发布后面批次。
    4. trafficRoutings 定义了业务 Ingress 控制器为 Nginx,此处设计为可扩展实现,除 Nginx 之外还可以支持 Istio、Alb 等其它流量控制器。
    apiVersion: rollouts.kruise.io/v1alpha1
    kind: Rollout
    spec:
      strategy:
        objectRef:
          workloadRef:
            apiVersion: apps/v1
            # Deployment, CloneSet, AdDaemonSet etc.
            kind: Deployment 
            name: echoserver
        canary:
          steps:
            # routing 5% traffics to the new version
          - weight: 5
            # Manual confirmation, release the back steps
            pause: {}
            # optional, The first step of released replicas. If not set, the default is to use 'weight', as shown above is 5%.
            replicas: 1
          - weight: 40
            # sleep 600s, release the back steps
            pause: {duration: 600}
          - weight: 60
            pause: {duration: 600}
          - weight: 80
            pause: {duration: 600}
            # 最后一批无需配置
          trafficRoutings:
            # echoserver service name
          - service: echoserver
            # nginx ingress
            type: nginx
            # echoserver ingress name
            ingress:
              name: echoserver
    

    基于 Metrics 指标自动化分批与暂停

    Rollout 过程中能够自动的分析业务 Prometheus Metrics 指标,然后与 steps 结合起来,来决定 Rollout 是否需要继续或者暂停。如下所示,在发布完每个批次之后分析过去五分钟业务的 http 状态码,如果 http 200 的比例小于 99.5 将暂停此 Rollout 过程。

    apiVersion: rollouts.kruise.io/v1alpha1
    kind: Rollout
    spec:
      strategy:
        objectRef:
          ...
        canary:
          steps:
          - weight: 5
            ...
          # metrics分析  
          analysis:
            templates:
            - templateName: success-rate
              startingStep: 2 # delay starting analysis run until setWeight: 40%
              args:
              - name: service-name
                value: guestbook-svc.default.svc.cluster.local
    
    # metrics analysis模版
    apiVersion: rollouts.kruise.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=~"{{args.service-name}}",response_code!~"5.*"}[5m]
              )) / 
              sum(irate(
                istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}"}[5m]
              ))
    

    金丝雀发布实践

    1. 假设用户有基于 Kubernetes 部署 echoServer 服务如下,并且通过 nginx ingress 对外服务:

    3.png

    1. 定义 Kruise Rollout 金丝雀发布(1 个新版本 Pod,以及 5% 流量),并 apply -f 到 Kubernetes 集群
    apiVersion: rollouts.kruise.io/v1alpha1
    kind: Rollout
    metadata:
      name: rollouts-demo
    spec:
      objectRef:
        ...
      strategy:
        canary:
          steps:
          - weight: 5
            pause: {}
            replicas: 1
          trafficRoutings:
            ...
    
    1. 升级 echoserver 镜像版本(Version 1.10.2 -> 1.10.3),并 kubectl -f 到 Kuberernetes 集群中
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echoserver
    ...
    spec:
      ...
      containers:
      - name: echoserver
        image: cilium/echoserver:1.10.3
    

    Kruise Rollout 监听到上述行为后,将会自动开始金丝雀发布过程。如下所示,自动生成 canary Deployment、service 以及 Ingress,并且配置 5% 流量到新版本 Pods:

    4.png

    1. 金丝雀一段时间后,业务研发同学确认新版本无异常后,可以通过命令 kubectl-kruise rollout approve rollout/rollouts-demo -n default 发布剩余所有的 Pods。Rollout 会精确的控制后续过程,当发布完成后,会回收所有的 canary 资源,恢复到用户部署的状态。

    5.png

    1. 如果在金丝雀过程中发现新版本异常,可以将业务镜像调整为之前版本(1.10.2),然后 kubectl apply -f 到 Kubernetes 集群当中。Kruise Rollout 监听到该行为,会回收所有的 canary 资源,达到快速回滚的效果。
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echoserver
    ...
    spec:
      ...
      containers:
      - name: echoserver
        image: cilium/echoserver:1.10.2
    

    6.png

    总结

    随着 Kubernetes 上面部署的应用日益增多,如何做到业务快速迭代与应用稳定性之间的平衡,是平台建设方必须要解决的问题。Kruise Rollout 是 OpenKruise 在渐进式交付领域的新探索,旨在解决应用交付领域的流量调度以及分批部署问题。Kruise Rollout 目前已经正式发布 v0.1.0 版本,并且与社区 OAM KubeVela 项目进行了集成,vela 用户可以通过 Addons 快速部署与使用 Rollout 能力。此外,也希望社区用户能够加入进来,我们一起在应用交付领域做更多的扩展。

    7.jpeg

    相关链接

    [1] OpenKruise:

    https://github.com/openkruise/kruise

    [2] Kruise Rollout:

    https://github.com/openkruise/rollouts/blob/master/docs/getting_started/introduction.md

    此处,查看 OpenKruise 项目官方主页与文档!

  • 相关阅读:
    java:maven(maven-ssm(聚合,分包开发))
    java:Maven(Maven_ssm)
    java:Mybatis框架3(二级缓存,延时和积极加载,SSI(Ibatis)集成,SSM集成)
    java:LeakFilling (Mybatis)
    java:Mybatis框架2(基于mapper接口的开发,多种查询,复合类型查询,resultMap定义,多表联查,sql片段)
    java:Mybatis框架1(基本配置,log4j,Junit4(单元测试))
    java:Springmvc框架3(Validator)
    java:Springmvc框架2(Ajax,Json,Interceptor,Upload,Exception)
    WebLogic XMLDecoder反序列化漏洞复现
    Struts2-052 漏洞复现
  • 原文地址:https://www.cnblogs.com/alisystemsoftware/p/16196212.html
Copyright © 2020-2023  润新知