云技术社区

Zuul:为了改进CI/CD而生,顺便淘汰了Jenkins

Posted on 2020-03-02

Jenkins是一个了不起的软件。作为一个执行和自动化引擎,它是你能找到的最好的引擎之一。Jenkins是无数持续集成(CI)系统的关键组成部分,但它本身不是一个CI系统,它只是为你运行东西。它做得非常好,有各种内置的插件和充满活力的插件生态系统,可以帮助你明白它在何时何地运行什么。

从根本上讲,CI旨在以尽可能高的频率和尽可能少的摩擦将多个软件开发流的工作集成到一个连贯的整体中。Jenkins并不知道你的源代码,也不知道如何将它们合并在一起,也不知道如何提供建设性的反馈。当然,你可以将它与其他可以执行这些活动的软件结合在一起,这就是CI系统包含Jenkins的方式。OpenStack也是如此。

没有测试就不行

2010年,一个名为OpenStack的开源项目社区形成。一些参与协作基础设施的开发人员还参与了一个名为“Drizzle”的免费数据库项目,该社区的一个关键理念是“没有测试就不行”。因此,OpenStack从最开始就要求,在被批准合并到任何源代码仓库的主干之前,对所有提议的更改进行审查和回归测试。为此,Hudson(后来分叉形成Jenkins项目)被配置为每个更改都运行测试。

一个插件用来与Gerrit代码评审系统接口,在提出新的更改时自动触发作业,并用评审注释返回报告,指出它们是成功还是失败。以今天的标准来看,这可能还不成熟,但在当时,这是开源协作的革命性进步。在CI看来,OpenStack上没有一个开发人员是特别的,每个人的更改都必须通过测试才能合并,这叫做“项目门控”。

然而,这种门控的想法有一个新的缺陷:为了保证两个无关的更改不会以功能上不兼容的方式改变一个软件,在它们合并之前,必须按顺序逐个测试它们。当时,OpenStack的安装和测试很复杂,并且很快就变得流行起来。开发人员贡献的不断增加,再加上测试覆盖率的不断提高,意味着在繁忙时期,根本没有足够的时间测试通过评审的每一个更改。一些运行时间更长的作业需要将近一个小时才能完成,因此可以通过门限的上限大约是一天内二十几次更改。

迎来Zuul

在2012年5月的OpenStack CI会议上,CI团队成员之一James Blair宣布他“一直在研究Jenkins作业的推测性执行。”推测性执行是现代微处理器管道中最常见的一种优化。与处理器硬件类似,该理论认为,通过对最近批准但尚未完成测试的更改乐观地预测正选通结果,随后批准的更改可以同时测试,然后有条件地合并,只要其前任也通过测试并合并。James给智能调度程序取的名字是:Zuul。

在此时间范围内,试图对Jenkins的XML作业配置执行更好的修订控制带来的挑战,导致了基于人类可读YAML的Jenkins Job Builder模板引擎的创建。Jenkins的JClouds插件的有限成功,以及使用作业来刷新一次性Jenkins的云镜像的繁琐尝试,都随着Nodepool服务的创建而结束。有限的日志存储能力使得团队添加了单独的外部解决方案,用于组织、服务和索引作业日志,并假设维护了一个废弃的安全复制协议(SCP)插件(取代Jenkins提供的现成的不太安全的FTP选项)。OpenStack基础设施团队围绕着Jenkins慢慢地构建了一系列服务和实用程序,但是开始遇到性能限制。

胜过Jenkins

到2013年年中,Nodepool一直在回收多达100台在Jenkins注册为slave的虚拟机,但这已经不足以跟上不断增长的工作量。Jenkins中全局锁的线程争用阻止了所有超过此阈值的尝试,无论主服务器上有多少处理器功率和内存。该项目曾提出为Jenkins slave捐赠额外的能力,以帮助缓解频繁的工作积压,但这将需要一个额外的Jenkins master。多个master之间的有效分工需要一个新的通信渠道来调度和协调作业。Zuul的维护人员认为Gearman作业服务器协议是一个理想的匹配,因此他们为Zuul提供了一个新的geard服务,并为Jenkins扩展了一个自定义Gearman客户端插件。

