DevOps系列:CI/CD

系列目录

《DevOps系列:开篇》

《DevOps系列:概述》

《DevOps系列:CMDB》

《DevOps系列:CI/CD》

《DevOps系列:监控》

《DevOps系列:SRE》


1. 介绍

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

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

1.1 CI 是什么?CI 和 CD 有什么区别?

缩略词 CI / CD 具有几个不同的含义。CI/CD 中的“CI”始终指持续集成,它属于开发人员的自动化流程。成功的 CI 意味着应用代码的新更改会定期构建、测试并合并到共享存储库中。该解决方案可以解决在一次开发中有太多应用分支,从而导致相互冲突的问题。

CI/CD 中的“CD”指的是持续交付和/或持续部署,这些相关概念有时会交叉使用。两者都事关管道后续阶段的自动化,但它们有时也会单独使用,用于说明自动化程度。

持续交付通常是指开发人员对应用的更改会自动进行错误测试并上传到存储库(如 GitHub 或容器注册表),然后由运维团队将其部署到实时生产环境中。这旨在解决开发和运维团队之间可见性及沟通较差的问题。因此,持续交付的目的就是确保尽可能减少部署新代码时所需的工作量。

持续部署(另一种“CD”)指的是自动将开发人员的更改从存储库发布到生产环境,以供客户使用。它主要为了解决因手动流程降低应用交付速度,从而使运维团队超负荷的问题。持续部署以持续交付的优势为根基,实现了管道后续阶段的自动化。

CI/CD 流程

CI/CD 既可能仅指持续集成和持续交付构成的关联环节,也可以指持续集成、持续交付和持续部署这三项构成的关联环节。更为复杂的是,有时“持续交付”也包含了持续部署流程。

归根结底,我们没必要纠结于这些语义,您只需记得 CI/CD 其实就是一个流程(通常形象地表述为管道),用于实现应用开发中的高度持续自动化和持续监控。因案例而异,该术语的具体含义取决于 CI/CD 管道的自动化程度。许多企业最开始先添加 CI,然后逐步实现交付和部署的自动化(例如作为云原生应用的一部分)。

1.2 CI 持续集成(Continuous Integration)

现代应用开发的目标是让多位开发人员同时处理同一应用的不同功能。但是,如果企业安排在一天内将所有分支源代码合并在一起(称为“合并日”),最终可能造成工作繁琐、耗时,而且需要手动完成。这是因为当一位独立工作的开发人员对应用进行更改时,有可能会与其他开发人员同时进行的更改发生冲突。如果每个开发人员都自定义自己的本地集成开发环境(IDE),而不是让团队就一个基于云的 IDE 达成一致,那么就会让问题更加雪上加霜。

持续集成(CI)可以帮助开发人员更加频繁地(有时甚至每天)将代码更改合并到共享分支或“主干”中。一旦开发人员对应用所做的更改被合并,系统就会通过自动构建应用并运行不同级别的自动化测试(通常是单元测试和集成测试)来验证这些更改,确保这些更改没有对应用造成破坏。这意味着测试内容涵盖了从类和函数到构成整个应用的不同模块。如果自动化测试发现新代码和现有代码之间存在冲突,CI 可以更加轻松地快速修复这些错误。

进一步了解技术细节

1.3 CD 持续交付(Continuous Delivery)

完成 CI 中构建及单元测试和集成测试的自动化流程后,持续交付可自动将已验证的代码发布到存储库。为了实现高效的持续交付流程,务必要确保 CI 已内置于开发管道。持续交付的目标是拥有一个可随时部署到生产环境的代码库。

在持续交付中,每个阶段(从代码更改的合并,到生产就绪型构建版本的交付)都涉及测试自动化和代码发布自动化。在流程结束时,运维团队可以快速、轻松地将应用部署到生产环境中。

1.4 CD 持续部署(Continuous Deployment)

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

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



2. 构建CI/CD

https://www.infoq.cn/article/wht0wfmdrrbu-dtkh1xp

https://gitbook.cn/gitchat/column/5aa795539c3cf94d49162f03/topic/5aaa1abe0bb9e857450e7a9e

CI/CD 与 DevOps 学习笔记

DevOps 是为了应对软件发布频率越来越高与传统的“瀑布型”开发模式之间的矛盾提出的,CI/CD 是 Devops 的基础。CI/CD 将 Dev、QA、Ops 连接在一起,就是所谓的“开发运维一体化”,通过高度自动化的流程保证频繁且可靠的发布。

CI/CD 基本流程

从开发提交代码,到上线,整个过程都是属于 CI/CD 的范畴。

CI 意思是 持续构建,指的是从提交代码到最终生成的可以发布的应用,应用可以是 jar 包,也可以指 tar 包,甚至是 docker 镜像。 CI 的基本流程包括,提交代码、对代码的监控、编译打包、基本测试,发布包。

CD 意思是 持续交付/持续部署,持续部署比持续交付多强调了一点,即deploy的自动化。两者的区别实践起来并不重要,主要流程指将持续构建的产物,快速部署到测试环境进行测试,测试完毕后进行评审后即可自动化发布、部署到现网。

CI 具体分析

CI——Confinuous Integration,持续集成。

集成的意思是,将开发者的代码迅速集成到整个代码项目中,与历史的代码、他人的代码集成。传统的开发模式中,一个项目,分成几部分,大家分别开发,最后发布前,将所有的代码合到一起然后进行迭代测试直到发布。在 CI 流程中,每个人随时将自己的代码合入到主干,并且合入能够很快得到反馈,这种反馈不止是基于修改部分的代码,而是基于整个代码仓库的测试。这种模式下,问题可以被更早的发现,尤其是那些在集成测试中容易出现的问题。

