[CI/CD] 什么是CI/CD?

981 阅读14分钟

CI/CD 的概述

WX20240724-112618@2x.png

CI/CD 是一种在开发阶段引入自动化来频繁向客户交付应用的方法

CI/CD 的核心概念是持续集成、持续交付和持续部署。它是作为一个面向开发和运维团队的解决方案,主要针对在集成新代码时所引发的问题

CI/CD 可让持续自动化和持续监控贯穿于应用的整个生命周期(从集成和测试阶段,到交付和部署)

这些关联的事务通常被统称为 CI/CD 管道(pipeline),由开发和运维团队以敏捷方式协同支持

1. 持续集成(Continuous Integration)

1.1 什么是持续集成

Continuous Integration:持续集成,简称CI,是软件开发周期的一种实践,把代码仓库(Gitlab或者Github)、构建工具(如Jenkins)和测试工具(SonarQube)集成在一起,频繁的将代码合并到主干然后自动进行构建和测试。简单来说持续集成就是一个监控版本控制系统中代码变化的工具,当发生变化是可以自动编译和测试以及执行后续自定义动作。

在传统的软件开发中,集成过程通常在每个人完成工作后的项目结束时进行。整合通常需要数周或数月的时间,可能会非常痛苦。持续集成是一种将集成阶段置于开发周期中较早的做法,因此,构建,测试和集成代码的时间安排更为规则。

敏捷开发中开发人员通常使用称为CI Server的工具来进行构建和集成。CI要求自检代码。这是用于自我测试以确保其按预期工作的代码,这些测试通常称为单元测试。集成代码后,当所有单元测试通过时,将得一个最新的的代码版本。这表明他们已经验证了自己的更改已成功集成到一起,并且代码按测试期望的那样工作。

2098378-20221027153514239-553284460.webp

解读上图

  • 开发人员(代号,10101)提交代码到Source Repository(源代码仓库,如 GitLab)
  • 有代码更新到代码仓库后,会通过 WebHook自动触发CI Server(持续集成服务器,如 Jenkins)的相关功能,执行编译-测试-输出结果的流程,这里的测试一般只包含单元测试,不是我们常说的功能测试,也不是接口测试
  • CI Server会将执行结果的report返回给开发人员

1.2 持续集成好处

  1. 快速发现错误,每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易
  2. 节省人力成本
  3. 加快软件开发进度,让产品可以快速迭代,同时还能保持高质量

1.3 持续集成总结

  • 持续集成仅仅是让所有开发提交的代码成功集成到代码库中并正常协同工作。
  • 代码集成到主干之前,先进行自动化测试,只要有一个测试用例失败,就不能集成,当然持续集成并不能完全的消除bug,而是让他们非常容易发现和改正。
  • 没有经过针对合入代码的自动化测试,所以集成的代码并不能马上发布到生产环境

2. 持续交付(Continuous Delivery)

2.1 什么是持续交付

Continuous Delivery:持续交付,简称CD,是在CI的基础进行了扩展,在CI环节完成了软件构建和测试工作并形成了新的版本,那么接下来就要进行交付,而这里的交付并不是交付到生产环境,而是类生产环境(STAGING),我们可以理解为灰度环境或者预发环境,进而接受部分真实流量的测试。如果没有问题的话则通过手动的方式部署到生产环境。

简化的含义为:一种能够使得软件在较短的循环中可靠地发布的软件工程方法。

与持续集成相比,持续交付的侧重点在于 交付,其核心对象不在于代码,而在于可交付的产物。

由于持续集成仅仅针对于新旧代码的集成过程执行了一定的测试,其变动到持续交付后还需要一些额外的流程。

2098378-20221027153525990-1782378259.webp

解读上图,可以看到与持续集成相比较,持续交付添加了 Test->Staging->Production 的流程,也就是为新增的代码添加了一个保证:确保新增的代码在生产环境中是可用的。

  • 代码提交(CI已包括)
  • 单元测试(CI已包括)
  • 合入代码(CI已包括)
  • 测试(Test):接口或UI自动化测试、集成测试、系统测试,代替人工测试
  • 部署到预发环境(预生产环境Staging):在预发环境进行产品的主流程验证,验证通过再执行下一步
    • 预生产环境 Staging:尽可能地对真实的网络拓扑、数据库数据以及硬件设备等资源进行模拟,从而为测试人员反馈代码在生成环境中的可能表现。
  • 手动部署到生产环境(Production):开发手动部署

