- DevOps贯穿整个软件生命周期,而CI/CD则是它的基础和技术核心。但是在没有自动化测试、持续集成和持续部署的支撑下,DevOps就是空中楼阁。
1、CI/CD介绍
- CI是指持续集成(Continuous Integration,CI)。狭义的CD指持续交付(Continuous Delivery,CD),广义的CD指持续部署(Continuous Deployment)。
- 持续,是指每完成一个完整的部分,就向下个环节交付,发现问题可以马上调整,使问题不会放大到其他部分和后面的环节。
- 集成,是指个人研发的软件部分向整体部分交付,以便尽早发现个人开发部分的问题。
- 交付,是指研发尽快向质量团队或者用户交付,以便尽早发现生产环境中存在的问题。
- 部署,是指代码通过测试后自动部署到生产环境。
1.1、持续集成
- 随着软件项目复杂度的增加,对软件组件之间的集成和协同工作提出了更多的要求。如果开发人员在后期才进行集成,发现和解决问题的代价会很大,很有可能导致项目延期甚至失败。因此要“尽早集成、经常集成”,在项目早期发现的风险和质量问题更容易得到解决,并保证了开发进度,持续集成就诞生在这样的背景下。
- 持续集成指的是频繁地将代码合入到主干分支,只有通过自动化测试和验证的代码才能被集成,目的是让产品在可以快速迭代的同时还能保证质量。简单来说就是,针对软件系统的每次变更,能持续且自动地进行验证:构建、测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集戚在一起,并确保核心功能正常执行,不受影响。Martin Fowler说过:“持续集成并不能消除Bug,而是让它们非常容易被发现和改正。”
- 持续集成的流程如图所示:
- 重复循环该过程就是持续集成:
- (1)开发人员首先获取当前代码库的副本。随着其他开发人员将更改后的代码提交到源代码库,该副本与源代码库中的代码差异会逐渐变大。源代码库可能不仅仅被更改,还可能添加新库,或者增加其他依赖、或者冲突的模块。
- (2)代码分支分出的时间越长,当开发者将分支重新集成到主线时,产生的冲突和失败的风险就越大。当开发人员将代码提交到源代码库时,必须先更新代码,使本地副本和代码库中的主线分支同步。代码库包含的更改越多,开发人员在提交自己的变更前必须进行的工作越多。
- (3)开发人员的代码提交到源代码库时,会触发CI服务器进行构建和测试,并把测试结果反馈给开发人员。测试通过,代码会合并到源代码库中继续下一轮的测试;测试失败,开发人员根据反馈结果修改后重新提交。
- 持续集成一般由代码变更触发,遵循先进先出的原则,否则容易引起混乱,很难定位是谁的代码破坏了集成。而且构建时间不能太长,否则构建次数将会变少,大部分变更会一直处于等待状态。
- 注意,在代码提交之前,开发人员必须在本地完成单元测试,集成测试通常在检测到新提交时在CI服务器上自动运行。
- 持续集成的好处:
- 快速发现错误,变更容易追踪,节省了项目生命周期间的时间和金钱。
- 避免版本发布最后时期才集成的混乱。
- 测试失败或出现bug时更容易恢复。
- 保证主干分支的可用。
- 频繁地集成推动开发人员设计模块化、不太复杂的代码。
1.2、持续交付
- 持续交付是在持续集成的基础上,频繁地将集成后的代码交付给质量团队(QA)或者用户,部署到更接近真实运行环境的类生产环境中以供测试评审,通过测试就进入发布,生产阶段。它旨在更快更频繁地构建、测试和发布软件,有助于降低交付的成本、时间和风险。直接和可重复的部署过程对于持续交忖非常重要。持续交付并不意味着每个变更都会尽快部署到生产环境中,它意味着每次更改都被证明可以随时部署。持续交付的目标不是要消灭缺陷,而是要规范开发和测试的流程,从根源上提高产品的质量。开发人员需要了解任何代码提交都可能会随时发布给客户,这一点很重要。
- 持续交付的流程如图所示:
- 持续交付在持续集成的基础上多了手动部署和系统测试等流程。
- 持续交付的产品一般有:
- 源代码交付:比如Python/Shell脚本,但这些文件不是标准的软件包,不利于集中管理和运行。
- 软件包交付:比如通过RPMBuilder工具制作Linux标准包。
- 镜像交付:可以是虚拟机镜像,也可以是Docker镜像。
- 持续交付的优点:
- 提高了产品质量,加快了产品上市时间。
- 产品更符合用户需求,提高了客户满意度。频繁地发布使开发团队可以更快地获得用户反馈,专注于开发对客户有用的功能,有助于构建正确的产品。
- 提高了生产力和效率。
- 在实施持续交付的过程中,必须考虑将基础设施的维护纳入进来,作为支持产品运行的一部分。传统的基础设施运维管理存在以下几个问题:
- 自动化缺乏串联:虽然有一定的自动化,但不能做到无人值守,需要执行一些临时命令。由于环境释放和重建的成本高,因而倾向于不释放,导致资源利用率低。
- 与产品团队脱节:很难根据需求随时动态增加环境。需要额外的文档来描述环境,可能更新不及时。
- 通过基础设施代码化(Infrastructure as Code,IaC)可以解决上述问题,大大有助于实现持续交付,促使持续交付和DevOps的成熟,是DevOps的一项关键实践。
- IaC有四项关键原则:
- 再生性:环境中的任何元素可以轻松复制。
- 一致性:无论何时,创建的环境中各个元素的配置是完全相同的。
- 快速反馈:能够频繁、容易地进行变更,并快速验证变更是否正确。
- 可见性:所有对环境的变更应该容易理解、可审计、可回退、受版本控制。
1.3、持续部署
- 持续部署是持续交付的下一阶段,即软件通过测试后自动部署到生产环境。持续部署的前提是能自动化完成测试、构建、交付等步骤。目标是代码在任何时刻都是可部署的,可以进入生产阶段。
- 持续部署的流程如图所示。
- 持续部署意味着每次更改都会自动部署到生产环境中,强调的是自动化。为了进行持续部署,必须持续交付。虽然持续部署可能不适合每个团队或项目,但持续交付是DevOps实践的绝对要求。
1.4、CI/CD工作流
- 以上简单介绍了CI/CD的概念及每个阶段的工作流程,整合起来即一套完成的CI/CD流水线。在实际应用中,一般通过代码评审系统实现代码审查和集成反馈。整个CI/CD系统配置了代码仓库系统、代码评审系统和构建工具系统。
- CI/CD工作流程如下:
- (1)代码提交:开发者向代码评审系统(比如Gerrit)提交代码。
- (2)第一轮测试:系统监听到代码评审系统的事件后即触发相关的测试。这里的测试有如下几种:
- 单元测试:针对函数或者模块的测试。
- 代码风格检查:针对代码编写的风格进行检查,比如Python的pep8等。
- 集成测试:功能测试。
- (3)构建:是将源代码转换为可以运行的软件包或者镜像等。(测试通过后,代码就可以合并到主干分支,然后进行构建。)
- (4)第二轮测试:构建完成后进行下一轮测试,此阶段的测试比第一轮测试全面,包括功能测试、系统测试、性能测试等。
- (5)交付:第二轮测试通过,代码就进入发布阶段。
- (6)部署:经过多轮测试后的版本就是一个可直接部署到生产环境的稳定版本,此版本发布到制品库上,用户就可以在获取版本后通过自动化工具部署到生产环境。
2、OpenStack的CI/CD
- OpenStack作为现在世界上第二大开源社区,有着一个完整的、标准化的、自动化的持续集成测试平台。它由社区的OpenStack-Infra团队开发维护,具有高可靠性、灵活性和可扩展性,对于搭建企业内部CI/CD系统有非常好的借鉴意义。
- 注意,如果不做特殊说明,CD就是指持续交付。
2.1、当前Cl/CD系统的形态
- 以Jenkins作为持续集成工具为例,CI/CD系统的复杂程度分4个等级:
- 第1级:如图2-4所示,仅使用Jenkins,且都在一套服务器上,适用于产品项目较小、资源较少的场景,使用维护较为简单。
- 第2级:如图2-5所示,在第1级的基础上引入了Gerrit评审系统,但是具体构建还是在本地,测试环境受限。
- 第3级:如图2-6所示,也是目前稍具规模的公司或社区都会使用的系统,使用Jenkins+Jenkins-Job-Builder(JJB)工具。在执行构建时,使用了一些静态资源(如虚机、容器或物理机),可以满足多场景构建和测试需求,但是资源利用率较低,多次测试的环境上下文存在耦合,目前OPNFV社区使用这种框架。
- 第4级:如图2-7所示,在第3级的基础上引入了任务门控系统(Zuul)和动态资源管理系统(Nodepool)的使用模式,也是目前OpenStack开源社区的应用。
2.2、OpenStack的CI/CD架构
1
# #标签:集成,CI,交付,代码,持续,CD,测试,DevOps01 From: https://www.cnblogs.com/maiblogs/p/17189081.html