当前位置: 首页 > 后端技术 > Java

云效率发布策略指南|滚动、批量、灰度如何选择?

时间:2023-04-01 19:10:42 Java

介绍:在日常与用户交流的过程中,我们经常会被用户问到关于发布的问题,比如不同职能团队应该如何合作,最好的发布实践应该是什么样子等等。今天我们就来聊一聊常见的应用发布方式的选择以及每种发布方式适用于哪些场景。无论从开发运维还是产品运营的角度,任何上线都是有风险的。从最基本的应用停止导致流量丢失、服务不可用、服务QPS水平下降,到步骤遗漏、流程不规范、开发过程中引入的BUG、新产品/功能上线带来的用户体验变化,都会导致上网风险。在日常与用户交流的过程中,我们经常会被用户问到关于发布的问题,比如不同职能团队之间如何合作,最好的发布实践应该是什么样子等等。今天我们就来聊一聊常见的应用发布方式的选择以及每种发布方式适用于哪些场景。平滑升级:滚动发布批量发布通常是指取出一个或多个应用实例,停止其服务,升级到新版本;一遍又一遍地重复这个过程,直到所有实例都升级到新版本。滚动发布可以最大程度地减少发布带来的流量损失和服务不可用问题;该模式也是Kubernetes应用部署的默认模式。对于部署规模小、领域边界清晰、业务发展变化快的微服务应用,滚动发布过程简单可靠。但由于普遍缺乏强有力的干预手段,释放的可逆性较差;一旦在发布过程中检测到问题,通常需要进行全面回滚。一般来说,滚动发布适用于满足以下条件的场景:应用部署规模小,启动和回滚速度快;应用关注的业务领域比较小,边界清晰,容易进行在线回归验证;发行商充分理解并掌握平台提供的滚动发布策略;新版本引入的更改是向后兼容的。下面以ECS和Kubernetes为例,介绍如何在云平台上进行滚动发布。面向ECS的滚动发布在云效应中,我们可以使用主机部署任务进行滚动发布。如图所示,假设如下由2台ECS组成的主机组需要转出,每次更新一台主机:管道中,配置主机部署任务:设置“暂停方式”为“不暂停”",""批量"为2,可以实现滚动发布。ECS滚动发布需要注意的一件事:通常情况下,滚动发布中的主机不能对外提供服务,这意味着集群的整体服务水平(比如可以承担的QPS)会降低——比如上面2台主机分成2批发布过程中,集群中只有一台主机可以响应请求,整体QPS水平下降50%。发布者需要仔细评估“发布导致服务主机不可用”对服务水位的影响,选择合适的时间(如业务低峰期)发布。原生支持:KubernetesYAML滚动发布YAML发布是我们使用Kubernetes最直接的应用部署方式。在持续交付流水线中,我们一般通过Git来管理这些用于描述Kubernetes资源的YAML文件进行统一的版本管理,通过云效CI/CD平台监控代码库的变更事件,并通过云效CI/CD平台将这些YAML变更同步到集群中管道。例如下面的app.yaml:apiVersion:apps/v1kind:Deploymentmetadata:name:nginx-deploymentlabels:app:nginxspec:replicas:3selector:matchLabels:app:nginxtemplate:metadata:labels:app:nginxspec:containers:-name:nginximage:${IMAGE}ports:-containerPort:80由于没有声明发布策略,Kubernetes会默认指定RollingUpdate策略,即滚动发布。YAML文件中的占位符${IMAGE}是专门为云效管线预留的替换变量,发布时会替换为具体图片。如下图所示,我们可以使用“Kubernetes发布”任务来实现上述Deployment的滚动发布:具体发布进度请参考发布单中的展示:极简体验:Kubernetes镜像升级相对分为开发团队和运维团队。在特定场景下,开发团队可能希望尽量少了解Kubernetes相关概念,由专职运维团队负责完成应用环境的部署和初始化;开发团队只负责完成代码开发,并通过流水线自动化完成应用镜像的构建,并使用镜像升级集群中已有的应用。如下图所示,在云效管道中,我们监控应用代码库的变化,并构建相应的Docker镜像;在发布阶段,我们只需要指定集群中实例生成的镜像,并关联前面的任务即可完成应用。升级发布。和YAML发布一样,默认情况下,镜像升级也是采用滚动发布模式:上面说了,这种场景适用于:开发运维分离:运维团队充分了解Kubernetes的原生发布策略,以及开发团队只负责生产集群中应用的实际运维管理过程由运维团队控制:批量发布通常是指取出一批应用实例,停止其服务,并将它们升级到新版本;效果符合预期后,取出下一批;一遍又一遍地重复此过程,直到所有实例都升级到新版本。滚动过程中,新旧版本并存,平等接收流量和提供服务;发布者决定是进一步扩大新版本的部署比例,还是放弃发布回滚。批量发布的基本模式类似于滚动发布,主要区别在于它允许手动控制新版本上线和旧版本下线的过程。由于新版本的部署比例可控,发布人员可以提前制定批量部署计划,对部署的少量新版本进行基于生产环境流量的小规模在线验证;如果应用本身规模较大或者逻辑复杂,维护一段时间的小规模验证也可以作为在线回归测试。另一方面,部署批次的人工控制使得整体发布的可逆性更强:一旦在小规模验证中发现问题,可以快速回滚已经发布的新版本。批量发布通常适用于:应用在业务环节较为关键,部署规模较大,业务逻辑较为复杂;在线验证时,灰度流量难以划定,需要使用小比例的新版本部署进行验证,以控制风险影响面;新版本引入的更改是向后兼容的。ECS批量发布在云效果中,主机部署任务也可以配置为批量发布模式,如下图:我们可以通过指定“首批暂停”或“每批暂停”来实现批量控制:如果指定“暂停每批”,每批下达后,需要人工确认后才能下批下达。这种模式适用于需要全程控制释放节奏的场景。通过逐步观察线上指标,逐步确认新版本的正确性;或者有明确的发布计划,比如“先部署1批(10%),夜间业务低峰期+次日9-11点业务高峰期。观察无问题后,实例按30%、50%、80%、100%递进部署,每批暂停不少于30分钟,期间观察在线指标,出错回滚”。如果指定“首批暂停”,只有首批发布完成后,才会等待发布人员确认;一旦确认,后续批次将自动部署,类似于滚动发布。这种模式结合了滚动发布的简单性和批量发布的小规模验证和快速回滚能力。通常适用于“先做一批小规模线上验证,验证通过后全量发布”的场景。发布者可以根据应用的部署规模、重要性和逻辑复杂度,选择不同的批量暂停模式。Kubernetes的批量发布在云效果的批量发布中,我们以Service作为最小的发布单元。在发布之初,我们会基于新版本镜像创建应用的V2版本,并根据当前应用的总副本数和批次数,缩容和扩容应用实例新旧版本分别控制实际进入新版本应用的流量比例,实现小规模的发布验证。发布完全验证后,老版本将逐步下线应用。与ECS部署类似,可以暂停和手动恢复批处理以控制发布过程。该模式适用于采用Kubernetes原生服务发现机制,希望获得比原生Kubernetes版本更好的流程控制和安全性的用户。流量可控:相对于滚动/批量发布,灰度发布加强了对在线验证范围的控制:通常需要部署两套新/旧版本服务,实例数相同;然后通过流量分发控制方式,将特定在线流量导入新版本,其余流量仍然??流入旧版本;在线验证通过后,所有流量将导入新版本实例,旧版本实例可作为下一次发布的模板。常见的流量分配控制方式包括:支持新旧版本按比例分配流量;支持匹配特定URL/cookie/header/业务字段(如用户ID)的流量流入新版本。使用相对清晰的规则进行流量分发控制,意味着从技术团队的角度进一步改变风险控制:发布者可以选择具有某些特征的请求来验证新发布的功能,并使影响范围尽可能易于识别。从产品运营团队的角度来看,灰度发布除了可以更精准地控制技术风险的影响外,还可以辅助他们比对客户数据:比如运营团队可以提前与某家公司沟通一些客户有兴趣体验新功能达成合作,采用灰度方式开放新功能供其试用;另一个典型的例子是A/B测试,它收集新/旧版本的用户数据来评估新设计是否更合理。灰度发布一般适用于:能够定义流量分发规则(如header、cookie、userID等);变更具有较高的技术风险,或者业务有较大变更,受影响的流量需要控制在更精准的范围内进行在线验证(例如让内部员工先试用);产品运营团队希望利用线上的自然流量来对比新旧设计。由于Kubernetes生态提供了很多便捷的流量控制方式,我们以Kubernetes的发布为例,展示如何在云上进行灰度发布效果。Kubernetes对外流量:Ingress灰度发布是一个典型的对外接收流量的场景,就是利用Ingress来暴露服务。在云效流水线的ingress灰度发布中,我们以Ingress为发布单位。当deployment被触发时,会基于当前Ingress创建一个V2版本的Service/Deployment,并基于新版本的镜像创建其关联的Service/Deployment资源,并通过Announation完成流量规则的声明NginxIngress,以保证只有满足特定特征的流量才能进入V2版本。比如下图中的pipeline,我们根据cookie匹配流量,进行灰度发布:当处于灰度状态时,pipeline会等待人工验证触发发布或回滚操作。Kubernetes内部流量:Istio/ASM蓝绿发布在使用微服务架构时,大部分后端服务只在集群内部开放,微服务之间通过KubernetesService相互访问。这种情况下,如果要采用灰度发布方式,需要在Service层面进行流量控制,保证指定流量进入灰度链路,不影响正常用户。但是由于Kubernetes原生的Service级别不支持任何流控规则,所以我们需要在集群中部署Istio或者使用阿里云ServiceMesh对服务之间的流量进行细粒度的控制。如下图,在使用Kubernetes蓝绿发布模式时,可以设置灰度流量规则,只将包含指定cookie配置的请求转发到灰度版本:该模式适用于:使用Istio或AlibabaServiceMesh的CloudKubernetes用户,并希望能够以灰度方式验证发布。原文链接本文为阿里云原创内容,未经许可不得转载。