现在,工作分布在越来越多的Jenkins master上,不再有任何一个单一的仪表盘可以完整地查看工作活动和结果。为了促进新的多master,Zuul开发了自己的status API和WebUI,以及通过StatsD协议发送指标的功能。在接下来的几年里,Zuul稳定地吸收了更多用户所依赖的CI特性,而Jenkins在该系统中的地位也随之下降。

OpenStack很早就选择对Python编程语言进行标准化——这反映在Zuul的开发中,而Jenkins及其插件是用Java实现的。Zuul的配置以与OpenStack用来模板化Jenkins作业相同的YAML序列化格式进行维护,而Jenkins则将所有内容都保存在baroque XML中。这些差异使正在进行的维护复杂化,并导致来自相关社区的新管理员的学习曲线变得不必要的陡峭(这些相关社区已经开始尝试运行Zuuls)。

又一次革命的时候到了。

Ansible的崛起

2016年初,Zuul的维护人员开始了一项雄心勃勃的为期一年的全面检查,以期将Jenkins从整体系统设计中剔除。这时,Jenkins只是作为一个管道,通过SSH在slave上运行主要由shell脚本组成的作业,提供作业输出的实时流,并将生成的结果复制到长期存储。人们发现Ansible非常适合第一个需求——它是专门为通过SSH远程运行命令而构建的,它是用Python编写的(就像Zuul一样),还使用YAML来定义它的任务。它甚至还为先前作为定制Jenkins插件实现的功能提供了内置模块。Ansible提供了真正的多节点即时支持,因此相同的palybook可用于模拟和执行复杂的生产部署。不断扩展的第三方模块生态系统填补了空白,就像以前Jenkins社区的插件一样。

一个新的Zuul执行器服务填补了Jenkins master之前的角色:它对调度程序geard中的挂起的请求执行操作,通过Ansible将它们发送到Nodepool管理的临时服务器,然后收集结果和工件以供发布。它还公开了基于经典RFC 742 Name/Finger协议的正在进行的build输出,从Ansibe的命令输出模块的扩展进行实时流式传输。一旦不再需要将作业限制在Jenkins的解析器可以理解的范围内,Zuul就可以自由地增加新的功能,比如分布式存储库作业定义、在具有继承和安全处理机密的项目之间共享,以及测试为作业本身提出更改的能力。Jenkins的时代终于要结束了。

关于未来

Zuul的社区喜欢说,它通过预测性执行的新颖应用“测试未来”。曾经,你想对现有的作业进行改进,会担心一旦应用到生产中是否会使它失去功能,现在这种令人痛心的日子一去不复返了。大型中央作业存储库的过载审查团队已经成为过去。作业被视为软件的一部分,并与其他源代码一起提供,利用Zuul的其他功能(如跨存储库依赖关系),这样,你对一个项目中作业的一部分所做的更改可以与另一个项目中的提议作业更改一起执行。它甚至会对你的作业更改进行评论,突出显示有语法问题的特定行,就像是一个代码审阅者给你提供建议一样。

这些都是Zuul以前梦寐以求的功能,但这些需要从Jenkins那里获得自由,这样它就可以将作业解析交给自己。这是CI的未来,Zuul的用户可以实现这一点。

2019年初,OpenStack基金会承认Zuul是一个独立的、公开治理的项目,拥有自己的身份和繁荣的社区。如果你对开源CI感兴趣,可以考虑一下参与Zuul下一个演进的开发。


Posted in OpenStack
咨询热线:400-100-3070

北京易捷思达科技发展有限公司:北京市海淀区西北旺东路10号院东区1号楼1层107-2号

南京子公司:江苏省南京市雨花台区软件大道168号润和创智中心B栋一楼西101

上海office:上海黄浦区西藏中路336号华旭大厦22楼2204

郑州分公司:河南省郑州市中原区西三环路大学科技园东区14号楼3层北户301

成都分公司:成都市高新区199号天府三街太平洋保险金融大厦A区8楼


邮编:100094


邮箱:

contact@easystack.cn (业务咨询)

partners@easystack.cn(合作伙伴咨询)

marketing@easystack.cn (市场合作)

training@easystack.cn (培训咨询)

hr@easystack.cn(招聘咨询)

Copyright © 2017 EasyStack Inc. All Rights Reserved. 京ICP备16000234号-1 京公网安备 11010802024994号