专栏名称: xcbeyond
架构师
目录
相关文章推荐
小米汽车  ·  2025年春节假期小米汽车出行报告:小米汽车 ... ·  17 小时前  
蔚来  ·  2025顺意开年,满电出发 ·  3 天前  
蔚来  ·  下一个目的地,你设定好了吗? ·  2 天前  
理想汽车  ·  拼手速!理想商城开年秒杀倒计时 ·  3 天前  
51好读  ›  专栏  ›  xcbeyond

从 CI/CD 持续集成部署到 DevOps 研发运维一体化

xcbeyond  · 掘金  ·  · 2021-02-02 19:40

正文

阅读 18

从 CI/CD 持续集成部署到 DevOps 研发运维一体化

今天整理下从传统的CI/CD到DevOps研发运维一体化的整个演进过程。类似于每日构建和冒烟测试,实际上在10多年前就已经在实践,比如当前用的笔记多的Ant+CruiseControl方式来实现自动化的编译构建和持续集成能力。

包括当前DevOps过程实践中的持续集成,实际和原来在思想上并没有太大的变化,对于DevOps我原来也给出过一个总结。

DevOps过程概述

首先还是回顾下DevOps的简单定义如下:

DevOps(英文Development和Operations的组合)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。它的出现是由于软件行业日益清晰地认识到:为了按时交付软件产品和服务,开发和运营工作必须紧密合作。

对于DevOps的提出已经很多年,其主要的推动仍来自两个方面:

1. 业务和需求驱动下,推动敏捷方法论,敏捷下需要更加短周期,更快地发布和交付。

2. 技术和运维部门需要衔接,在PaaS和容器技术发展下,进一步推动这部分陷阱的自动化。

虽然是三方交融地方为DevOps的内容,但是可以看到DevOps本身更多的是要解决两大类协同和自动化的问题,其一是开发部门和QA协同,其二是开发部门和运维的协同。

对于第一个问题重点解决思路即常说的CI/CD持续集成和持续部署方法论,而对于第二个问题则涉及到当前由云平台,微服务架构,容器技术发展推动的自动化发布和监控运维,基于敏捷研发的过程改进等。

因此对于DevOps已经不是简单的CI/CD,而是更多最佳实践的融合。

持续集成和持续部署CI/CD

敏捷研发和过程协同

微服务化

基于容器云的自动部署和动态资源扩展

自动化测试技术解决QA和开发协同

虽然当前对于微服务化,容器云等并不是实施推进DevOps过程的必要选项,但是对于当前大部分组织研发过程改进和开发选项中,微服务和容器化也成为了一种默认的标准规范。

因此今天这篇文章重点整理从CI/CD开始是如何叠加上各种过程能力和技术,然后逐步发展到当前完整的DevOps过程体系。

CI/CD持续集成和持续部署

最早的团队软件开发中,往往会专门安排一个开发人员或配置管理人员来人工完成编译和部署工作。简单来说核心要做的就是就是:

  • 从配置或源代码库update到最新代码

  • 进行代码编译和构建

  • 将编译完成的部署包部署到测试环境

而这个过程本身可以进行自动化处理,即人工完成的工作转为程序自动化来完成。可以看到里面会涉及到配置代码库,编译构建环境,测试环境三个典型资源。

其次编译过程需要进行自动化,将如何进行编译的过程,编译需要依赖的包,编译构建顺序等通过xml配置文件进行配置,后续基于该配置内容进行自动化编译。从最早的Ant到Maven基本均是该思路。

因此,最简的自动化编译和自动部署,冒烟测试过程如下:

为何需要持续集成类工具?

从上图可以看到,即使最简单的编译构建和部署往往也涉及到多个步骤的联动。如上图需要首先连接到配置管理库,拉群和更新到最新的源代码;需要调用自动化编译脚本进行编译,需要触发自动化部署脚本进行部署,部署后还需要调用外部自动化测试脚本进行测试,整体完成后还需要生成报告或发送邮件。

而整个过程需要工具来进行自动化组合和编排,即CI/CD类工具来完成。

每日构建和冒烟测试

