zoukankan      html  css  js  c++  java
  • 云效发布策略指南|滚动、分批、灰度怎么选?

    简介:在日常和用户交流过程中,我们也经常会被用户问到关于发布的问题,比如不同职能团队之间应该如何配合、发布的最佳实践应该是什么样子的等等。今天我们就来聊聊常见应用发布方式的选择,以及每种发布模式适合什么样的场景。

    image.png

    无论从开发运维还是产品运营的角度来看,任何一次上线都是有风险的。从最基本的应用停止导致流量丢失、服务不可用、服务QPS水位下降,到步骤的遗漏、流程的不规范、开发过程中引入的bug,以及新产品/新功能上线导致用户体验的变化,都会导致线上风险。在日常和用户交流过程中,我们也经常会被用户问到关于发布的问题,比如不同职能团队之间应该如何配合、发布的最佳实践应该是什么样子的等等。今天我们就来聊聊常见应用发布方式的选择,以及每种发布模式适合什么样的场景。

    平滑升级:滚动发布

    分批发布通常指取出一例或多例应用实例,将其停止服务、升级到新版本;周而复始地重复这一过程,直到所有实例都升级到新版本。使用滚动发布,可以最大程度地避免因发布导致的流量丢失和服务不可用问题;这一模式也是Kubernetes应用部署使用的缺省模式。

    针对部署规模较小、领域边界较清晰,同时面临业务快速发展变化的微服务应用,滚动发布流程简易且可靠性较高。不过由于通常情况下缺乏强干预手段,发布的可逆程度较差;一旦在发布过程中觉察到问题,往往需要进行全量回滚。

    一般来说,滚动发布适用于符合如下条件的场景:

    • 应用部署规模较小、启动和回滚的速度较快;
    • 应用所关注的业务领域范围相对小、边界较清晰,且易于进行线上回归验证;
    • 发布人员充分理解、掌握平台所提供的滚动发布策略;
    • 新版本引入的变更,具有向下兼容性。

    下面我们分别以ECS和Kubernetes为例,展示如何在云效平台上进行滚动发布。

    面向ECS的滚动发布

    在云效中,我们可以使用主机部署任务进行滚动发布。如图所示,假设需要对以下由2台ECS构成的主机组进行滚动发布,每次滚动更新1台主机:

    image.png

    在流水线中,配置主机部署任务:

    image.png

    设置“暂停方式”为“不暂停”、“分批数量”为2,即可实现滚动发布。

    image.png

    在进行ECS滚动发布时需要注意一点:通常情况下,滚动发布中的主机无法对外提供服务,这意味着集群整体服务水位(如可承接的QPS)会降低——例如在上面2台主机分2批发布的过程中,集群始终只有1台主机可以响应请求,整体QPS水位下降了50%。发布人员需要仔细评估“由于发布而导致服务主机不可用”对服务水位的影响,并选择合适的时间(如业务低峰期)进行发布。

    原生支持:Kubernetes YAML滚动发布

    YAML发布是我们在使用Kubernetes时最直接的应用部署方式。在持续交付流水线中,我们一般将这些用于描述Kubernetes资源的YAML文件通过Git进行统一版本管理,通过云效CI/CD平台监听代码库的变更事件,并通过流水线将这些YAML变更同步到集群当中。

    例如下面的app.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: ${IMAGE}
            ports:
            - containerPort: 80

    由于没有声明发布策略,Kubernetes会缺省指定RollingUpdate策略,也即滚动发布。

    YAML文件中的占位符${IMAGE}是为云效流水线专门留出的替换变量,发布时会被替换成具体的镜像。

    如下图所示,我们可以通过“Kubernetes发布”任务实现上述Deployment的滚动发布:

    image.png

    具体的发布进度,可以参考发布单中的展示:

    image.png

    极简体验:Kubernetes镜像升级

    在一些开发团队与运维团队分工较为明确的场景中,开发团队可能希望够尽可能少地理解Kubernetes相关概念,由专职的运维团队负责完成应用环境的部署和初始化;开发团队只负责完成代码开发,并通过流水线自动化完成应用镜像构建,并使用该镜像对集群中已有的应用进行升级。

    如下图所示,在云效流水线中,我们监听应用代码库的变化,并构建出相应的Docker镜像;发布阶段只需要指定对集群中实例并关联前序任务产生的镜像,即可完成应用的升级发布。与YAML发布相同,缺省情况下,镜像升级也使用了滚动发布模式:

    image.png

    如上所述,该场景适用于:
    • 开发和运维分离:运维团队充分理解Kubernetes的原生发布策略,开发团队只负责产出代码以及应用镜像,由运维团队负责集群中应用的实际运维管理

    过程可控:分批发布

    分批发布通常指取出一批应用实例,将其停止服务、升级到新版本;人工观察实际效果符合期望后,再取出下一批;周而复始地重复这一过程,直到所有实例都升级到新版本。在滚动过程中,新旧版本共存且同等地接受流量、提供服务;发布人员基于对服务质量(如请求成功率、响应时间等基础指标,或特定的业务成功率等业务指标)进行观察,决定是否进一步扩大新版本部署比例,或是放弃发布进行回滚。

    分批发布的基本模式与滚动发布相似,主要差异则在于允许人工控制新版本上线、老版本下线的过程。由于新版本的部署比例可控,发布人员可以预先制定批次部署计划,在少量部署的新版本上,基于生产环境流量进行小规模线上验证;若应用自身规模较大或逻辑较复杂,维持一段时间的小规模验证也能起到线上回归测试的作用。另一方面,人工控制部署批次使得发布整体具有较好的可逆性:一旦在小规模验证中发现问题,可以快速回滚已经发布的新版本。

    分批发布通常适合:

    • 应用在业务链路中较为关键,部署规模较大,业务逻辑较复杂;
    • 进行线上验证时,难以圈定灰度流量,需要使用较少比例的新版本部署进行验证,以期控制风险影响面;
    • 新版本引入的变更,具有向下兼容性。

    面向ECS的分批发布

    在云效中,主机部署任务也可以被配置为分批发布模式,如下图所示:

    image.png

    image.png

    我们可以通过指定“第一批暂停”或“每批暂停”,实现分批控制:
    • 若指定“每批暂停”,则每一批发布完成后,都需要人工确认后方可发布下一批。这种模式适合需要全程控制发布节奏的场景,通过逐步观察线上指标,逐步确认新版本的正确性;或是有明确的发布计划,如“先部署1批(占比10%)、夜间业务低峰期+次日9-11点业务高峰期观察无问题后,按30%、50%、80%、100%实例数递进部署,每批停顿不少于30分钟,期间观察线上指标,若出现问题则回滚”。
    • 若指定“第一批暂停”,则只有第一批发布结束后,会等待发布人员确认;一经确认,此后的各批次将自动部署,与滚动发布类似。这种模式结合了滚动发布的简便性,以及分批发布的小规模验证、快速回滚能力,通常适用于“先进行一批小规模线上验证,验证通过后即可全量发布”的场景。

    发布人员可根据应用的部署规模、重要程度及逻辑的复杂程度,选用不同的分批暂停模式。

    面向Kubernetes的分批发布

    云效的分批发布中,我们以Service为最小发布单元,在发布开始阶段我们将基于新版镜像创建出应用的版本V2,并根据当前应用的副本总数以及分批数量,对新旧两个版本的应用实例分别进行缩容和扩容,来控制实际进入到新版应用的流量比例,从而可以实现小规模的发布验证,在对发布进行充分验证后,再逐步完全下线老版应用。

    与ECS部署类似,批次之间支持暂停和手动恢复,用以对发布过程进行控制。

    image.png

    该模式适用于:采用Kubernetes原生的服务发现机制,并希望获得相比于原生Kubernetes发布更好过程控制性以及安全性的用户。

    流量可控:灰度发布

    较之滚动/分批发布,灰度发布加强了对线上验证影响范围的控制:通常需要以同样的实例数,部署新/老版本两套服务;再通过流量分发控制手段,将特定的线上流量导入新版本、其余流量仍然流入老版本;线上验证通过后,所有流量都将导入新版本实例,而老版本实例则可用作下一次发布的模板。

    常见的流量分发控制手段如:

    • 支持流量在新/老版本之间按比例分配;
    • 支持匹配特定URL/cookie/header/业务字段(如用户ID)的流量,流入新版本。

    使用相对明确的规则进行流量分发控制,从技术团队的角度来看意味着进一步的变更风险控制:发布人员可以选定具有某种特征的请求,用于在验证新发布的功能同时,使得影响范围尽量容易识别。而从产品运营团队的角度来看,灰度发布除了可以更精确地控制技术风险的影响面之外,更重要的一点是可以辅助他们进行客户数据对比:举例来说,运营团队可以事先和某些有意向体验新功能的客户达成合作,使用灰度方式为他们开通新功能进行试用;另一类典型的例子则是A/B test, 通过灰度发布提供的流量控制能力,收集新/老版本的用户数据,用以评估新的设计是否更为合理。

    灰度发布一般适用于:

    • 能够定义流量分发规则(如header、cookie、用户ID等);
    • 变更具有较高的技术风险,或对业务有较大改动,需要将受影响的流量控制在较为精确的范围内(如先让内部员工试用)进行线上验证;
    • 产品运营团队希望使用线上的自然流量,对新/老设计进行比较。

    由于Kubernetes生态提供了很多方便的流量管控手段,我们以kubernetes发布为例,展示如何在云效上进行灰度发布。

    Kubernetes外部流量:Ingress灰度发布

    一种典型的对外接收流量的场景,是使用Ingress暴露服务。在云效流水线的Ingress灰度发布中,我们以Ingress作为发布单元,当触发部署后,将会根据当前Ingress以及其关联的Service/Deployment资源,基于新版镜像创建出V2版本的Service/Deployment,并通过Nginx Ingress的Annoation完成对流量规则声明,从而确保只有满足特定特征的流量才能进入到V2版本中。

    例如在下图的流水线中,我们根据cookie匹配流量,进行灰度发布:

    image.png

    当处于灰度状态时,流水线将会等待人工验证,以触发发布或者或者回滚操作。

    image.png

    Kubernetes内部流量:Istio/ASM蓝绿发布

    当采用微服务架构时,大部分的后端服务只在集群内部开放,微服务之间通过Kubernetes Service进行相互访问。在这种情况下,如果希望采用灰度发布模式,则需要在Service级别进行流量控制,以确保指定的流量进入到灰度的链路,而不对正常用户产生影响。

    不过由于Kubernetes原生Service级别并不支持任何的流量控制规则,因此我们需要在集群中部署Istio或者采用阿里云ServiceMesh来对服务之间的流量进行细粒度的控制。

    如下图所示,当使用Kubernetes蓝绿发布模式时,可以设置灰度流量规则,从而只有当请求中包含指定的Cookie配置的请求转发到灰度版本当中:

    image.png

    该模式适用于:采用Istio或者阿里云ServiceMesh的Kubernetes用户,并且希望能够通过灰度的方式对发布进行验证。

    原文链接
    本文为阿里云原创内容,未经允许不得转载。 

  • 相关阅读:
    Java JMX 监管
    Spring Boot REST(一)核心接口
    JSR 规范目录
    【平衡树】宠物收养所 HNOI 2004
    【树型DP】叶子的颜色 OUROJ 1698
    【匈牙利匹配】无题II HDU2236
    【贪心】Communication System POJ 1018
    【贪心】Moving Tables POJ 1083
    Calling Extraterrestrial Intelligence Again POJ 1411
    【贪心】Allowance POJ 3040
  • 原文地址:https://www.cnblogs.com/yunqishequ/p/15739523.html
Copyright © 2011-2022 走看看