DevOps的CI/CD及常见的软件发布方式

                                              作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.持续集成,持续交付和持续部署

1.CI/CD概述

最初是瀑布模型,后来是敏捷开发,现在是DevOps,这是现代开发人员构建出角色的技术路线。

随着DevOps的兴起,出现了 持续集成(Continuous Integration),持续交付(Continuous Delivery),持续部署(Continuous Deployment)的新方法。
	- 持续集成(Continuous Integration)
		集成指将多位开发者的开发代码提交后,合并集成在一起,存放在代码库的过程,并且后续还会不断的迭代更新代码。
		持续集成是值多名开发者在开发不同功能代码的过程当中,可以频繁的将代码合并到一起并且互相不影响工作。
		持续集成强调开发人员提交了新代码之后,立刻进行构建,(单元)测试。
        
	- 持续交付(Continuous Delivery)
		持续交付的目标是拥有一个可以随时部署到生产环境的代码库。
	
	- 持续部署(Continuous Deployment)
		持续部署可以自动将应用部署到生产环境。
		 
	
传统的软件开发和交付方法正在迅速变得过时,从以前的敏捷时代,大多数公司会每月,每季度,每两年发布/发布软件。

然而现在在DevOps时代,每周,每天,甚至每天多次是常态。当SaaS正在占领世界时,尤其如此,您可以轻松地动态更新应用程序,而无需强迫客户下载新组件。

很多时候,他们甚至不会意识到正在发生变化。开发团队通过软件交付流水线(Pipeline)实现自动化,以缩短交付周期,大多数团队都有自动化流程来检查代码并部署到新环境。


CI/CD是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法。CI/CD的核心概念是持续集成,持续交付和持续部署。作为一个面向开发和运营团队的解决方案,CI/CD主要针对在集成新代码时所引发的问题。

具体而言,CI/CD可让持续自动化和持续监控贯穿于应用的整个生命周期(从集成和测试阶段,到交付和部署)。这些关联的事务通常被统称为"CI/CD管道",由开发和运维团队以敏捷方式协同支持。


CICD红帽参考链接:
	https://www.redhat.com/zh/topics/devops/what-is-ci-cd
	
	
推荐阅读:
	https://docs.gitlab.com/ee/ci/introduction/

2.持续集成(Continuous Integration)

集成指将多位开发者的开发代码提交后,合并集成在一起,存放在代码库的过程,并且后续还会不断的迭代更新代码。

持续集成是值多名开发者在开发不同功能代码的过程当中,可以频繁的将代码合并到一起并且互相不影响工作。

很多情况下每天都要进行几次,主要目的是尽量早发现集成错误,使团队更加紧密结合,更好的协作。

CI属于开发人员的自动化流程。成功的CI意味着应用代码的新更改会定期构建,测试并合并到共享存储库中。

该解决方案可以解决在一次开发中有太多应用分支,从而导致互相冲突的问题。

持续集成强调开发人员提交了新代码之后,立刻进行构建,(单元)测试。

根据测试结果,可以确定新代码和原有代码能否正确地集成在一起。通过持续集成可以自动编译,打包,签名项目,配合单元测试可以实现持续集成+自动化测试。

让工程师从重复而又枯燥的手动打包代码完全释放出来,让工程师更加专注于代码本身,最大限度的减少误操作风险,降低修复错误代码的成本,大幅图提高效率。

3.持续交付(Continuous Delivery)

完成CI中构建及单元测试和集成测试的自动化流程后,持续交付可以自动的将已验证的代码发布到存储库。

为了实现高效的持续交付,务必确保CI已内置于开发管道。持续交付的目标是拥有一个可以随时部署到生产环境的代码库。

在持续交付中,每个阶段(从代码更改的合并,到生产就绪型构建版本的交付)都涉及测试自动化和代码发布自动化。

在流程结束时,运维团队可以快速,轻松地将应用部署到生产环境中。

持续交付完成了构建和测试过程细致的自动化,但是如何发布以及发布什么仍然是需要人工操作,持续部署可以改变这一点。

持续集成(Continuous Integration)指的是开发人员频繁的(一天多次的)将所有开发者合并到主干上。这些新提交最终合并到主线之前,都需要通过编译和自动化测试进行验证。以保障所有的提交在合并主干之后的质量问题,对可能出现的一些问题进行预警。持续集成的核心在于确保新增的代码能够与原先代码正确的基础。

