什么是 CI/CD ?

Posted Z1404686551

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是 CI/CD ?相关的知识,希望对你有一定的参考价值。

说在开头
CI、CD 其实是三个概念,包含了一个 CI 和两个 CD,CI全称 Continuous Integration,表示持续集成,CD包含 Continuous Delivery和 Continuous Deployment,分别是持续交付和持续部署。这三个概念之间是有前后依赖关系的。
CI/CD 并不是一个工具,它是一种软件开发实践,核心是通过引入自动化的手段来提高软件交付效率。CI/CD 最终目的:让工程师更快 & 更高质量 & 更简单的交付软件!

持续集成 & 持续交付 & 持续部署
持续集成(Continuous Integration)

什么是持续集成?
定义:持续频繁的(每天多次)将本地代码“集成”到主干分支,并保证主干分支可用

持续集成这个词,起源于极限编程,是当时原始的12种实践之一,持续集成的目的快速反馈问题让产品可以快速迭代,同时还能保持高质量。它的核心措施是,代码集成到主干之前,必须通过编译、代码扫描、安全扫描、自动化测试等。只要编译失败、扫描出高级别问题或测试用例失败,就不能集成。
Martin Fowler 说过,“持续集成并不能消除Bug,而是让它们非常容易发现和改正。”

好处?
(1)通过自动化手段提高集成速度
在传统的研发过程中,一般通过手动方式执行编译、测试、部署,自动化后,可大幅提高集成频次,同时可以减少维护手工脚本带来的低级问题
(2)将问题前置
在每次 commit 时就触发编译、测试,更快的发现问题
(3)防止本地代码大幅偏离主干
如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。

触发方式?
自动触发,通过自动化的 CI 服务或工具,自动监听代码库 Git Push & MR 等事件触发

常见的工具如 Jenkins、GitlabCI、CircleCI、GithubActions 等等

蚂蚁支持持续集成平台有:雨燕(前端)、LinkE CI(后端)、伙伴(终端)、ACI(多语言)等

面临的问题 & 阻碍?
理想很丰满,现实很骨感,持续集成理念虽好,但实践过程中却有非常多的问题和阻碍,远没有想象中那么简单!

常见的问题如:
(1)执行环境异构导致结果差异
比如Java测试,用户执行测试一般是本地通过IDEA右击执行测试或 mvn 命令,但是 CI 服务上的环境&机器规格和本地有很多差异,比如 JDK 不一样、Maven 版本不一样、Mac 和 Linux 差异等等会造成很多本地执行可以通过但是 CI 上执行不通过,或者 CI 上执行明显比本地慢的现象。
解决此类问题本质还是减少异构,比如通过容器化方式让执行环境标准化,通过 Maven 缓存提高测试时间等等,同时作为 CI/CD 平台方,也最好将测试、构建的过程透明化(执行机制、清晰的错误码和解决方案),方便在出现问题的时候开发可以很方便的自助排查。

(2)没有严格的测试要求
持续集成的理念是只要有问题一定要及时修复,比如执行测试,必须保证所有case全部通过才能集成到主干,但是在现实中的场景,特别是一些规模大的历史项目,由于历史债等原因,导致测试case无法全部通过或者必须通过重试解决,开发很难有动力去改,导致集成质量低效。
所以,持续集成的前提是,需要有一个心里准备花大精力去治理项目中的一些历史债,尤其是改善历史 case ,补充新 case ,降低 case 噪音,确保每次自动化触发的测试可以准确反馈集成质量!

(3)非常慢的构建 & 测试速度
在 CI 上执行构建或测试的速度非常慢,导致集成效率非常低,这里的慢有两种原因,一种是本身测试&编译就慢,这时需要深入分析,需要结合并行分组、分布式缓存等技术解决。
这里的自动化测试中的集成测试可能会非常慢,所以一般保证在持续集成阶段先让单元测试通过,集成测试放在在持续交付阶段完成。