每日构建和每日编译的最大区别就在于是否进行了冒烟测试,系统必须通过了冒烟测试才能够算每日构建成功。而测试人员人工介入的测试是基于冒烟测试通过的基础上面的。

冒烟测试由于要验证整个编译的正确性,因此冒烟测试必须是针对整个系统进行冒烟测试。但冒烟测试只需要关注系统的主体功能即可,通过冒烟测试并不是说系统没有BUG,只是说通过了冒烟测试后可以说系统是一个稳定的版本,说系统的每日构建是成功了,代表系统可以转交专门的测试人员进行测试了。

冒烟测试工作一般需要提前准备好自动化测试代码或脚本,CI工具仅仅是对自动化测试脚本进行集成,在测试完成后输出相应的测试结果报告。

基于二进制的环境迁移

对于CI/CD工具将二进制的部署包部署到测试环境,通知开发人员进行测试。如果开发人员在SIT测试环境测试通过,可能就需要将版本部署到UAT验收测试环境通知最终的用户进行验收测试。

那么这个时候是否重新再进行编译构建操作,然后朝UAT环境部署?如果这样的话显然不合适,即无法保证测试人员在SIT测试通过的版本就是最终推送给用户在UAT环境测试的版本。

持续集成应该是一次构建,形成二进制部署包多处运行。

因此部署版本不应该反复构建,而是直接用测试通过的部署版本进行UAT环境的部署,但是这个时候往往不同环境存在的不同的配置信息,典型的即类似接口访问地址,数据库连接串信息等,这些信息都和环境相关。

那么就需要将这些环境相关配置从WAR包中剥离出来,在进行环境迁移或新环境部署的时候,仅仅需要动态修改这些配置文件即可。

整个过程如下:

可以看到,整个持续集成和持续部署实际要完成多个环境之间的集成和协同工作,那么支撑集成整个过程设计最好是从上面这些环境中剥离出来,应该是单个一个Server服务器来执行整个持续集成流水线设计和编排,调度和运行。

进一步解耦,持续集成节点和制品库

在前面已经谈到,持续集成需要调度和编排多个环境和工具,这个已经不再适合放在类似构建环境上来完成,因此需要独立出来。

其次,对于自动化编译完成的结果,也不适合放在构建环境,编译和构建环境本身是一个临时的环境,不适合对对构建完成的二进制包进行完整的管理,版本追溯,配置等各种操作。因此制品库也需要从构建环境中移出,形成独立的制品库。

基于以上两点,整体过程如下:

到了这步,基本一个完整的持续集成和持续部署就完成了。比如当前主流的Jekins进行持续集成和持续交付核心思路仍然如上,包括在最早版本的集成上增加了更加灵活的流水线设计,增加了和容器云能力的集成,增加了和自动化测试工具集成等。

在传统的持续集成里面,一般很少形成独立的制品库Server,而到了DevOps和容器云集成后,一般更加强调独立的制品库和镜像仓库,这个是进行各个环境部署,资源动态扩展的基础。

同时持续集成Server是整个核心,通过Server来设计和编排,来统一调度各个能力单元,同时实现编译构建过程,和最早的测试,生产环境间的协同。

持续集成类:源代码库,构建环境,制品库,CI/CD环境

资源类:开发环境,测试环境,正式生产环境

持续集成最终就是实现整个开发到交付过程的完全自动化管理。

和容器云集成

对于容器云相关内容,可以参考网上的其它文章。当持续集成和持续交付和容器云集成的时候可以看到,如下几个变化点。

其一是二进制部署包转变为镜像交付

其二是新增加一个制作镜像的过程,我们一般叫打包

原来整体只有两个动作,编译构建-》部署

在和容器云集成后,整体过程会变化为三个关键动作,即编译构建-》打包-》部署。其中打包即是镜像制作过程,在镜像制作完成后将镜像推送到镜像仓库。同时发起部署任务的时候,是从镜像仓库里找到特定的版本,将版本部署到测试环境上。

整体过程如下:

可以看到整体持续集成和交付过程并没有明显的变化,仅仅在于交付的单位变成镜像,同时增加了镜像制作的过程。