流程中每一个环节的执行结果都会对开发人员进行反馈,每一个出现的错误都会导致版本的回滚。当测试完毕确认无误之后,将由相关人员对其进行 手动部署到生产环境。

2.2 持续交付小结

  • 持续交付是持续集成的延伸,将集成后的代码部署到类生产环境,确保以可持续的方式快速向客户发布新的更改
  • 经过持续交付,即可手动部署到生产环境
  • 持续集成的重点是集成代码,但持续交付的重点是可交付的产品。可交付的产品一定要有达标的质量,确保产品在生产环境没问题,所以在CI集成代码之后,还需要进行自动化测试、集成测试。

3. 持续部署(Continuous Deployment)

3.1 什么是持续部署

Continuous Deployment:持续部署,简称CD,它是在持续交付的基础上打通最后一公里的工作,就是把手动部署到生产环境的方式升级为自动部署。看下图和上图在最后部署到生产环境中的区别。

简化的含义为:通过自动化部署的手段将软件功能频繁地进行交付。

与持续交付以及持续集成相比,持续部署强调了通过 automated deployment 的手段,对新的软件功能进行集成。

2098378-20221027153546008-1745451204.png

解读上图,与第二张持续交付的图片对比后,发现只有一点差别,就是自动化部署生产(Production)环境

所以说,持续部署与持续交付之间的差异就是前者将部署自动化,开发人员提交代码到编译、测试、部署的全流程都不需要人工干预,完全自动化执行。

3.2 持续部署好处

这一策略加快了代码提交到功能上线的速度,保证新的功能能够第一时间部署到生产环境并被使用。

4. 为什么要使用CI/CD

总结CI/CD是为了实现以下几个目的:

  1. 快速交付:CI/CD 自动化流程可以使软件交付过程更快、更频繁,减少了手动操作和人工干预的时间。这样可以更快地将新功能、修复和改进的代码交付给用户,满足市场需求并保持竞争优势。

  2. 提高质量:持续集成通过频繁地集成和构建代码,并进行自动化测试和静态代码分析,有助于发现和解决问题。通过尽早发现和修复缺陷,可以提高软件的质量和稳定性。

  3. 自动化部署:持续交付将部署过程自动化,从而减少了手动部署的错误和风险。通过自动化部署流程,可以确保软件在不同环境中的一致性,并减少了部署时间和工作量。

  4. 可靠性和可重复性:CI/CD 强调自动化和标准化的流程,使软件交付过程变得可靠和可重复。每次构建、测试和部署都是基于相同的流程和环境,减少了人为因素的影响,提高了软件交付的一致性和可靠性。

  5. 团队协作与反馈:CI/CD 促进了团队成员之间的协作和沟通。通过频繁地集成和交付,团队成员可以及时了解彼此的工作进展和变更,减少代码冲突和集成问题,并能够更好地合作解决出现的问题。

  6. 可追溯性和回滚能力:由于 CI/CD 自动化流程的记录和版本控制,可以轻松追踪每个构建和部署的结果。这样,在出现问题时可以快速定位和回滚到之前的可用版本,减少了故障修复时间和影响范围。

总而言之,CI/CD 提供了一种高效、可靠和可持续的软件交付方法。它可以加速软件开发和交付的速度,提高软件质量和可靠性,并促进团队之间的协作和反馈。通过使用 CI/CD,组织可以更好地适应市场需求,降低软件交付的风险,并实现持续创新和改进。

5. CI/CD的缺点

  1. 配置和维护成本:实施 CI/CD 需要配置和维护相应的自动化工具和流程,这可能涉及一定的学习曲线和资源投入。

  2. 学习和文化变革:CI/CD 需要团队成员适应持续集成和持续交付的理念和工作方式,可能需要进行培训和文化变革,以适应新的开发流程。

  3. 环境和依赖管理:CI/CD 要求在自动化流程中管理好开发、测试和生产环境的配置和依赖关系,这可能需要额外的工作和注意力。

  4. 安全和合规性考虑:CI/CD 强调快速交付和自动化,但在安全和合规性方面可能需要额外的考虑和措施,以确保敏感数据和法规要求的合规性。

  5. 项目复杂性和规模限制:对于大规模和复杂的项目,CI/CD 的实施可能需要更多的配置和定制化工作,以适应项目的规模和复杂性。