持续交付(Continuous Delivery)
什么是持续交付?
定义:是持续集成的下一步,持续频繁地将软件的新版本交付到类生产环境(类似于预发),交付给测试、产品验收。
持续交付强调的是“交付”,不管怎么更新,软件是随时随地可以交付的,相比持续集成,持续交付除了交付到类生产环境之外,还会执行一些集成测试、API测试等等,确保交付的产物可以直接交付部署。

触发方式?
手动触发,通过研发平台手动触发(如触发LinkE预发部署流水线),一般交付结果是一个二进制包或者镜像

面临的问题 & 阻碍?
(1)很难保证和线上环境完全一致
由于持续交付的环境很难和线上环境一致,所以可能导致一些问题无法验证,使得交付的产物具备一定风险
探索方案:仿真环境

(2)大量脑壳疼的联调环境问题
经常遇到的场景是虽然本系统开发好了,但是由于各种原因导致上下游系统没有 ready 导致无法持续交付,针对上下游依赖非常多的系统,对联调环境稳定性、效率有非常强的依赖

(3)很难保证严格充分的自动化测试
持续交付最终要做到交付的产物可直接部署线上,那么对代码的质量要求就非常高,需要覆盖全场景充分的测试 case

持续部署(Continuous Deployment)
什么是持续部署?

定义:是持续交付的下一步,“自动”将代码部署到生产环境

持续部署强调的是“部署”,它的目标是,代码在任何时刻都是可部署的,可以进入生产阶段。

持续部署和持续交付触发方式的区别是,持续部署是自动完成的,持续交付是手动完成的

触发方式?
自动触发,通过研发平台配置定时任务,自动获取交付产物进行自动部署。

目前即使在蚂蚁,应该很少有团队和研发平台能够真正做到持续部署,因为持续的部署的条件更加严苛

面临的问题 & 阻碍?
(1)发布条件受限
部分场景上线需要严格的审批的流程 & 频繁的封网
(2)低效手工发布流程
发布过程需要人工一次次确认,灰度和线上发布过程多分组场景下,需要一次次人工确定,不放心自动发布
目前蚂蚁解决方案:无人值守
(3)缺乏线上问题快速准确的反馈机制( 精准 OPS 能力)
没有 OPS 或者 OPS 噪音太大都会导致反馈不及时,这样研发就不敢把部署过程直接交给系统,也是上面发布需要人工确认的根因

目前公司对线上安全要求非常高,持续部署现阶段很难在蚂蚁大规模落地,特别针对类似金融核心这些安全要求非常高的系统,不过其实也未必要“一刀切”,公司还有很多级别不是特别高的应用,可以尝试小范围针对这些应用试点,同时不断持续改进周边 OPS 工具

最后
最后,我们来畅想一下,一个优秀的 CI/CD 研发过程应该是什么样子的?
假设开发同学小蚂第一天入职,他打开电脑,通过以下几步完成上线:
第一步:从 AntCode clone 代码到本地,修改了几行代码,本地测试后,通过git commit & push到代码仓库
第二步:push 过程自动触发了 CI 流水线,5 min 后,执行结束,通过钉钉通知告诉小蚂某个测试case失败了
第三步:小蚂本地修改失败 case ,重新 commit & push ,再次触发 CI 流水线,自动执行编译、测试、扫描等,收到钉钉消息,执行通过
第四步:小蚂将功能交给测试&产品验收,发现问题或收到建议,重新到第二步修改代码。
第五步:测试&产品验收没有问题后,手动触发预发部署流水线,并自动生成部署产物交付,后面流程就不用管啦。
第六步:持续部署流水线每几分钟自动检测交付产物包,发现更新后,自动将产物部署到线上。发布成功后,小蚂收到通知小蚂的功能生效啦。

理想状态?
(1)由于发布而导致的加班频次应该大幅减少
(2)开发大部分精力是花在写代码和思考如何写好代码,扫描、部署的事情交由平台自动化完成,并且体验良好,反馈精准。

什么是CI/CD