持续交付在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境的类生产环境(production-like environments)中。

比如,我们完成单元测试后,可以把代码部署到链接数据库的Staging环境中更多的测试。如果代码没有问题,可以继续手动部署到生产环境中。此方式是当前普遍采用的方式。

4.持续部署(Continuous Deployment)

对于一个成熟的CI/CD管道来说,最后的阶段是持续部署。作为持续交付(自动将生产就绪型构建版本发布到代码存储库)的进一步延伸,持续部署可以自动将应用部署到生产环境。由于在生产环境之前的管道没有手动风控,因此持续部署在很大程度上都得依赖精心设计的测试自动化。

实际上,持续部署意味着开发人员对应用的更改在编写后的几分钟内就能生效(假设它通过了自动化测试)。这更加便于持续接收和整个用户反馈。总而言之,所有这些CI/CD的关联步骤都有助于降低应用的部署风险,因此更便于以小件的方式(而非一次性)发布对应用的更改。不过,由于还需要编写自动化测试以适应CI/CD管道中的各种测试和发布阶段,因此前期投资还是会很大。


持续部署是基于某种工具或平台实现代码自动化构建,测试和部署到线上环境以实现交付高质量的产品,持续部署在某种程度上代表了一个开发团队的更新迭代速率。


与持续集成相比,持续交付(Continuous Delivery)的侧重点在于交付,其核心对象不在于代码,而是在于可交付的产物。由于持续集成仅仅针对新旧代码的集成过程执行了一定的测试,其变动到持续交付后还需要一些额外的流程。与持续集成相比较,持续交付添加了测试Test ---> 模拟Staging ---> 生产Production的流程,也就是为新增的代码添加了一个保证: 确保新增的代码在生产环境中是可用的。

在持续交付的基础上,把部署到生产环境的过程自动化。如果你对比上图持续部署就可以发现持续部署和持续交付的区别就是最终部署到生产环境是自动化的。因为自动发布存在较大的风险,当前采用此方式较少。

5.CI/CD流程架构

应用部署发展阶段:
    - 开发人员自行上传代码:
        早期项目,没有专业的运维人员,运维的工作由开发兼职完成,项目发布很不专业,很容易出错,也是最原始方式。

    - 开发人员先将代码发给运维,再由运维手动上传至生产环境:
        专业的运维人员完成应用的部署,每次项目发布都由运维人员一步一步手动实现,效率低下且容易出错。

    - 运维利用脚本和自动化运维工具实现部署:
        由运维人员编写shell,Python等脚本或利用自动化运维工具,如ansible等实现半自动化应用部署,效率很高,但对技术的专业性有较高要求。

    - 通过web等GUI界面实现一键自动化部署:
        可以通过开源或自研的运维平台实现方便的应用部署,操作容易,效率高,但需要提前构建运维平台。
        
        
如上图所示,为典型的DevOps代码发布流程实现CI/CD。
	- 开发人员不断进行代码提交到本地,在提交到远程的代码仓库服务器。
	- Jenkins作为持续集成工具,使用Git工具到git仓库拉取代码到集成服务器,代码测试与审查,在配合JDK,Maven,Go等软件完成代码编译,测试,打包等工作,在这个过程中每一步如果出错,都需要重新在执行一次整个流程。
	- Jenkins把生成的软件jar或war包等分发到测试服务器或生产服务器,测试人员或用户就可以访问应用。

二.常见的软件发布方式

1.蓝绿部署(Blue-green Deployment)

蓝绿部署指的是不停止老版本(不影响上一个版本访问),而是在另外一套环境部署新版本然后进行测试,测试通过后将用户流量切到新版本,其特点为业务无中断,升级风险相对较小。但本方式成本较高,一般小公司较小使用。

蓝绿部署是一种部署策略,利用两种相同的环境,即"蓝色"(又名预发布)环境和"绿色"(又名生产)环境,具有不同版本的应用程序或服务。质量保证和用户接收度测试通常在承载新版本或更改的蓝色环境中进行。一旦蓝色环境中测试并接收新的变化,用户流量就会才能从绿色环境转变为蓝色环境。然后,一旦部署成功,您可以切换到新环境。

