简介:在日常和用户交流过程中,我们也经常会被用户问到关于发布的问题,比如不同职能团队之间应该如何配合、发布的最佳实践应该是什么样子的等等。今天我们就来聊聊常见应用发布方式的选择,以及每种发布模式适合什么样的场景。
无论从开发运维还是产品运营的角度来看,任何一次上线都是有风险的。从最基本的应用停止导致流量丢失、服务不可用、服务QPS水位下降,到步骤的遗漏、流程的不规范、开发过程中引入的bug,以及新产品/新功能上线导致用户体验的变化,都会导致线上风险。在日常和用户交流过程中,我们也经常会被用户问到关于发布的问题,比如不同职能团队之间应该如何配合、发布的最佳实践应该是什么样子的等等。今天我们就来聊聊常见应用发布方式的选择,以及每种发布模式适合什么样的场景。
平滑升级:滚动发布
分批发布通常指取出一例或多例应用实例,将其停止服务、升级到新版本;周而复始地重复这一过程,直到所有实例都升级到新版本。使用滚动发布,可以最大程度地避免因发布导致的流量丢失和服务不可用问题;这一模式也是Kubernetes应用部署使用的缺省模式。
针对部署规模较小、领域边界较清晰,同时面临业务快速发展变化的微服务应用,滚动发布流程简易且可靠性较高。不过由于通常情况下缺乏强干预手段,发布的可逆程度较差;一旦在发布过程中觉察到问题,往往需要进行全量回滚。
一般来说,滚动发布适用于符合如下条件的场景:
- 应用部署规模较小、启动和回滚的速度较快;
- 应用所关注的业务领域范围相对小、边界较清晰,且易于进行线上回归验证;
- 发布人员充分理解、掌握平台所提供的滚动发布策略;
- 新版本引入的变更,具有向下兼容性。
下面我们分别以ECS和Kubernetes为例,展示如何在云效平台上进行滚动发布。
面向ECS的滚动发布
在云效中,我们可以使用主机部署任务进行滚动发布。如图所示,假设需要对以下由2台ECS构成的主机组进行滚动发布,每次滚动更新1台主机:
在流水线中,配置主机部署任务:
设置“暂停方式”为“不暂停”、“分批数量”为2,即可实现滚动发布。
在进行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的滚动发布:
具体的发布进度,可以参考发布单中的展示:
极简体验:Kubernetes镜像升级
在一些开发团队与运维团队分工较为明确的场景中,开发团队可能希望够尽可能少地理解Kubernetes相关概念,由专职的运维团队负责完成应用环境的部署和初始化;开发团队只负责完成代码开发,并通过流水线自动化完成应用镜像构建,并使用该镜像对集群中已有的应用进行升级。
如下图所示,在云效流水线中,我们监听应用代码库的变化,并构建出相应的Docker镜像;发布阶段只需要指定对集群中实例并关联前序任务产生的镜像,即可完成应用的升级发布。与YAML发布相同,缺省情况下,镜像升级也使用了滚动发布模式:
如上所述,该场景适用于:
- 开发和运维分离:运维团队充分理解Kubernetes的原生发布策略,开发团队只负责产出代码以及应用镜像,由运维团队负责集群中应用的实际运维管理
过程可控:分批发布
分批发布通常指取出一批应用实例,将其停止服务、升级到新版本;人工观察实际效果符合期望后,再取出下一批;周而复始地重复这一过程,直到所有实例都升级到新版本。在滚动过程中,新旧版本共存且同等地接受流量、提供服务;发布人员基于对服务质量(如请求成功率、响应时间等基础指标,或特定的业务成功率等业务指标)进行观察,决定是否进一步扩大新版本部署比例,或是放弃发布进行回滚。
分批发布的基本模式与滚动发布相似,主要差异则在于允许人工控制新版本上线、老版本下线的过程。由于新版本的部署比例可控,发布人员可以预先制定批次部署计划,在少量部署的新版本上,基于生产环境流量进行小规模线上验证;若应用自身规模较大或逻辑较复杂,维持一段时间的小规模验证也能起到线上回归测试的作用。另一方面,人工控制部署批次使得发布整体具有较好的可逆性:一旦在小规模验证中发现问题,可以快速回滚已经发布的新版本。
分批发布通常适合:
- 应用在业务链路中较为关键,部署规模较大,业务逻辑较复杂;
- 进行线上验证时,难以圈定灰度流量,需要使用较少比例的新版本部署进行验证,以期控制风险影响面;
- 新版本引入的变更,具有向下兼容性。
面向ECS的分批发布
在云效中,主机部署任务也可以被配置为分批发布模式,如下图所示:
我们可以通过指定“第一批暂停”或“每批暂停”,实现分批控制:
- 若指定“每批暂停”,则每一批发布完成后,都需要人工确认后方可发布下一批。这种模式适合需要全程控制发布节奏的场景,通过逐步观察线上指标,逐步确认新版本的正确性;或是有明确的发布计划,如“先部署1批(占比10%)、夜间业务低峰期+次日9-11点业务高峰期观察无问题后,按30%、50%、80%、100%实例数递进部署,每批停顿不少于30分钟,期间观察线上指标,若出现问题则回滚”。
- 若指定“第一批暂停”,则只有第一批发布结束后,会等待发布人员确认;一经确认,此后的各批次将自动部署,与滚动发布类似。这种模式结合了滚动发布的简便性,以及分批发布的小规模验证、快速回滚能力,通常适用于“先进行一批小规模线上验证,验证通过后即可全量发布”的场景。
发布人员可根据应用的部署规模、重要程度及逻辑的复杂程度,选用不同的分批暂停模式。
面向Kubernetes的分批发布
云效的分批发布中,我们以Service为最小发布单元,在发布开始阶段我们将基于新版镜像创建出应用的版本V2,并根据当前应用的副本总数以及分批数量,对新旧两个版本的应用实例分别进行缩容和扩容,来控制实际进入到新版应用的流量比例,从而可以实现小规模的发布验证,在对发布进行充分验证后,再逐步完全下线老版应用。
与ECS部署类似,批次之间支持暂停和手动恢复,用以对发布过程进行控制。
该模式适用于:采用Kubernetes原生的服务发现机制,并希望获得相比于原生Kubernetes发布更好过程控制性以及安全性的用户。
流量可控:灰度发布
较之滚动/分批发布,灰度发布加强了对线上验证影响范围的控制:通常需要以同样的实例数,部署新/老版本两套服务;再通过流量分发控制手段,将特定的线上流量导入新版本、其余流量仍然流入老版本;线上验证通过后,所有流量都将导入新版本实例,而老版本实例则可用作下一次发布的模板。
常见的流量分发控制手段如:
- 支持流量在新/老版本之间按比例分配;
- Supports traffic matching specific URL, cookie, header, and service fields (such as user ID) to the new version.
Using relatively clear rules for traffic distribution control means further change risk control from the technical team’s point of view: the publisher can select requests with certain characteristics that can be used to validate the functionality of the new release while making the scope of impact as easy to identify as possible. And from the point of view of product operations team, gray released in addition to more precise control of technology risk, however, more important is can assist their customer data comparison: for example, the team can be in advance, and some are interested customers to achieve cooperation experience a new function, using the gray way as they open new function test; Another typical example is A/B test, which collects user data of the new/old version and evaluates whether the new design is more reasonable through the flow control capability provided by grayscale publishing.
Grayscale release is generally applicable to:
- Define traffic distribution rules (such as headers, cookies, and user ids).
- The change has a high technical risk or a large change to the business, so it is necessary to control the affected traffic within a relatively accurate range (for example, let internal employees try it out first) for online verification;
- The product operations team wanted to use the natural flow online to compare new/old designs.
Because Kubernetes ecology provides a lot of convenient means of traffic control, we take Kubernetes publishing as an example to show how to publish in cloud efficiency.
Kubernetes external flow: Ingress grayscale publishing
A typical scenario for receiving outbound traffic is using the Ingress exposure service. In the Ingress grayscale release of cloud effect pipeline, we take Ingress as the release unit. When Deployment is triggered, V2 version of Service/Deployment will be created based on the new version image according to the current Ingress and its associated Service/Deployment resources. And through the Annoation of Nginx Ingress to complete the declaration of traffic rules, so as to ensure that only traffic that meets specific characteristics can enter V2 version.
For example, in the pipeline shown in the following figure, we perform grayscale publishing according to cookie matching traffic:
When in the grayscale state, the pipeline will wait for manual validation to trigger a publish or rollback operation.
Kubernetes internal traffic: Istio/ASM blue green published
When the microservices architecture is adopted, most of the back-end services are only open within the cluster, and the microservices access each other through Kubernetes Service. In this case, if you want to use grayscale publishing mode, you need to control traffic at the Service level to ensure that the specified traffic goes to the grayscale link without affecting normal users.
However, since Kubernetes native Service level does not support any traffic control rules, we need to deploy Istio in the cluster or use Aliyun ServiceMesh for fine-grained control of traffic between services.
As shown in the figure below, when using Kubernetes blue-green publishing mode, grayscale traffic rules can be set so that only requests containing the specified Cookie configuration are forwarded to the grayscale version:
This mode is suitable for Kubernetes users who use Istio or Aliyun ServiceMesh and want to be able to verify their publications in grayscale.
The original link
This article is the original content of Aliyun and shall not be reproduced without permission.