CI/CD 的出现改变了开发人员和测试人员发布软件的方式。从最初的瀑布模型, 到后来的敏捷开发(Agile Development ), 再到今天的 DevOps,这是现代开发人员构建出色产品的技术路线。 随着 DevOps 的兴起,出现了持续集成,持续交付(CI/CD)和持续部署的新方法, 而传统的软件开发和交付方式在迅速变得过时。过去的敏捷时代里, 大多数公司的软件发布周期是每月、每季度甚至每年;而在现在 DevOps 时代,每周、每天甚至每天多次都是常态。 当 SaaS 成为业界主流后尤其如此,您可以轻松地动态更新应用程序, 而无需强迫用户下载更新组件。很多时候,用户甚至都不会注意到正在发生变化。

开发团队通过软件交付流水线(Pipeline)实现自动化,以缩短交付周期, 大多数团队都有自动化流程来检查代码并部署到新环境。 我们一直在关注自动化测试流程,但这将在之后的文章中介绍。 今天,我们将介绍什么是 CI/CD ,以及现代软件公司如何使用工具将部署代码的流程自动化。

img

下面我们一起来看看到底什么是DevOps、CI/CD、Agile Development以及他们之间的关系和区别。

1、DevOps

DevOps是Development和Operations的组合,是一种方法论,是一组过程、方法与系统的统称,用于促进应用开发、应用运维和质量保障(QA)部门之间的沟通、协作与整合。以期打破传统开发和运营之间的壁垒和鸿沟。

img

DevOps是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。通过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。具体来说,就是在软件交付和部署过程中提高沟通与协作的效率,旨在更快、更可靠的的发布更高质量的产品。

也就是说DevOps是一组过程和方法的统称,并不指代某一特定的软件工具或软件工具组合。各种工具软件或软件组合可以实现DevOps的概念方法。其本质是一整套的方法论,而不是指某种或某些工具集合,与软件开发中设计到的OOP、AOP、IOC(或DI)等类似,是一种理论或过程或方法的抽象或代称。

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

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

2、Continuous Integration

CI的英文名称是Continuous Integration,中文翻译为:持续集成。

img

CI中,开发人员将会频繁地向主干提交代码,这些新提交的代码在最终合并到主干前,需要经过编译和自动化测试流进行验证。 持续集成(CI)是在源代码变更后自动检测、拉取、构建和(在大多数情况下)进行单元测试的过程。持续集成的目标是快速确保开发人员新提交的变更是好的,并且适合在代码库中进一步使用。CI的流程执行和理论实践让我们可以确定新代码和原有代码能否正确地集成在一起。

通俗点讲就是:通过持续集成, 开发人员能够在任何时候多次向仓库提交作品,而不是独立地开发每个功能模块并在开发周期结束时一一提交。这里的一个重要思想就是让开发人员更快更、频繁地做到这一点,从而降低集成的开销。 实际情况中,开发人员在集成时经常会发现新代码和已有代码存在冲突。 如果集成较早并更加频繁,那么冲突将更容易解决且执行成本更低。当然,这里也有一些权衡,这个流程不提供额外的质量保障。 事实上,许多组织发现这样的集成方式开销更大,因为它们依赖人工确保新代码不会引起新的 bug 或者破坏现有代码。 为了减少集成期间的摩擦,持续集成依赖于测试套件和自动化测试。 然而,要认识到自动化测试和持续测试是完全不同的这一点很重要。

CI 的目标是将集成简化成一个简单、易于重复的日常开发任务, 这样有助于降低总体的构建成本并在开发周期的早期发现缺陷。 要想有效地使用 CI 必须转变开发团队的习惯,要鼓励频繁迭代构建, 并且在发现 bug 的早期积极解决。

3、CD

这里的CD可对应多个英文名称,持续交付Continuous Delivery和持续部署Continuous Deployment。下面我们分别来看看上面是持续交付和持续部署。

3.1、持续交付(CD)