持续的意思,可以理解为,强调的是整个过程是持续不断的。提交代码 -> 监控到代码提交并触发测试(也可能是定时的,比如每天一次)->反馈结果到开发,整个过程持续贯穿在代码开发的整个流程中。

CI 流程中的测试,一般不同于 CD 流程中的测试。在 CI 流程中,比如在提交代码阶段,一般会有 commit hook,对提交的代码进行基本的静态检查,代码提交之后,一般会有产物的构建流程。在测试中,常常包含的是基本的自动化测试、单元测试以及基本的集成测试。

但是这些也取决于具体的场景的决策,这种决策需要兼顾的是两个方面:

  • 时效性,在 CI 阶段的测试一般来讲应该是可以比较快的反馈到开发者的,否则就会降低开发的效率
  • 问题出现的可能性,应该思考在 CI 阶段比较容易出现、常出现的问题是哪些,这些问题可以尽量放到该阶段,但是一般是一些基础的测试,复杂的测试可以放到 CD 中去做。

CD 具体分析

CD 的输入是 CI 的输出,也叫 CI 的产物(Artifact),它可能是 jar 包、war包、tar包、image 等等,CD 流程从归档地址(Artifact Repository) 获取产物。

CD 的主要过程是部署产出物到测试环境,进行集成的全面的测试,并且最终得到一个通过了所有测试的、可以被评审发布的产物。

在 CD 的测试中,尽管各个厂商叫法不同,但是可以将其基本分为三种环境,分别是测试环境、预发环境、生产环境。团队可以根据自身实际情况,定义三个环境的部署基准。

在 CD 流程中的测试应该是全面覆盖的,包括但不限于单元测试、接口自动化测试、集成自动化测试、UI测试、性能压测以及整个的端到端的测试。

经过了所有的测试的发布包,经过评审发布,就可以部署到现网,如果部署到现网也做到自动化,这个就叫 Continuous Deployment,也就是 持续部署。

持续部署必须拥有回滚的能力。

CI/CD 工具

CI/CD 整体是自动化的,同时由于多个任务并行/串行构成了流水线,Jenkins 提供的就是自动化流水线的能力以及丰富的插件的能力。

Jenkins 基本是事实上的标准,容器化目前可以作为补充来完善或者加速整个流程。但是同时也有一些容器化的工具开始挑战 Jenkins,比如 Drone。

Jenkins 主要在于它强大的生态,几乎可以搞定整个 CI/CD 流程的各个方面。Jenkins 可以安装很多插件,必要时写一个插件也不算太难——比如通过插件可以监控代码仓库的提交。

Jenkins 1.0 中开发者基本就是依靠 shell 脚本来构建一条流水线,在 Jenkins 2.0 中有了 pipeline as code,从而可以将发布的流程也纳入到版本管理中,可以很方便的复制迁移工程。

除了 Jenkins 之外,也可以使用 gitlab 的 CI/CD 流程工具,学会了使用其中一个,另一个也就比较容易上手了,比如知道了如何在 Jenkins 中添加 slave,那么自然就知道 gitlab 中添加 Runner 是干啥的了。gitlab 对代码的托管的集成肯定是更好的,但是 Jenkins 的源码管理插件也已经足够好用了。

Docker 提供了另外一种产物的可能,比如之前发布的包是 jar 包,使用了 docker 之后,可以发布一个 docker 镜像。将产物从打包好了的代码变成处理好了的镜像,就可以解决“测试环境明明运行的好好的,现网却挂了”这种环境导致的问题。

当然,也可以在其它具体的任务场景下使用 docker,比如使用 docker 作为构建机器,好处依旧是配置更加简单,启动停止销毁也变得容易。

另外,kubernates 也可以在 CI/CD 中发挥巨大的作用,比如使用 Jenkins 对接 Kubernates 集群,可以完成 master 挂掉立即重启一个 master的操作,也可以 解决slave 需求峰值低谷差异大造成资源浪费的问题。

但是比较明显的是,容器化能做的远远不止这些,未来的 CI/CD 会跟容器化会联系地更加紧密,几乎是毫无疑问的事情。

总结

CI/CD 可以认为是 DevOps 工作流的基础,它完成了应用的快速且高质量的发布。

持续集成 完成了提交代码到产出物的快速迭代。

持续交付 完成了整个测试流程的快速迭代。

持续部署 自动化了生产环境的部署,并且定义了灰度发布、回滚等能力及策略。

持续集成和持续交付的分界点是 Artiface Repository 中的产出物。

持续交付和持续部署的分界点是评审后的 Release 的产出物。

整个流程是一直在不断 running 的,因此叫做“持续”。

构建CICD工具链

  • 源码管理: git、svn
  • CI 平台:Jenkins、gitlab ci
  • 代码静态分析工具:比如 pylint
  • 单元测试:开发者应该写单元测试
  • 集成测试:集成自动化用例
  • 测试环境:最好可以自动化,支持多版本部署验证
  • 软件发布平台
  • 全覆盖测试工具,UI测试工具、压测工具等
  • 预发环境
  • 自动化部署工具
资料及扩展
  1. 阿里巴巴如何基于 Kubernetes 实践 CI/CD
  2. Jenkins 用户手册
  3. Getting started with Gitlab CI/CD
  4. CICD 方案分析
  5. 基于 Jenkins 和 Docker 搭建持续交付流水线
  6. 持续集成与交付解决方案
  7. 基于 Docker 的 CI/CD 流水线实践
  8. 解读阿里 CI/CD、DevOps、分层自动化技术

2.2 工具

https://jenkins-zh.cn/wechat/articles/2020/01/2020-01-10-the-complete-ci-cd-collection-tutorials/


3. 结论