蓝绿部署具体流程如下:
	- 当前版本(V1)业务正常访问;
	- 在另外一套环境部署新代码版本(V2),代码可能是增加了功能或者是修复了某个bug;
	- 测试通过之后将用户请求流量切到新版本环境;
	- 观察一段时间,如有异常直接切换旧版本;
	- 下次升级,将旧版本(V2)升级到新版本(V3);
	
	
蓝绿部署适用的场景:
	- 不停止老版本,额外部署一套新版本,等测试确认新版本正常后,才将用户请求切换至新版本,如果有问题,切换会老版本;
	- 蓝绿发布是一种用于升级与更新的发布策略,部署的最小维度是容器,而发布的最小维度是应用;
	- 蓝绿发布对增量升级有比较好的支持,但是对于设计数据表结构变更等等不可逆转的升级,并不完全合适使用蓝绿发布来实现,需要结合一些业务的逻辑及数据迁移与回滚的策略才能完全满足需求;

2.金丝雀(灰度)发布(Canary Deployment)

"金丝雀"的由来: 17世纪应该矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯,金丝雀也会停止唱歌,而当瓦斯含量超过一定限度时,虽然人类毫无察觉,金丝雀却早已经毒发身亡。当时采矿设备相对简陋的条件下,工人每次下井都会带上一只金丝雀作为"瓦斯检测指标",以便在危险状况下紧急撤离。

金丝雀发布也叫灰度发布,是值在黑与白之间,能够平滑过渡的一种发布方式,灰度发布是增量发布(例如:2%,25%,75%,100%)进行更新的一种类型,灰度发布是在原有版本可用的情况下,同时部署一个新版本应用作为"金丝雀"(小白鼠),测试新版本的性能和表现,以保障整体系统稳定的情况下,尽早发现,调整此方式在实际生产中较为普遍。

金丝雀/灰度发布步骤组成:
	- 准备好部署各个阶段的工件,包括:构建组价,测试脚本,配合文件和部署清单文件;
	- 从负载均衡列表中移除掉"金丝雀"服务器(选择一全部服务器的一部分);
	- 升级"金丝雀"应用(排掉原有流量并进行部署);
	- 对应用进行自动化测试;
	- 将"金丝雀"服务器重新添加到负载均衡器列表中(连通性和健康检查);
	- 如果"金丝雀"在线使用测试成功,升级剩余的其他服务器,否则就会滚回旧版本;
	

金丝雀/灰度发布部署使用的场景:
	- 不停止老版本,额外搞一套新版本,不同版本应用共存;
	- 灰度发布中,尝尝按照用户设置路由权重,例如"90%"的用户维持使用老版本,"10%"的用户尝鲜新版本;
	- 经常与A/B测试一起使用,用于测试选择多种方案;

3.滚动发布(更新)

滚动发布顾名思义,就是逐步升级服务的节点。

滚动发布是指每次只升级一个或多个服务实例,升级完成后加入生产环境,不断执行这个过程,直到集群中的全部旧版本升级新版本。

如上图所示,对应不同阶段的实例变化:
    绿色:
        正在运行的实例
    红色:
        正在更新的实例。
    蓝色:
        更新完成并加入集群的实例。
        
滚动发布过程:
	- 先升级1个服务实例,主要部署验证;
	- 每次升级1个服务实例,自动从LB上摘掉,升级成功后自动加入集群;
	- 事先需要由自动更新策略,分为若干次,每次数量/百分比可配置;
	- 回滚是发布的逆过程,先从LB摘掉新版本,再升级老版本,这个过程一般时间比较长;
	- 自动化要求高;

4.A/B测试

A/B测试集同时对外提供两个APP允许环境,这和蓝绿部署的同时只有一个版本在线是不同的。

A/B测试用来测试应用功能表现的方法,例如可用性,受欢迎程度,可见性等等。

蓝绿部署和A/B测试是不同的,蓝绿部署的目的是安全稳定地发布新版本应用,并在必要时回滚,即蓝绿部署是同一时间只有一套正式环境在线,而A/B测试是两套正式环境同时在线,一般用于多个产品竞争时使用。
posted @ 2020-01-18 08:10  尹正杰  阅读(1314)  评论(0)    收藏  举报