Learn Jenkins the hard way (0) - Jenkins的罪与罚

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: ## 写在开头 Jenkins是非常流行的开源的持续交付平台,拥有丰富的插件、文档与良好的社区。是国内大多数公司私有持续集成方案CI/CD服务器的选型。开发者可以快速的通过Jenkins搭架符合自己业务场景的pipeline,结合大量的开源插件,可以轻松的满足不同语言、不同平台、不同框架的持续集成场景。

写在开头

Jenkins是非常流行的开源的持续交付平台,拥有丰富的插件、文档与良好的社区。是国内大多数公司私有持续集成方案CI/CD服务器的选型。开发者可以快速的通过Jenkins搭架符合自己业务场景的pipeline,结合大量的开源插件,可以轻松的满足不同语言、不同平台、不同框架的持续集成场景。无论是风头蒸蒸日上的Gitlab-CI或者是在开源领域广受好评的travis.ci,都无法替代Jenkins在持续集成领域的地位。但是再高大的建筑也无法遮住阳光下的影子,Jenkins虽然有各种各样的优势,它的问题也足以令人扼腕。本系列的初衷是通过源码的方式学习Jenkins,改造Jenkins。

Jenkins的罪与罚

高可用性

作为持续集成领域多年的Top one,Jenkins的所有的数据存储竟然都是以xml文件的方式进行持久化的。在Jenkins启动的时候需要指定存储源数据的目录,可以通过JENKIN_HOME这个目录进行配置。JENKINS_HOME的目录结构如下:

1.4M    ./updates
180M    ./plugins
147M    ./cache
4.0K    ./.docker
60K     ./secrets
124K    ./.java
508K    ./logs
4.0K    ./fingerprints
8.0K    ./init.groovy.d
21M     ./monitoring
260K    ./users
44K     ./nodes
12K     ./.ssh
45G     ./jobs
74M     ./war
8.0K    ./userContent
45G     .

其中users中存放了和Jenkins用户相关的配置信息;jobs中存放和Jenkins的任务相关的信息,包括构建历史、构建配置等等;在nodes中存放了Jenkins子节点的相关配置信息。这就意味着,Jenkins的Master的水平无状态扩展成为了不可能,虽然Jenkins支持的Master/Slave的架构,可以支持一台Master并发数百个Slave,但是单台的Server的可靠性与稳定性都面临巨大的挑战。面对这样的情形,社区的开发者们提出了2种解决的方案:

分片+冷备的Jenkins企业版HA方案

