开发者学堂课程【ALPD 云架构师系列:云原生 DevOps 36计-阿里云云效出品:云原生持续交付的4大原则-上】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/772/detail/13507
云原生持续交付的4大原则-上
内容介绍:
一.持续发布的前提:持续部署
二.原则#1/4:准确、可预期的部署结果
三.原则#2/4:部署过程不影响线上服务
一.持续发布的前提:持续部署
(持续提供稳定、可预期的系统服务)
云原生时代主流的软件发布形态让持续发布成为可能,而持续发布的前提,就是持续部署。
有的时候,针对一些传统的来说发布的话,可能持续发布给别人东西,比如我给你一个光盘,再给你一个光盘,这样你自己做,但实际上可能中间会停机的。就像我们今天麦克可能出现出了一个问题,那我中间停机,它更新了一下。那么它更新的这段时间就不能用了,这就是一个非持续的部署形态。那所谓的持续部署,是什么样子呢?
1.准确、可预期的部署结果
2.部署过程不影响线上服务
3.有可持续部署的软件增量
4.低成本、高效地部署发布
接下来,我们了解一下持续部署的四大原则。
二.原则#1/4:准确、可预期的部署结果
1.,原则
⑴明确的待发布制品(及配置)
⑵明确的运行环境
⑶明确的发布过程及发布策略
明确的待发布制品需要一个确定的代码源,以及相应的一些依赖,然后最后生成一个确定的制品和版本。另外明确的运行环境里也提到了验证环境,第一个包含了在环境里运行的制品是明确的、确定的。然后另一个运行的上下文是明确、确定的配置,并且它本身环境的一些相应的变化、变快的策略是一样。第三个的一个过程和发布策略也需要明确、具体和一致,这样你才可以做到一个正确的部署。
2.举例
首先看这么一个简单的发布内容,让那么这里包含了什么。
首先,这里有多的配置,有启动配置、容器配置,还有一些配置文件。甚至于还有一些像secret的这样的,比如说我们可能用到的一些密码、证书这样的东西,这些东西可能不会在我们的代码中明文的保存,而是保存在其他平台。
另外一块就是环境,我们会把制品和配置最后发布到环境上,来完成了整个发布。
所以说,发布的内容就是把制品和配置的集合应用到环境集合上的一个过程。所以我们要确定它是一个确定的、明确的一个待发布制品和运行环境。这些是有相应的一些描述的,它会把相应的制品配置和环境都描述清楚,无论是通过什么平台,它们都会组合在一起,然后发布成一个内容,然后这才可以往做后面的第二步。
2.最简单的发布:,while(current,!=,target),{do;,assert;,then;},
如果当前发布的的版本和目标的版本之间是不一样的,我们首先应该做什么?,首先做一些什么事,验证一下结果,然后做下一个步骤。
这种发布方式好像太简单了,那么有什么问题吗?
⑴结果不确定
每次运行的结果都是不可预期的,无法保证结果的一致性。
⑵状态不可见
在发布过程中,缺乏可观测性,不知道发到哪了,有何问题。
⑶过程不可控
在发布过程中,无法实施有效的干预手段,对发布流程缺乏管控措施。
三.原则#2/4:部署过程不影响线上服务
1.,原则
⑴滚动式部署
采取像灰度发布这样的发布策略,分批滚动部署,做到线上服务不中断。
比如说,我们可以采取像灰度这样的方式,那绝大多数服务在哪里,然后持续的灰度的滚动式部署上去的,当我发现没有问题的时候,我才会切过相应的流量,把它切过去,然后让我做到线上的服务是不中断的。对于滚动式部署呢,很多时候这个滚动可能太快了,我们要保证每一个批次的间隔足够我们监控并去发现问题,要能有足够的时间涉及到足够的数据判断。
⑵部署可观测
部署过程中,实时监控线上服务及部署进度,问题及时反馈响应。
部署是可以观测的。整个部署过程一般可能会产产生一些报警,比如说部署可能会导致一些服务的一个节点的下降,但不是整个服务的下降。所以部署本身的监控是要打通的,首先,要避免无意义的报警,其次要让监控及时的发现产生的问题,比如说我就部署两个节点,但是也要监控它的流量什么样,服务情况什么样。
⑶随时可干预
对部署过程中的异常问题可以及时干预,如分流等操作,保障服务的可用性。
因为绝大多数时候,我们在部署的过程当中会发现,因为很多不可确定的问题突然冒出来,我们需要有像一些干预手段,比如分流的操作。因为可能突然之间流量特别大,这时你没办法承接住,就需要记得很多相关的经验,去运用到整个部署过程中。,
⑷随时可回滚
对部署过程中失败等情况,可以快速及时选择正常版本进行回滚。,
如果你的干预很难解决掉问题,那这时你就需要做到随时可回滚。因为部署过程当中有一些失败情况,可能相应的修复成本特别高,这时如果能快速的做到一个快速的回滚机制,就能够让它回滚到前面的一个正常的版本,然后保证你的服务不会受到影响,所以其实部署过程不影响线上服务。
2.举例:灰度分布
这是灰度发布非常常见的一个架构就是这样子的,前面讲到有一个复载均衡,它的服务版本一般是 v1,但是现在要发布一个新的v2的版本,就需要先在里面加一个节点。
但是,我现在要发布一个新的版本叫b2,我可能先从里面加一个节点,就是1/5的流量我用 v2。然后这时,我们可以看到,在这种情况下,部署情况就会发生一些事情,原来所有 Pod 都是在 Deployment-1上,但是现在有一个 Pod 现在到了Deployment-2上。
就是我的 Pod 发布多了一个,那多了一个,其实就可以通过其他手段去控制它走,比如5%的流量走到20%。那在这种情况下,会发生什么呢,就说我们希望是这样子,多的 Deployment-2就逐步被替换掉,你的Pod服务就慢慢的起来了,然后把流量慢慢切过来。那 Deployment-2的的流量,就慢慢的被替换、被下线。然后整个这个过程中呢,用户是无感知的,整个请求是正常的。然后呢,各类监控,包括基础监控、应用监控、业务监控数都是正常的,这就是我们期望的结果。但是这个也是非常常见的一个灰度发布的一个现实情况。是我们很多时候如果没有很多工具支撑的话,最常见的做法。就是可能,我生成一个新的样本文件,里面有不同的内容,它可能带了一个版本号或者什么东西。然后,我同时存在两个地方的那个版本,然后通过不断的去调整两边的数量,去达到一个灰度的目的,这是最普通的、最常见的,因为这个成本很低。但是它的缺点可能是,没法做很精细的流量控制,但是如果服务量不大,其实是可以搞定的。
3.期望结果:
⑴Deployment-2在service相关的所有 pod 上运行
⑵Deployment-1逐步被替换并下线
⑶发布过程中用户请求正常
⑷各类基础监控、应用监控和业务监控数据正常
4.对发布的要求:
⑴对于某一个 service,最多只有一个进行中的发布。
因为这里需要做一个流量的不断切换去做验证的过程
⑵对于某一个service,发布完成后,只有一个版本的 deployment 在运行。
如果不允许两个同时存在,这样的话会产生很多困惑
⑶发布过程中,同时存在的两个版本的deployment都能正确处理业务请求。
有时候有两个版本的服务在提供,那么我要保证这两个版本服务都能正确提供,而且不管它的上下游是什么,都应该能正确处理业务,这就要求这个服务是要做到兼容。
⑷整个发布过程不会造成服务的中断
比如说,普通的短连接服务,需要保证这个筛选不会因为这个发布,而导致前后断开,或者前后不连续。如果是常连接的,那我要保证这个连接,能够自动的迁移到新的服务上。,
⑸整个发布过程不会造成用户请求的错误
这里需要一个机制,保证它处理完之后,不接受新的请求。这种情况下,才能够保证做到一个期望的灰度发布的效果。
所以整个灰度发布的过程,不仅是对发布的工具好,对发布的策略也好,但它其实对应用程序本身有不少要求。我们要做到很多方面才能够就达到一个非常平滑的灰度发布。所以说基于此,我们总结了几点针对灰度发布的一些实践建议,供大家参考一下。
5.灰度发布的实践建议
⑴应用需要保证对前一个(或数个)版本的兼容。
版本的兼容数量的取决于应用的线上情况,有时候线上会同时存在几个版本的应用,那我们就要保证这几个版本的兼容性。
⑵创建一个新的 deployment,,提供同样的 service,通过调整 pod 数或者 ingress流量来进行灰度。
这种灰度的情况下,我们可以很精细的去控制它,所以这里比较建议,通过流量去控制。
⑶定义灰度批次以及每一批的比例和观察时间(保证监控有足够的数据可以发现问题)。
灰度的批次应该设计的合理,而且保证每个批次之间的间隔有足够的时间,让我们去发现并做处理。如果灰度特别快、时间特别短,那有可能这个监控还没有来得及报警,它就进入下一个更大的批次了,也有可能会带来非常大的风险。
⑷除了关注基础监控和应用监控外,也需要关注业务监控,发现异常应立即暂停发布。
监控是一个很大的范畴,很难几句话把它说清楚。但是从发布的角度讲,我们的最终目的是要避免发布带来的业务损失。业务损失可能包含很多,比如说发布导致业务不可用,或者业务出现错误,但是更严重的可能是业务发布带来的某一些观测指标产生一个大的变化。比如说用户转化率,或者是其他的一些,就是用户的那个登录成功次数这种事情发生大的变化,在这种情况下就是一个异常的数据,而这个异常数据应该及时被发现,并且当这种情况发生时,应该立即暂停掉。
⑸先切换流量,观察一段时间后,再清理Pod。
这是为了将来做回滚的时候更高效。如果这个Pod还在,我就可以用很快的流量切过来。如果我把它全部清理掉,那我再次回滚的时候,就需要重新去创建,重新拉去镜像,这就会很慢。
⑹记录下发布的版本,方便进行回滚
记录版本是为了下一步的回滚,除了具体版本,我们还要知道这个版本在哪个位置,哪一些地方部署。另外,如果你记下了相应的版本,一些相应合规的也可以同样的做到回滚和部署。
⑺回滚≠重新发布,可能与发布有不同的策略
首先策略不一样,回滚不可能说跟发布那样每个批次很小,有可能为了解决问题,需要做大量的批次,然后就它的策略和发布也是不同的。
⑻如果系统为多租户,可以基于租户进行流量隔离和AB测试
这个方式会很方便,尤其 a,b 测试。
6.蓝绿部署
蓝绿部署和灰度其实是差不多的,只是所需要的资源一个会更多一点,一个非 a 即 b,一个先 a 增加上2a 的概念。
这两种的选择取决于你本身的软件的部署形态,和机器的资源数量,以及相应的一些决定。
除了这些,像金丝雀也是类似的,这种也是灰度方式,不过蓝绿比灰度对软件的要求会更低一点,可以保证整个应用都不上去之后才去切。但灰度不行,我们要持续能够上去,相对来说风险比较高。
但如果要做到不影响线上的服务,除了部署的一些策略之外,有时我们会遇到相应的其他的一些问题。比如说,软件
只开发了一半,或者服务已经部署上去,然后需要和别的服务配合才能作为一个完整的系统服务提供给用户。那么这个时候,我们可能会用到相应的特性开关的这种方式。
其实就是想有一些配置文件,一般都是动态配置的形式下发。
这就好比移动端的更新是比较固定的,需要应用市场去推,可能一个月推一次,这种情况下其实服务端早上去了,但是有些特性开不了。移动端放上去之后,我们才能去开某个特性。这时我们一般会采用动态配置的方式,然后给它一个特性开关。真正的特性是等到客户端或者前端发布上去之后,我们通过相应的动态的特性开关配置,然后把它从内部起来。所以严格上来说,特性开关的打开本身其实也是一次发布,而且也是一个版本管理。无非我们的目标就是做到不中断线上服务,任何时候,任何人都可以放心的发布软件。
任何时候,这个服务都可能会有很多人在访问,也有很多时候没有很多人在访问,但是不管任何时候你都能发,并且任何人都可以放心。
而且发布的操作是特别简单的,不需要掌握什么技能,只要点一下它就发上去。
而且还有另外一个放心的发布方向,发布意味着之后不会出现什么大纰漏,或者说出现纰漏,有一个兜底的一个方式。
7.愿景:任何时候任何应用都可以发布上线
想要任何时候任何应用都可以发布上线,就需要有非常完整的技术保障,包括相应一些实践来保证发布的安全性和可靠性。因为一旦出现问题,可能就导致故障。而且这种时候可能产生一些雪崩效应,就可能会带来一系列的故障和问题,可能最后整个系统就会瘫痪掉。




