前言
大家好,我是洋子。CI/CD这个词大家或多或少都听过,甚至在进行软件测试面试时经常会进行考察
那CI/CD到底是什么呢,有的同学认为CI/CD 就是 Jenkins 集成,这其实是一种片面的理解,我们可以使用 Jenkins
来实现CI/CD,也可以借助其他工具来实现,如GitLab CI/CD
,在互联网大厂基本也有自研的CI/CD工具
今天就带大家完整的介绍一下CI/CD的概念,以及CI/CD在大厂是如何进行落地的
CI/CD概念
CI/CD 是持续集成(Continuous Integration,CI)、持续交付(Continuous Delivery,CD)与持续部署(Continuous Deployment,CD)的简称,注意CD对应了两个名词
CI/CD是实现敏捷开发
和Devops
理念的一种方法,具体而言,CI/CD 可让持续自动化和持续监控贯穿于应用的整个生命周期(从集成和测试,到交付和部署)。这些关联的事务通常被统称为CI/CD 管道(Pipeline)
,由开发(RD)、测试(QA)、运维(OP)团队以敏捷方式协同支持
持续集成(Continuous integration,CI)
大师 Martin Fowler 对持续集成是这样定义的:持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件
通俗的来讲,持续集成就是在开发写完代码后,提交代码准入后自动触发的一系列流程,主要包括:
- 代码编译
- 代码打包
- 单元测试
- 代码静态扫描分析
- UI、接口自动化测试
持续集成(CI)可以帮助开发人员更加频繁地(有时甚至每天)将代码更改合并到共享分支或"主干"(master分支)中,另外通过持续集成当中的单元测试、代码扫描、自动化测试
我们可以尽早发现新提交的代码引入的问题,从而更加快速修复这些错误
请添加图片描述
持续交付(Continuous Delivery,CD)
完成以上CI的流程后,持续交付可自动将已验证的代码发布到存储代码库。为了实现高效的持续交付流程,务必要确保 CI 已内置于开发管道。持续交付的目标是拥有一个可随时部署到生产环境的代码库
在持续交付中,每个阶段(从代码更改的合并,到生产就绪型构建版本的交付)都涉及测试自动化和代码发布自动化。在流程结束时,运维团队可以快速、轻松地将应用部署到生产环境中
注意,持续交付在自动化测试和集成结束后,具备部署的能力,但不会自动部署,而是手动部署。如果有自动部署,则是持续部署
的概念了
持续部署(Continuous Deployment,CD)
对于一个成熟的 CI/CD 管道来说,最后的阶段是持续部署。作为持续交付——自动将生产就绪型构建版本发布到代码存储库——的延伸,持续部署可以自动将应用发布到生产环境
由于在生产之前的管道阶段没有手动门控,因此持续部署在很大程度上都得依赖精心设计的自动化测试
持续部署当中可配置分级发布拦截,在上线部署时,对无流量、小流量机器进行自动化测试,发现问题后及时拦截回滚
实际上,持续部署意味着开发人员对应用的更改在编写后的几分钟内就能生效(假设它通过了自动化测试)。这更加便于持续接收和整合用户反馈
总而言之,所有这些 CI/CD 的关联步骤都有助于降低应用的部署风险,因此更便于以小件的方式(而非一次性)发布对应用的更改。不过,由于还需要编写自动化测试以适应 CI/CD 管道中的各种测试和发布阶段,因此前期成本会比较高
CI/CD小结
- 持续集成: 高频率的将代码合入主干,在合入之前触发单测和集成测试等去验证代码的改动,确保改动不会对应用造成破坏
- 持续交付:将代码合入到代码仓库。其目标是拥有一个可随时部署到生产环境的代码库
- 持续部署:在流程结束时,运维团队可以快速、轻松地将应用部署到生产环境中
CI/CD 工具
CI/CD 集成于 CI/CD 工具及代码托管服务。CI/CD 有时也可理解为进行 CI/CD 的构建服务器,而提供 CI/CD 的服务,如以下产品,将会提供构建服务与 GitHub/GitLab 集成在一起
- Jenkins
- GitLab CI/CD
- Travis CI
若公司没有 CI/CD 基础设施,那么可以尝试 github 免费的 CICD 服务GitHub Actions
若公司以 GitLab CI 作为 CI/CD 工具,此时需要自建 GitLab Runner 作为构建服务器
在互联网大厂,一般是有自研的CI/CD 工具
CI/CD 配置文件
CI/CD 流水线(pipeline)的配置文件使用的便是 yaml 语法写的,因此需要先理解一下相关的语法。这里推荐通过阮一峰老师的文章学习https://www.ruanyifeng.com/blog/2016/07/yaml.html
以下为GitLab CI/CD
完整 pipeline 的配置文件gitlab-ci.yml
,该配置中一共是三个阶段stage
:build、test、deploy;这三个阶段合在一起描述了代码上库之后的需要进行的处理,分别是代码构建(编译)、测试、部署阶段
各阶段执行的顺序为,build(构建)=> test(测试)=> deploy(部署)
在每个阶段,我们可以设置对应的任务Job
。以编译阶段为例,就用echo打印了下 “build project”这个字符串,然后执行了make -f Makefile
命令进行编译
# .gitlab-ci.yml
stages:
- build
- test
- deploy
build_job:
stage: build # 指定job所属stage
image: centos:7 # 指定执行job的所使用docker镜像
tags:
- clf-centos-runner # 指定执行job的runner(即机器)
script: # job执行时运行的脚本
- echo "build project"
- make -f Makefile
test_job:
stage: test
image: centos:7
tags:
- clf-centos-runner
script:
- echo "test project"
deploy_job:
stage: deploy
image: centos:7
tags:
- clf-centos-runner
script:
- echo "deploy project"
在实践过程中,可以根据需要创建三条pipeline,触发时机分别为
- ChangePipeline :代码提交后,入库前自动触发
- BranchPipeline:代码入库后,发布前自动触发
- MasterPipeline:合入主干时自动触发
开发在合入代码后,首先触发的是ChangePipeline,我们可以在这流水线进行代码静态扫描、单元测试,只有这条流水线触发、通过后才能进行合入代码库分支
在代码合入分支后,触发BranchPipeline这条流水线上适合进行接口或者UI自动化测试(对应下图核心功能准入测试),因为往往接口和UI自动化测试相对耗时,开发某个需求往往有多次提交,没有必要在每次提交代码后进行。这条流水线还可以进行测试环境沙盒部署,提测,功能回归等
MasterPipeline是在进行合入主干的时候触发,一般进行准出测试,上线,线上冒烟测试等等
根据业务需求不同,也可以在BranchPipeline 针对某个分支修改进行上线,不必在合入master时才进行上线
结尾语
「持续集成(Continuous Integration)」、「持续交付(Continuous Delivery)」和「持续部署(Continuous Deployment)」提供了一个优秀的 DevOps 环境,对于整个团队来讲,好处与挑战并行。不管如何,频繁部署、快速交付以及开发测试流程自动化都将成为将来软件工程的重要组成部分