2.2 OpenStack CI/CD

OpenStack作为现在世界上第二大开源社区,有着一个完整的、标准化的、自动化的持续集成测试平台。它由社区的OpenStack-Infra团队开发维护,具有高可靠性、灵活性和可扩展性,对于搭建企业内部CI/CD系统有非常好的借鉴意义。

注解

社区的持续交付,主要应用于版本发布,后文如不做特殊说明,CD指的都是持续交付。框架上是支持持续部署的。

2.2.1 当前CI/CD系统的形态

以Jenkins作为持续集成工具为例,CI/CD系统的复杂程度分4个等级:

第1级:如图2-4所示,仅使用Jenkins,且都在一套服务器上,适用于产品项目较小、资源较少的场景,使用维护较为简单。

图2-4 CI/CD 1级

第2级:如图2-5所示,在第1级的基础上引入了Gerrit评审系统,但是具体构建还是在本地,测试环境受限。

图2-5 CI/CD 2级

第3级:如图2-6所示,也是目前稍具规模的公司或社区都会使用的系统,使用Jenkins +Jenkins-Job-Builder(JJB)工具。在执行构建时,使用了一些静态资源(如虚机、容器或物理机),可以满足多场景构建和测试需求,但是资源利用率较低,多次测试的环境上下文存在耦合,目前OPNFV社区使用这种框架。

图2-6 CI/CD 3级

第4级:如图2-7所示,在第3级的基础上引入了任务门控系统(Zuul)和动态资源管理系统(Nodepool)的使用模式,也是目前OpenStack开源社区的应用。

图2-7 CI/CD 4级

首先我们来学习一下OpenStack社区的CI/CD框架。

2.2.2 OpenStack CI/CD架构

首先做个说明,社区的CI/CD已经演进到V3版本,版本之间的差异比较大,本文所有框架和组件的介绍都基于V2版本。

CI/CD系统框图如图2-8所示。大致分为以下几部分:

图2-8 CI/CD架构

Gerrit服务器:代码评审服务。

CI Master:主要由以下几个组件构成。

■ 任务门控系统(Zuul)

■ 持续集成系统(Jenkins)和Jenkins任务管理工具(JJB)

■ 节点资源池管理系统(Nodepool)

■ 集群任务分发系统(Gearman)

这一部分是系统的核心,从监听代码变更,到匹配需要运行的任务,再到触发任务在合适的节点运行。

CI Slave:即真正运行测试的节点,由Nodepool创建和管理,供Jenkins Master使用。

LogServer:日志服务器。

ELK日志分析服务器:可视化的日志分析平台。

制品库:版本发布服务器。

下面先简单介绍各组件功能,后续章节会对每个组件做详细介绍,包括工具原理和使用方法。

(1)Gerrit

代码评审管理系统,提供了提交和补丁管理功能,同时提供了丰富的用户权限管理,控制着哪些用户或组可以提交代码、合并代码、管理代码库并提供Gerrit事件流通知服务。

(2)Zuul

监听Gerrit事件流,匹配到对应的pipeline,以及该项目在这个pipeline下需要执行哪些任务。Zuul可以处理具有复杂依赖关系的多个补丁(Patch)。它能监控正在执行的任务,并可提前结束因依赖的Patch测试失败而必定失败的测试任务。

(3)Jenkins & JJB

Jenkins负责具体任务的构建,每个Jenkins任务都需要通过配置Jenkins的config.xml文件实现。而在任务数量达到一定级别后,手工去配置每个任务会变得非常复杂,而且手工配置常常会带来人为操作风险。

由图2-9可以看出,手工干预的步数越多,部署成功率越低。

图2-9 手工操作数VS部署成功率

XML文件也不易于维护,因此引入了JJB这个工具。顾名思义,JJB就是用来创建Jenkins任务的工具,支持Yaml或者Json格式存储Jenkins任务模板。JJB通过解析用户配置的文件来自动生成config.xml,支持模板和任务组的方式,复用性高。

(4)Gearman

Jenkins用的是Master/Slave架构,一台Master管理所有Slave节点。在Slave节点增加到一定数量后(大约100台), Jenkins的Master节点就会出现问题并成为瓶颈。同时Master节点是单点部署,无法完成HA等处理。为了扩展Jenkins而引入了Gearman,加入Gearman后,Zuul不再与Jenkins直接交互,而是提交执行任务的请求给Gearman服务器,由Gearman服务器完成任务的分发。通过Gearman,使得CI测试架构具有了伸缩性:通过部署多个Jenkins Master,实现了Jenkins Master的HA功能。

(5)Nodepool

管理和维护Jenkins Slave的服务,会在一个或多个已部署的OpenStack环境中自动创建Slave节点,并在Slave节点运行完一次测试后删除并重建。

(6)LogServer

日志服务器,用来存储任务构建的所有日志信息。如果测试失败,开发者可以查看日志信息排查故障,同时它也是ELK采集日志的源。

(7)ELK

可视化的海量日志分析平台,从日志服务器上采集日志进行存储、分析及可视化,可用于系统监控和故障排查等。

(8)制品库

存放发布版本的服务器。

2.2.3 CI/CD系统工作流程

CI/CD系统的框架有了,如何搭建并配置这套复杂的系统使各组件之间协作是本书要详细阐述的内容。这里先不做说明,后续章节会详细介绍各组件的搭建和配置,这里先总体介绍下各组件之间的协作流程。

1.准备工作

(1)Zuul

配置Zuul对接的Gerrit服务器。

定义pipeline以及每个项目在对应pipeline下运行哪些任务。

(2)JJB定义项目任务,解析任务并上传到Jenkins服务器。

(3)Nodepool

一个可用的OpenStack云环境。

编译镜像,上传到云环境。

连接到云环境,用上传的镜像孵化Slave节点资源池。

2.工作流

CI/CD系统的工作流程如图2-10所示:

图2-10 CI/CD工作流程

1)贡献者在Gerrit上提交新Patch、添加评论等。

2)Gerrit提交一个通知事件到它的事件流中(Event Stream)。

3)Zuul从Gerrit的事件流中读取事件,并准备好本地项目代码,然后匹配事件到一个或多个pipeline,并找到该Patch对应的项目下的pipeline任务,把任务提交给Gearman服务器。

4)Gearman把Job分发到可以执行该任务的Worker上。

5)Worker根据Slave节点信息在对应节点上构建任务。

6)构建后操作:把当前任务执行的日志信息和中间结果(包括编译结果)拷贝到日志服务器上。

7)返回任务结果到Jenkins的事件流中:

Jenkins通过消息方式通知Nodepool此次任务完成。

Nodepool删除执行该Job的Slave节点,并重新孵化新的节点。

Jenkins通过Gearman把当前的任务执行结果返回给Zuul。

8)根据测试结果,Zuul在Gerrit中对Patch添加一个Review结果。

9)贡献者在Gerrit上可以查看相关日志信息。

如果当前变更被批准合入主分支,即重复第(2)步进入持续发布阶段。