持续交付(CD)实际上是 CI 的扩展,其中软件交付流程进一步自动化,以便随时轻松地部署到生成环境中。 成熟的持续交付方案也展示了一个始终可部署的代码库。使用 CD 后,软件发布将成为一个没有任何紧张感的例行事件。 开发团队可以在日常开发的任何时间进行产品级的发布,而不需要详细的发布方案或者特殊的后期测试。

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

img

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

CD 集中依赖于部署流水线,团队通过流水线自动化测试和部署过程。此流水线是一个自动化系统, 可以针对构建执行一组渐进的测试套件。CD 具有高度的自动化,并且在一些云计算环境中也易于配置。在流水线的每个阶段,如果构建无法通过关键测试会向团队发出警报。否则,将继续进入下一个测试, 并在连续通过测试后自动进入下一个阶段。流水线的最后一个部分会将构建部署到和生产环境等效的环境中。 这是一个整体的过程,因为构建、部署和环境都是一起执行和测试的,它能让构建在实际的生产环境可部署和可验证。

3.2、持续部署(CD)

持续部署扩展了持续交付,以便软件构建在通过所有测试时自动部署。在这样的流程中, 不需要人为决定何时及如何投入生产环境。CI/CD 系统的最后一步将在构建后的组件/包退出流水线时自动部署。 此类自动部署可以配置为快速向客户分发组件、功能模块或修复补丁,并准确说明当前提供的内容。采用持续部署的组织可以将新功能快速传递给用户,得到用户对于新版本的快速反馈,并且可以迅速处理任何明显的缺陷。 用户对无用或者误解需求的功能的快速反馈有助于团队规划投入,避免将精力集中于不容易产生回报的地方。

随着 DevOps 的发展,新的用来实现 CI/CD 流水线的自动化工具也在不断涌现。这些工具通常能与各种开发工具配合, 包括像 GitHub 这样的代码仓库和 Jira 这样的 bug 跟踪工具。此外,随着 SaaS 这种交付方式变得更受欢迎, 许多工具都可以在现代开发人员运行应用程序的云环境中运行,例如 GCP 和 AWS。但是对于一个成熟的CI/CD管道(Pipeline)来说,最后的阶段是持续部署。作为持续交付——自动将生产就绪型构建版本发布到代码存储库——的延伸,持续部署可以自动将应用发布到生产环境。目前最受欢迎的自动化工具是 Jenkins,后面我们也将详细介绍关于 Jenkins 的相关内容。

img

持续部署意味着所有的变更都会被自动部署到生产环境中。持续交付意味着所有的变更都可以被部署到生产环境中,但是出于业务考虑,可以选择不部署。如果要实施持续部署,必须先实施持续交付。持续交付并不是指软件每一个改动都要尽快部署到产品环境中,它指的是任何的代码修改都可以在任何时候实施部署。持续交付表示的是一种能力,而持续部署表示的则一种方式;持续部署是持续交付的最高阶段。

4、Agile Development

最后我们再来看看上面是敏捷开发,这个称呼似乎还没有所谓的简称,而且这个称呼似乎在国内被滥用了。敏捷开发着重于一种开发的思路,拥抱变化和快速迭代。如何实现敏捷开发,目前似乎尚没有完善的工具链,更多的是一种概念性,调侃的说法“既想马尔跑得快,又想马儿不吃草”的另外一种说法。

img

上图揭示了敏捷开发的一些内涵和目标,似乎有点儿一本真经的胡说八道的意思。对于上面概念性的内容每个人的理解都有所不同。就好比CGI 这个词,即可以理解成CGI这种协议,也可以理解成实现了CGI协议的软件工具,都没有问题,咬文嚼字过犹不及。最后我们通过下面的图来看看前面讲到的CI、CD和DevOps之间的关系 :

img

以上是关于什么是 CI/CD ?的主要内容,如果未能解决你的问题,请参考以下文章

Jenkins CI CD

Jenkins与Docker的自动化CI/CD流水线实战

CI/CD

SpringBoot+Git+Jenkins+Docker实现CI/CD

Docker——Jenkins + Git + Registry构建自动化持续集成环境(CI/CD)

Jenkins与Docker的自动化CI/CD实战