作者:达日汗,中国农业银行研发中心,系统支持部
CI (Continuous Integration)在维基百科中的定义是:经常将几个小改动合并到一个主分支中,强调开发人员提交了新代码之后,立刻进行构建和(单元)测试。持续集成可以帮助开发人员尽早定位到错误,控制开发流程,减少大量不必要的工作,提高工作效率。一个好的持续集成和持续部署管道(CI/CD)可以使项目开发事半功倍。下面介绍一种使用Jenkins搭建持续集成流水线的方法。
Jenkins简介
Jenkins 是一个起源于Hudson(Hudson是商用的),使用 java 语言开发的开源持续集成工具,使软件项目可以进行持续集成,并且可以跨平台部署在 Windows、Linux和MacOS 等多种环境。经过十多年的发展 Jenkins 生态环境已经十分完善,大量插件的存在使得 Jenkins可以适应多种业务场景,是多数企业完成持续集成、持续部署等相关技术实践的首选。Jenkins 有如下几个特点:
-
开源免费且多平台支持。
-
安装配置简单。
从官网下载Jenkins执行文件后,直接运行,无需额外的安装,更无需安装数据库并且 提供友好的GUI配置界面,浏览器访问即可完成配置;
-
插件资源丰富。
除了官方插件外,Jenkins 支持第三方插件,这使得Jenkins 功能变得越来越大能够满足多种场景下的需求。
-
主从分布式架构。
主节点可只提供调度功能,增加从节点即可提高任务处理能力,扩展简便。
流水线运行流程
如下图所示,我们通过在前端页面编排好流水线,将其以描述文件的形式发送给后端Jenkins调度模块,描述文件包含了流水线内多个任务包括代码下载、代码构建和制品上传等。
调度模块将其转化成Jenkins任务配置文件并发送给Jenkins的Master节点完成任务的生成。最后Master节点将任务分发到Slave节点执行完成一次流水线的运行。
Jenkins支持通过网页端进行各类操作,但是实际应用中需要和项目前端对接,并且Jenkins的API接口比较完善,所以通过API接口的方式对Jenkins进行了调用。
图一
流水线任务转化
首先我们需要将前端编排的任务转化为Jenkins流水线任务。下图所示为通过页面生成Jenkins流水线任务,任务以Groovy脚本形式创建。Jenkins pipeline是基于Groovy语言实现的DSL,用于描述流水线如何进行,包括编译、打包、部署、测试等等步骤。其中一些基本概念如下:
-
pipeline: 代表整条流水线,包含整条流水线的逻辑。
-
agent部分:
指定流水线的执行位置(如:
物理机、虚拟机、Docker容器等)。
-
stage:
阶段,代表流水线的阶段,每个阶段都必须有名称,本例中,build就是此阶段的名称。
-
stages:
流水线中的多个stage的容器,stages部分至少包含一个stage。
-
steps部分:
代表阶段中的一个或多个具体步骤(step)的容器。
steps部分至少包含一个步骤,下图中echo就是一个步骤,在一个stage中有且只有一个steps。
图二
在Jenkins中每个任务都有其配置文件(config.xml),如图三所示,存放在Jenkins的主目录下Jobs文件夹内。我们找到一个配置文件打开之后可以发现在
图三
流水线任务执行
在上一阶段我们已经通过转换流水线描述文件生成了Jenkins 任务的配置文件,下一步将通过Jenkins API完成任务的创建和执行。Jenkins的API大致可以分为站点、节点和任务构建三部分,如下图所示。
图四
在节点层面:
Jenkins可以提供节点信息的查询、系统的负载统计、节点的上下线、重启和任务创建等接口。我们项目中主要涉及到任务的创建,通过http:///createItem 接口配合配置文件和任务名称完成任务的创建。
在任务层面:
Jenkins可以提供执行任务、修改任务、启用任务、禁用任务、删除任务等接口。我们主要关注任务的启动与删除,任务创建成功后通过该接口启动任务,http:///job//build,其中Job-Name需要替换为上一步生成任务时的名字。通过http:///job//doDelete接口可以实现任务的删除,这通常在任务成功执行所有步骤后触发。
在构建层面:
Jenkins可以提共构建信息获取的接口。我们通过http:///job//BuildID/logText/progressiveText 完成日志查询。同时如果想要获取流水线任务每一阶段的状态可以通过http:///job//BuildID/wfapi/describe接口进行查询。(注:该接口非Jenkins原生,是pipeline stage view插件附带的接口)
在实际的应用过程中既可以通过原生API对Jenkins进行操作也可以通过第三方库完成功能实现。
Jenkins 部署方法
Jenkins性能问题依然是不可忽视的一点,单个Master节点 job数量达到一定程度时会开始出现延迟的情况,同时Slave节点的数量也需要进行控制,如果过多会出现大量Slave连接在构建过程中中断的情况,甚至可能会出现Slave连接丢失的情况。
在官方文档中推荐:Master节点每一个处理器核心对应500个任务,每500个任务对应15个executor(约等于一个CPU核心的Slave节点15台)在实际部署过程中我们根据CI流水线需求的不同预先将Master节点拆分为多个,根据不同的需求在调度模块将任务分流,以避免单个Master节点在高负载环境下出现性能问题。
图五
至此我们通过Jenkins完成了CI流水线的建设。Jenkins功能十分丰富,其应用场景有待进一步研究与挖掘。