有用底层的环境资源已经变成容器资源池,这些资源需要进行统一的管理,资源需要分配,需要基于资源使用负荷进行动态调度等。因此在Docker容器集群上需要有一个统一的管理和编排工具,这个即当前主流的Kurbernetes来实现容器集群管理,容器编排。

如上图通过Maven来实现代码的构建,同时在Jenkins中本身集成Maven,对于构建完成的部署包会进入到Jenkins本身的部署包仓库管理。这个完成后进一步启用Jenkins来调用底层的Docker命令生成Docker镜像文件,这个镜像则是我们后续做自动部署和持续集成的关键镜像文件。

在这个步骤完成后即对接到Kubernetes来实现Docker镜像文件的自动化部署和动态调度。

在持续集成中有一个重点就是环境迁移,注意每次迁移的都应该是相同的镜像文件,而对于和环境相关的配置则单独进行配置或放置到OS的环境变量中。只有这样才能够保证最终上线的部署包就是我们最终开发和测试完成的部署包而没有任何变动。

如果在动态部署的时候启用了多个节点,那么还需要提供负载均衡能力。要注意的是Kubernetes本身也提供负载均衡和虚拟IP路由能力。我们最终访问的是域名,而域名最终会解析到实际的计算节点。

和敏捷开发过程协同

在DevOps最佳实践里面分为了研发管理,持续交付和技术运营几个关键的过程域。

但是在实践的过程中,最容易出现问题的不是单个技术点,而是跨域的协同问题,或者说 研发过程管理和持续集成交付本身就是密不可分的两个部分 ,我们只是为了容易理解和学习将其划分为了不同的过程域而已。

因此 流水线设计需要理清研发过程管理和自动化持续集成间的协同关系 。具体两者的协同关系我们用下图来进行说明。

要明白任何一次新的编译构建部署完成后都涉及到测试人员测试,测试人员测试出问题后又会提交Bug,开发人员修改Bug后Check in代码,等待下一次打包部署以形成多次迭代。整个过程最好方式就是要尽量 减少大量的人工沟通协同,而是应该通过工具链协同 来完成。

对于传统的持续集成,一般最佳实践为每天晚上进行自动化构建和冒烟测试,而对于当期的DevOps过程,在设计完流水线后,可以手工去启动流水线作业,也可以自动去执行流水线,流水线执行时间频度也可以进一步缩短。

假设我们每2个小时自动化的执行一次流水线作业,我们以此场景来做进一步梳理。因为对于大部分企业来说再高频的构建集成也不需要代码有变动就马上触发构建打包的程度。

流水线增加启动检查节点

虽然2小时执行一次流水线,但是在执行前先进行启动前检查,如果在最近2个小时内没有新代码check in,那么不执行流水线。其次,如果上一次流水线执行实例还处于待处理或未关闭状态的时候,同样也不执行流水线作业而直接跳过。

是否需要人工验证

流水线打包部署包括两个方面,一个是新功能提交或新bug解决,只有这种情况才需要人工验证。因此一次流水线执行如果没有新需求或Bug状态变化,那么应该直接跳过人工验证节点并关闭。反之,则应该跳转到待人工验证环节。

需求和缺陷的管理

要注意到新需求和新缺陷都应该提交,而且都有状态,需求细分到具体的需求功能点,同时测试人员提交的缺陷应该对应到具体的需求功能点上面。一个需求开发完成后,需求本身也到待验证状态,但是一个待验证的需求是否能够关闭则必须是该需求下面所有的bug都解决完成后才能够关闭。

需求和缺陷状态的变化

开发人员首先是将需求或缺陷完成,并在本机进行自测通过,然后将代码check in到配置管理库。同时手工将需求或缺陷状态处理到待部署状态。在流水线启动后,如果整个构建打包和部署成功,则在成功完成应用部署后,将待部署状态的需求或bug转到待验证状态。在部署完成后测试人员可以看到待验证的bug或需求,那么他进入当前的测试环境一定是最新的可以进行缺陷验证的环境。







请到「今天看啥」查看全文