这个方案是Jenkins的最大维护公司Cloudbees提出的,Cloudbees开发并提供Jenkins的企业版的支持,提供Jenkins Cloud,面向公有云、私有云、大型企业用户提供付费的Jenkins服务。针对于大型企业Jenkins集群的场景,Cloudbees提出了如下的解决方案:
cloudbees-jenkins-platform.jpg
Cloudbees并非直接扩展Jenkins,而是在Jenkins的上层做了一个独立的系统,叫做Jenkins Operations Center(简称CJOC),CJOC是一个Jenkins集群的管理工具,是一个统一接入层,用户的身份认证(oauth或者ldap)在CJOC进行处理,然后分配到不同的Jenkins Master;集群的Slave节点资源池由CJOC进行分配;Master节点宕机,任务的重试由CJOC进行分发。可以说CJOC是Jenkins集群的资源、任务调度系统,不同的任务通过CJOC会调度到不同的Jenkins Master上。`
cluster-deployment.png
Jenkins Master在CJOC中是成对存在的,两个Master会通过共享存储的方式同步元数据信息,通过haproxy将两个节点挂载到一个虚拟IP下,当一个Jenkins Master宕机的时候,会再另外一台机器上启动起Jenkins Master实现宕机切换,原来在当前Master上运行的任务会通过CJOC再重新下发,分配到新的节点上。

采用Gearman插件实现伪Jenkins集群

Openstack项目使用Jenkins作为所有模块的持续集成方案,每天共计需要运行超过8000个JOB,而单个Master的方案无法满足自身的需求,因此Openstack的团队开发了一款Jenkins的Gearman插件,用来承载更多的任务,大致的架构图如下:
gearman_plugin_architecture2.png
Gearman插件是运行在Jenkins Master上的,此时Jenkins Master就可以看做一个Gearman的 worker。
gearman-flow1.png
Gearman插件会监听Gearman Server的事件,并将Gearman的Job转换为Jenkins的Job,并使用Jenkins Master的Slave进行Job的执行。也就是说Gearman并不是Jenkins的job的scheduler,而只是借助Jenkins的Slave的环境来执行任务。
51b5a79ad543428fdf33a1840928b266.png
Openstack团队通过Gerrit的自动触发,将任务触发给Gearman Server,Gearman Server将任务推送到消息队列中,在Jenkins Master中的Gearman worker监听到消息,通过Jenkins Job Builder,将项目转换为一个Jenkins Job,然后再下发到Jenkins的Slave中。

3d8e12d3e3ee7d0983d66b7e58b28ef2.png
如上图所示,Openstack的Jenkins集群方案之所以称为伪集群,是因为此时用户不是直接使用Jenkins来实现相关的功能,而是通过自动触发Gearman的方式将定制好的持续集成任务转换为Jenkins Job实现的。这种方式对于大多数开发者而言,搭建和改造的成本过大,而且缺乏页面的支持,对于很多业务繁多复杂的企业而言,是无法接受的。

对于大型的Jenkins集群而言,目前尚没有特别的好方案,特别是在高并发、多租户的场景下,Jenkins的集群SLA还是有很大的提升空间的。

性能

由于Jenkins采用xml文件的方式实现数据的存储,在long run的Jenkins项目中,需要持久化的数据是惊人的,而这也导致了单个Master可以创建的Job和长连接的Slave的数目受到了巨大的限制,下面是社区中开发者对Jenkins的性能测试的讨论。

  • Number of plugins.Plugins cause performance issues for builds (because of hooks) and UI (because they adds stuff to it). Do not add too many plugins and anyway - evaluate them thoroughly.
  • Number of jobs. Jenkins gets slow (at least in UI) with 1000+ jobs. Moving jobs to several masters (manual static sharding) helps. E.g. one master - for builds, another - for tests.
  • Number of slaves. There is “X1K initiative” - goal for Jenkins developers to assure smooth operation of master with 1000 executors on all slaves. It is still a challenge. Somewhere around 250 slaves and lots of builds slave connections start getting broken in the middle of a build.
  • Number of executors per slave. Increasing number of executors over the slave capabilities decreases overall throughput - due to clashes, IO congestion or RAM swapping. Leverage RAM, CPU cores and build type. RAM should be enough for maximum number of builds at maximum memory setting + file cache. CPU should be enough to work below 100% utilization, taking IO into account - IO releases some CPU time. Have less than 1 executor per CPU core for single-thread builds. Consider IOPS limit - to avoid disk IO being a bottleneck. Generally if 15 min Load Average more than the number of cores, the number of executors should be decreased. There is a suggestion - 1 executor per slave for isolation. It is reasonable in cloud but for dedicated hardware the same isolation can be achieved by lightweight containers.

    总结而言,Jenkins Master中需要尽可能少的加载插件,单个Master的Job数量最好不要超过1000,单个Master的Slave数目最好不要超过250个,每个slave上面的excutor需要更具项目来判断,设置合理的阈值。这些指标对于Jenkins而言有非常大的优化空间,这也是为什么本系列带大家一起学习Jenkins的原因。

扩展性

从某种意义来讲,Jenkins的扩展性是非常强的,支持非常多的扩展点,开发者可以通过扩展点开发插件来实现各种想要的功能,甚至Jenkins支持Jython或者Jruby的方式来扩展Jenkins。但是这样的灵活性是基于Jenkins的框架之上的。也就是说如果开发者想要去修改Jenkins core中的代码的时候,就要非常小心,因为有可能依赖的插件也同样扩展了core中的代码的扩展点,导致插件的不可用。而且插件和插件之间也是可以相互依赖的,这就导致了有可能开发者只是修改了一个扩展点中参数的类型,一连串的插件可能都无法使用。因此在扩展Jenkins的时候,尽可能的使用插件的方式会是更好的选择,可是插件越多Jenkins的性能损耗就越大,这就陷入了一个难以走出的循环泥淖,开发者需要抉择是选择性能,还是选择扩展的风险。

历史包袱

Jenkins本身的源码具有非常强大的扩展性,Jenkins拥有非常丰富的扩展点,基本上想要扩展的位置都可以通过扩展点的方式实现,这种强大的扩展性带来的好处是开发者可以快速的根据自身的需求来扩展相应的扩展点。但是权限开放的越大,就越难收回来,Jenkins从Hudson 2004年推出开始,在技术架构上面的演进一致被各种历史包袱掣肘着前进,Jenkins的设计放到今天来看也是先进的,但是在一些实现技术和代码的结构上可以发现非常明显的历史包袱和痕迹。自2011年Hudson改名为Jenkins,项目中时至今日,原来Hudson项目的源码还没有完全演进完毕,不得不说这对于想要深入学习、研究、修改Jenkins的开发者而言是一个巨大的挑战。

写在最后

虽然在本文中写了很多Jenkins的问题,但是这些问题大部分针对于希望扩展甚至改写Jenkins的开发者而言的,对于使用Jenkins的持续集成的开放者而言,Jenkins依然是目前最好的选择。在下一篇文章中,我们将正式开始从代码学习Jenkins。

目录
相关文章
|
jenkins Java 持续交付
Learn Jenkins the hard way (1) - 从源码运行Jenkins开始
## 前言 在上一篇文章中,总结了Jenkins的罪与罚。从本文开始,我们将迈入Jenkins的源码学习部分。学习源码的方式有很多种,对于Jenkins而言,网上关于源码的学习非常有限,比较建议大家先阅读官方关于如何成为contributor的文档,了解大体的结构后再逐步深入。
7943 0
|
存储 Java jenkins
Learn Jenkins the hard way (3) - Jenkins的存储模型
一篇文章来看Jenkins的存储模型并讨论高可用的可行性。
4737 0
|
jenkins Java 持续交付
Learn Jenkins the hard way (2) - Stapler与Jelly
## 前言 在上篇文章中,我们讨论了如何调试Jenkins的页面。今天我们将开始研究研究Jenkins的页面与路由机制。因为Stapler与Jelly的内容比较繁琐和复杂,暂定通过两篇文章来探讨。
4866 0
|
15天前
|
jenkins Devops Java
DevOps实践:Jenkins在持续集成与持续部署中的价值
【10月更文挑战第27天】在快速发展的软件开发领域,DevOps实践日益重要。Jenkins作为一款流行的开源自动化服务器,在持续集成(CI)和持续部署(CD)中扮演关键角色。本文通过案例分析,探讨Jenkins在Java项目中的应用,展示其自动化构建、测试和部署的能力,提高开发效率和软件质量。
39 2
|
3月前
|
jenkins 持续交付 开发者
自动化部署:使用Jenkins和Docker实现持续集成与交付
【8月更文挑战第31天】本文旨在为读者揭示如何通过Jenkins和Docker实现自动化部署,从而加速软件开发流程。我们将从基础概念讲起,逐步深入到实际操作,确保即使是初学者也能跟上步伐。文章将提供详细的步骤说明和代码示例,帮助读者理解并应用这些工具来优化他们的工作流程。
|
3天前
|
运维 jenkins Java
Jenkins在持续集成与持续部署中的价值
Jenkins在持续集成与持续部署中的价值
|
16天前
|
jenkins Devops 测试技术
DevOps实践:Jenkins在持续集成与持续部署中的价值
【10月更文挑战第26天】随着DevOps理念的普及,Jenkins作为一款开源自动化服务器,在持续集成(CI)与持续部署(CD)中发挥重要作用。本文通过某中型互联网企业的实际案例,展示了Jenkins如何通过自动化构建、持续集成和持续部署,显著提升开发效率、代码质量和软件交付速度,帮助企业解决传统手工操作带来的低效和错误问题。
44 4
|
1月前
|
jenkins Shell 持续交付
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(二)
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(二)
67 0
|
1月前
|
jenkins Shell 持续交付
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(一)
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(一)
136 0
|
3月前
|
持续交付 jenkins Devops
WPF与DevOps的完美邂逅:从Jenkins配置到自动化部署,全流程解析持续集成与持续交付的最佳实践
【8月更文挑战第31天】WPF与DevOps的结合开启了软件生命周期管理的新篇章。通过Jenkins等CI/CD工具,实现从代码提交到自动构建、测试及部署的全流程自动化。本文详细介绍了如何配置Jenkins来管理WPF项目的构建任务,确保每次代码提交都能触发自动化流程,提升开发效率和代码质量。这一方法不仅简化了开发流程,还加强了团队协作,是WPF开发者拥抱DevOps文化的理想指南。
82 1