6. CI/CD常用服务和工具

  1. 版本控制系统:如Git(例如GitHub、GitLab、Bitbucket等)用于管理代码版本和协作开发。

  2. 持续集成服务:如Jenkins、CircleCI、Travis CI、GitLab CI/CD等,用于自动化构建、测试和集成代码。

  3. 容器化平台:如Docker和Kubernetes,用于创建和管理容器化的应用程序环境,实现应用程序的可移植性和一致性。

  4. 云平台和部署服务:如Amazon Web Services(AWS)、Microsoft Azure、Google Cloud Platform(GCP)等,提供了各种云计算服务和部署工具,如AWS CodePipeline、Azure DevOps、Google Cloud Build等。

  5. 自动化测试工具:如Selenium、JUnit、Pytest等,用于编写和执行自动化测试脚本,验证代码的功能和质量。

  6. 静态代码分析工具:如SonarQube、ESLint、PMD等,用于静态代码分析和检查,帮助发现潜在的代码质量问题。

  7. 配置管理工具:如Ansible、Chef、Puppet等,用于自动化配置和管理应用程序和基础设施的环境。

  8. 日志和监控工具:如ELK Stack(Elasticsearch、Logstash、Kibana)、Prometheus、Grafana等,用于收集、分析和监控应用程序的日志和指标。

这些服务和工具可以根据具体需求进行组合和配置,形成一个符合项目要求的 CI/CD 工作流程。

7. 灰度发布

7.1 背景

线上的项目最容易出现问题的时候就是发布的过程中。如果将某变化较大的版本一次全部线上发布给用户,遇到生产事故对用户的影响会非常大,甚至有时需要紧急回滚到前一版本。因此在发布的时候可以采取一些措施来防止问题的扩散。常见的发布方案有:蓝绿发布滚动发布灰度发布

7.2 什么是灰度发布

灰度发布,又名金丝雀发布,是指在黑与白之间能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继灰度发布是对某一产品的发布逐步扩大使用群体范围,也叫灰度放量。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

17世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯,金丝雀也会停止歌唱;而当瓦斯含量超过一定限度时,虽然鲁钝的人类毫无察觉,金丝雀却早已毒发身亡。当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为“瓦斯检测指标”,以便在危险状况下紧急撤离。

7.3 灰度发布流程

在灰度发布开始后,先启动一个新版本应用,但是并不直接将流量切过来。测试成功后,将少量的用户流量导入到新版本上,然后再对新版本做运行状态观察,收集各种运行时数据,如果此时对新旧版本做各种数据对比。当确认新版本运行良好后,再逐步将更多的流量导入到新版本上,在此期间,还可以不断地调整新旧两个版本的运行的服务器副本数量,以使得新版本能够承受越来越大的流量压力。直到将100%的流量都切换到新版本上,最后关闭剩下的老版本服务,完成灰度发布。

image.png

常见名词

  • 灰度期:灰度发布开始到结束期间的这一段时间,称为灰度期。续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。

  • 流量切分:例如具体在部署的服务器上,给最初更新的10台服务器设置较低的权重、控制发送给这10台服务器的请求数,然后逐渐提高权重、增加请求数。这个过程叫流量切分。

7.4 灰度策略

  1. 按照比例划分:可以搭配负载均衡使用,如5%的用户首先使用新的版本,95%的仍然使用老版本。

  2. 按照用户属性划分:如限制IP、地域、性别、年龄或者浏览时间、客户等级等等用户画像,例如活跃度高的用户优先使用新版本

  3. 按照渠道划分:如内部客户优先使用新版本,大客户要保证服务稳定,使用旧版本

可以根据自己的业务情况以及变更情况修改自己的灰度策略。例如,某产品UI发生了变化,可以根据比例进行流量切分;某产品上线了新的接口,可以按照用户属性,优先内部客户和中小客户使用新版本。

但是,为了找到符合业务逻辑和需求的灰度发布,是需要开发人员进行额外的开发工作的,尤其项目如果同时涉及前端和后端,需要两边都要进行灰度发布的支持。

8. 文章推荐

Basics of CI/CD | by Semyon Kirekov | Medium | Level Up Coding