中国国际金融股份有限公司首席信息官 程龙
随着金融数字化转型的持续深入,团队规模扩大引发了构建资源紧张、构建需要排队等诸多问题。Jenkins作为DevOps平台的典型构建工具,通过灵活地进行代码编译、打包、部署,可高效支持多种类型的构建或持续集成。根据Slave节点不同的生成方式,可分为静态构建和动态构建两种模式。其中,动态构建是指基于Kubernetes的弹性工作负载机制,当构建任务被触发时,由JenkinsMaster临时从K8S集群中实例化工作节点,并在容器化的Pod中执行构建动作。然而,在代码编译过程中,当一个模块发生编译,往往会造成其他模块跟着一起重新编译,从而浪费大量的构建时间。对此,中国国际金融股份有限公司(以下简称“中金公司”)设计研发了一种基于云原生技术的持续交付构建服务平台,旨在为金融机构进一步节省构建资源、保证构建环境纯净、提高构建效率探索出一条可行路径,以助力金融机构更好实现高质量发展。
一、动态构建技术难点问题分析
当前,Jenkins针对构建后的Pod Retention主要有Never、Always、Default、On
failure等四种保留策略。其中,Never表示构建后删除构建节点;Always表示构建后保留构建节点;Default表示使用保留时间设置;Onfailure表示当构建失败时保留节点,其他情况删除节点。具体而言,如果设置为Never,则删除后下次构建仍需消耗一定的时间,不具备构建后立即重建的能力,多次的快速点击容易导致构建失败;如果设置为Always,则构建后不删除节点;如果设置为On
failure,即是指构建失败时保留节点,构建成功则删除节点;如果设置为Default,则是指在设置代理的空闲存活时间内可以保留节点,但易导致构建环境不够纯净,如不同构建任务下载的Jar包可能存在冲突或者修改了网络代理,两者都会导致构建失败。
现阶段,Jenkins动态构建主要存在以下问题:一是每次创建Pod,即便经过参数优化提高产生Jenkins
Slave的速度,也需要消耗一定时间;二是构建过程不能排队,针对同一任务的连续快速构建容易失效;三是当动态构建设置为Default时,设置保留时间虽然可以解决构建的连续性问题,但是构建环境并非纯净,且缺少删除Pod后自动重建的能力;四是动态构建的JNLP镜像不支持修改自身Agent的标签,即如果完成构建后对Agent赋予新的标签,Jenkins
Kubenetes插件通常不支持该操作。此外,如果在JNLP镜像中增加构建后删除Pod的操作,也易导致JNLP断开连接而使Jenkins构建失败,并影响整个Jenkins的构建结果。简言之,即当前的动态构建技术不具备构建后打新标签以及删除Pod的能力。
二、基于云原生的持续交付构建服务平台建设思路
为解决现有动态构建技术存在的问题,中金公司基于云原生技术,创新推出了持续交付构建服务平台,其功能主要包括动态构建资源管理和构建加速两部分(如图1所示)。在此模式下,用户可以通过Web端执行构建任务请求,并使用资源池中的执行机进行构建。其中,动态构建资源管理器可调用Jenkins
Master集群中的Jenkins API,以及Kubernetes平台中的Kubernetes API
server来创建和管理资源池,并将Jenkins和Kubernetes的配置信息存储于数据库中,包括Jenkins
Master信息、标签名称、Slave前缀名称、资源池Pod的最大个数、资源池最少空闲的Pod个数、创建Agent Pod的配置信息等。
图1 持续交付构建服务平台架构
1.动态构建资源管理器应用设计
动态构建资源管理器主要通过调用服务来创建和管理资源池。具体而言,动态构建资源管理器是一个微服务应用,通过数据库配置Jenkins、K8S集群、构建资源模板、资源规模、维护策略等相关信息与Jenkins和K8S集成,并以此来创建和管理动态构建资源。动态构建资源是一组K8S
Pod形态的构建执行机,基于标准容器的镜像模板生成,主要有两种生成方式:一种是使用固定策略预先创建一组执行机;另一种是构建任务到达时,临时创建执行机。其中,后者通常在没有可供调度的空闲执行机时采用。
在工作机制方面,动态构建资源主要通过执行机的状态标签(如“可回收”)和空闲标志来判定是否有构建任务在此执行机上运行过且已结束,再根据回收策略决定是立即销毁资源还是保留(用于现场查错)。新的构建任务则会选择其他可用执行机,以保证每次构建资源的纯净。同时,状态标签通常在构建任务结束时标记为“可回收”,由独立的维护进程定时清理,并在回收资源时同步创建新的执行机补充到资源池。此外,通过动态构建资源的维护机制,多数构建任务均可分配到空闲执行机立即运行,仅在全部执行机都被占用时,才会临时创建新的执行资源,而通过对资源池的使用情况进行监控告警,还可根据业务繁忙程度进行自动扩容或缩容。
发起构建任务之后,Jenkins
Master负责进行任务调度,并判断资源池是否有空闲资源(如图2所示)。如果资源池有空闲的资源,则资源池的执行机进行构建,当构建结束之后标记Slave
Agent的标签为预定义标签值(如“dirty”)并生成新的Agent。这样能保证下次构建时已经使用过的Agent不会再次被调度执行。如果资源池没有空闲的资源,则直接进行动态构建,设置Pod
Templete的模板配置策略,一般为Never,可以实现构建后立即删除Slave
Pod。根据预定义标签值和执行机的idle标志双重判断构建是否已经结束,如果包含预定义标签的Slave
Agent已经构建结束,即可执行删除操作进行资源回收。
图2 构建资源池操作流程
2.构建加速实现路径
基于不断提高企业开发效能的目标,需要提供一种构建加速能力,即针对Gradle和Maven构建技术栈,实现三大核心能力。一是构建基础平台,收集并统一管理软件开发构建阶段的生命周期元数据,以便加强组内协同开发、加速故障定位、缩短分析处理故障的时间。二是搭建构建缓存平台,利用分布式构建缓存技术,避免重复构建任务执行,减少构建耗时,提高开发体验。三是打造分布式单元测试平台,通过将单元测试在资源池中分布式执行,节省单元测试时间,缩小反馈闭环,缩短质量测试周期。
构建加速的主要原理是在每个任务构建前检查输入的哈希值,如果在缓存中找到相同的哈希值,即使用缓存的输出作为本次构建的结果,也无需再次构建,进而提高构建效率。具体而言,在构建缓存阶段,当下次需要构建相同的项目时,可以直接获取缓存构建过程中生成的文件和元数据,避免重复构建。在增量编译阶段,通过检测哪些代码发生了变化,只需重新编译发生变化的部分,而不必重新编译整个项目。此外,构建机上挂载缓存的数据卷时,通过将构建的中间结果进行缓存,将可在下次构建时直接从缓存中读取,减少网络传输开销。
构建基础平台主要包括以下功能:一是基础信息收集,包括构建工具、构建插件版本、构建操作系统、构建开始时间和结束时间等,可以让开发人员快速了解构建环境,掌握和对应基础构建信息。二是构建的性能分析,即在构建信息中展示Gradle或Maven构建的各阶段执行时间,并以此分析工程结构对构建性能的影响,以及生命周期中其他的潜在性能问题。三是单元测试展示,包括测试用例、测试结果、执行时间等,同时通过分析耗时较长的单元测试用例,为技术债务持续优化提供依据。四是基础设施信息收集,包括操作系统、CPU、JDK版本、JVM内存大小、所在机器信息等基础环境信息。五是总览页面,即除了展示上述基础信息外,还可展示构建语言的构建时间、同种构建语言不同版本的构建时间,以及展示不同项目、不同项目组和不同构建任务标签下的构建情况。
3.告警设计及应用成效
在监控告警方面,中金公司通过将动态构建资源池中的Agent标签设置为特定值(如“pool”),并使用Prometheus和Grafana将Jenkins
Jobs Stats模板中的Executors Busy per
Label(Stacked)标签设置为资源池中Agent的标签,实现了告警信息配置,即当资源池中执行机的个数为N,且当繁忙个数等于N-1时,发送告警信息告知管理员并执行扩容操作。同时,针对预定义标签的Agent进行监控,如果一定时间之内还存在预定义标签(如“dirty”),则说明资源没有被及时回收,将发出告警通知并予以删除。值得注意的是,采用特定标签值不仅可用于监控本方案中的构建资源池,还可针对不同类别的构建机设置不同的标签进行分类监控。
构建服务平台自2023年5月上线以来,虽然构建任务持续增加,但构建任务的等待时间呈下降趋势。构建任务平均等待时间趋势如图3所示。节省构建耗时方面,以某项目28天数据为例,代码仓库提交人数44人,所有人员构建13200次,平均节省时间为3分钟每次,月均节省时间为660小时。
图3 构建任务平均等待时间趋势
2023年7月,中金公司基于云原生的持续交付构建服务平台入选中国信息通信研究院主办的2023XOps“领新杯”“研运质效突破引领案例”和《中国DevOps现状调查报告(2023)》“优秀实践案例”。通过搭建持续交付构建服务平台,中金公司有效解决了动态构建初始化效率低,构建资源创建过程中构建任务不能排队、删除后不能自动重建等问题,实现了保证构建环境纯净、节省构建资源、提高构建效率等目标,为助力金融科技高水平发展提供了新方法、新路径。
作者:中国国际金融股份有限公司首席信息官 程龙
信息技术部执行总经理 叶明登
信息技术部 任党恩 王如迅 冯赫
|