开发者学堂课程【ALPD 云架构师系列-云原生 DevOps36计:云原生持续交付的4大原则-上(一)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/82/detail/1278
云原生持续交付的4大原则-上(一)
云研发时代主流的软件发布形态让持续发布成为可能。
持续发布的前提是做到持续部署
一、持续部署
持续提供稳定、可预期的系统服务。有时针对一些传统持续给别人东西。
它是什么样子?
第一准确,部署结果是准确可预期的,知道部署之后是什么样子,是什么结果。
第二可靠,就整个持续部署的过程中这个线上服务是不受影响的。
第三持续,随着的持续部署的发展发生,有可持续部署的一个软件增量的,就是可以一直有一个增量在那里待发布,那么什么时候想发布是可以发布的。
第四便宜,要为老板考虑的,就整个的持续部署这个过程应该是低成本和高效的。从这几个角度来说,这是提出来的,作为持续部署需要符合的,或者要去做到的四个原则也行。
接下来依次看一下,如何做到这4点。
1、准确、可预期的部署结果
首先原则(1),如何做到可以准确去部署结果。要做到准确部署,依赖于三个前提。那第一个就是明确的待发布制品,第二个是明确的运行环境。第三个是明确的发布过程和发布策略,那针对第一个和第二个,比如明确代发布制品,它需要什么?它需要一个确定的一个代码源,并且它相应的一些依赖,然后最后生成的是一个确定的视频以及它的版本。另外一个明确的运行环境,提高了运行环境里的。第一个包含了在环境里运行的那个制品,它是一个明确的,一个确定的,然后另外一个它的运行的一个上下面是明确确定的配置,那另外一个就是说它本身的环境的一些相应的一些的编排的一个规则是一样的。第三个就是一个过程和发布策略也是需要一个明确具体和一致的,那么这样才可以做到一个准确的部署。关注点在第三点上。
所以这是作为第一点,比如可以看到一个简单的发布的内容,看看发布内容里包含了什么,拿下图例子来看,首先明确有一个页面制,如果在那云校上做过那个发布,肯定有体会,其实在这个的云校上是用环境变量的形式去替换掉的,因为它是从上游过来的,是一个构建的一个产物。那么同时这里面配置了很多的配置,这里有那启动的配置,有容器的那个配置,然后还有一些配置文件。其实还有一些像secret的这样配置,就是里面可能用到的一些密码,证书,那这些东西可能是不会在代码中时候明文的保存,它可能是保存在一个flow这样的平台或者是云校平台上,去注入进来的。那另外一块就是环境,其实都用过云校来做那个课程作业,在云校里面会加配置,这个配置最后就会形成一个环境,这个环境会从 DevOps 平台注入下来,然后整个被发布所用,到最后就会把制品和配置最后发布到这个环境上,就完成了整个的发布
所以发布的内容是什么?发布内容是就是把制品和配置的集合应用到环境集合上的一个过程。所以这里要去确定它是一个确定的一个代发复制品和运行环境,其实在这里是有相应的一些描述的,它会把相应的制品配置和环境都描述清楚,无论是通过平台还是其他的一些平台或者就是明文的,因为它都是把他们组合在一起。然后形成一个发布的内容,
然后这样才可以往后面做第二步,也就是发布出去。这里举了一个例子,就是发布其实是当前的这一个版本和目标的一个版本之间是不一样的,当不一样时,做一些什么事情,然后就验证一下结果,然后做下一个步骤,它是很简单的三步,do, assert, then 这三步, 那它的判断结束是当前是不是跟期望是一样的,所以最简单的发布,cop controrl 拉一下,这就发布完了,那这种发布方式太简单了。它有什么问题?
(1)结果不确定。每次运行的结果都是不可预期的,无法保证结果的一致性。(2)状态不可见。再发布过程中缺乏可观测性,不知道发到哪儿了,有啥问题。(3)过程不可控。一条命令下去之后,是没有反悔的空间的,如果这个版本有问题,有严重的bug,它全部的流量就跌零了,那是没办法去反悔的,这个是非常危险的,所以其实在真正的个发布过程中,是要一个干预手段,比如当发现这个流量会到导致一个很大的下降的,那可能要停止发布,甚至回滚。
2、部署过程不影响线上服务
(1)滚动式部署。采取向灰度这样的方式,让绝大多数服务在哪里,然后持续的,然后灰度的这样滚动的部署上去。当发现没有问题的时候,才切过相应的流量把它切过去,然后做到线上的服务是不中断的,对于滚动式部署,很多时候这个滚动可能是太快了,所以要保证什么,每一个批次的间隔足够监控去发现问题,监控有足够的时间涉及到足够的数据去判断。
(2)部署是可以观测的。整个部署过程,其实有过经验应该都知道,就是部署本身是可能会产生一些报警的。比如部署可能会导致一些服务的有一个节点的一个下降,当然不是服务整个的下降,所以部署本身的监控是要打通的,首先要避免无意义的报警,其次要能够让监控及时的发现现在的一个部署的产生的问题。比如部署两台节点,但是两台节点的它的流量怎么样子?它的服务器情况什么样子或者延迟有没有增加,这些都是需要去监控的。
(3)随时可干预。因为绝大多数时候在部署的过程当中,会发现很多不可确定突然之间冒出来,那么这个时候需要有一些干预手段,比如像一些分流的操作,突然之间可能流量特别大了,这个时候没办法承接住,那么这时要相应的一些切流。其实这个应该积累了很多相关的经验,这些经验可以非常好的去运用到整个部署过程中。
(4)随时可回滚。因为部署过程当中有一些失败情况,相应的修复的一个成本特别高,那么这时如果能快速的做到一个快速的回滚机制,能够让它可以回滚到前面的一个正常的一个版本,然后保证服务不会受到影响。
举例:灰度发布
常见的一个架构,前面有一个负载均衡,负载均衡下面的那个服务版本一般来说就是 V1,但是要发布一个新的版本,叫 V2,可能先从里面加一个节点,就是说1/5的流量用 V2。
然后这个时候可以看到在这种情况下,整个的那个部署情况发生什么?原来所有的Pod 都是在 Deployment-1这个版本上,但是有一个 Pod,现在到了 Deployment-2。就是 Pod 发布多了一个,从上面 Load Balancer 下来,其实到 service 路由的时候,就多了一条。比如,5%的流量走到 Deployment-2上,在这种情况下,会发生什么呢?就是期望是 Deployment-2,它在位子就逐步替换掉 Deployment-1,它的服务慢慢的起来代替很多的 Deployment,然后把 Deployment-1的流量慢慢切过来,那 Deployment-1的流量就慢慢的被替换被下线。然后整个这个过程中,用户是无感知的,整个请求是正常的,然后各类监控,包括基础监控,应用监控,业务监控都是正常的,这是期望的结果,但是这个也是非常常见的,灰度发布的现实情况。
很多时候如果没有很多工具支撑,最常见的做法就是生成一个新的Deployment,要么文件里面有不同的内容,这个内容可能带了一个版本号或者什么东西,然后同时存在两个Deployment的那个版本,通过不断的去调整两边的那个的数量,去达到一个灰度发布的一个目的,这是最普通的,最常见的,因为这个成本很低,所以它的缺点是可能没法做很精致的流量控制。但是 anyway,如果整个服务量不大,其实是可以考虑这种方式的,但这种发布的形式其实于服务有一些要求。首先要求什么?对于某一个具体的 service 的时候,其实最多只有一个进行中的发布。因为需要去做一个流量的,一个不断的一个切换去做验证的过程。
第二个对于某一个 service,发布完成后,应该只有一个版本的 Deployment 在运行,就是不允许两个同时存在。否则会产生一种困惑,它现在到底发布完成没有?是有什么问题?
第三个在这个过程中,其实是存在两个版本的 Deployment,就是有两个版本的服务在提供,要保证这两个版本它的服务都能够正确提供,而且不管它的上游是什么,下游是什么,它都能正确处理业务请求。然后这样要求这个服务是要做到形象兼容的。
第四个是整个的发布过程不能造成服务的中断,这个要求就比较多了,比如普通的短连接的服务,保证这个 service 的东西不会因为这个发布而导致它前后断开或者前后不连续,如果是常连接的,要保证这个连接能够自动的迁移到新的服务上,这里有很多的要求。
那最后一个就是说整个发布过程不会造成用户请求的错误,整个发布不会很鲁莽的把某一个请求直接 shift down 掉,而是一个机制,保证它处理完之后,不接受新的请求,在这种情况下才能够保证做到期望的一个灰度发布的一个效果,所以可以看到整个这个灰度发布过程,它不仅仅是对发布的工具,发布的策略有一些要求,它其实对应用程序本身有不少的要求,要做到很多方面才能够达到一个非常平滑的一个灰度发布,所以基于此总结了几点,针对于灰度发布一些实践的一些建议,供参考一下。



