jenkinsFile从听说到放弃

最近由于工作需要,顺便了解了一下Jenkins file,然后还是很难得的,以这么快的速度把这玩意丢进了黑名单。然后后来仔细想了半天,觉得JenkinsFile并不至于完全处于黑名单,应该处于默认不使用,使用须慎重的位置。

那么我们就以下几点来看看,JenkinsFile的优势与不足。

一、版本化配置####

当然是个很好的理由,而且的确,假设项目组内存在一个间谍故意破坏各种设施,那么版本化是个很好的手段去追责。虽然大多数时候只是为了防止手滑改错配置。
JenkinsFile的确解决了这个问题,而且解决的很不错。因为JenkinsFile是跟着代码走的,代码有版本管理的情况下,JenkinsFile的自然也就有了版本化。
<b>这一切看上去的确很美,但是问题是,其实早就审美疲劳了。</b>
没有JenkinsFile的时代里,JobConfigHistory完全可以满足版本化配置的需求。你的配置怎么改的,在哪个时候改的,改了什么,都是清清楚楚。如果说有什么缺陷的话,就是图标的分辨率太低了,看着很丑。
这个插件还有个缺陷就是,xml比groovy丑多了,有多丑呢?丑到我都不想看xml,xml太臃肿了,一坨一坨的无用信息简直辣鸡。但是问题在于,你的改动点很难改到一些“多余”的内容,大多的修改都是简短的,因为其实绝大多数Jenkins的配置框都没有多少东西留给你输入。或者说,很少有什么task(不是job)需要你填20多项输入框的。也就是,整个xml大的不行,但是其实一个task的那一段还是很短的。当然,项目嘛,啥情况都有的,就是有那种50多个参数的task要你改。这种规模,怕不管是xml还是groovy一口气改完的话都难保证质量吧?
所以,就版本化配置来说,JenkinsFile几乎没有什么好处,当然还是承认groovy的好处,但是基本用处不大。<b>这一点JenkinsFile的确有优势,但是很微弱……</b>就像Java和PHP一个道理,PHP的确是最好的语言,但是其实绝大多数场景其实差不多……

二、迁移方便####

<b>这个理由完全不成立。</b>
不是说Jenkinsfile的对迁移没有帮助,而是说JenkinsFile做的不够好。假设我们依赖于JenkinsFile做迁移,那么我们<b>只</b>需要把JenkinsFile交给Jenkins就能解决问题了。所以,如果我在管理50多个项目的build,那么我就要和Jenkins说50多次JenkinsFile的位置。<b>也就是随着项目增多,依赖JenkinsFile迁移Jenkins的代价呈线性增长。</b>
然而,Jenkins已经有了很多backup的插件了。其原理说白了就是把xml打个包存起来,当然也许也有不打包直接把所有xml合并成一个xml的。然后,你当然可以把它扔数据库,也可以扔版本管理,或者你闲的慌的话可以删掉再来一次……
然而,当我们迁移的时候,直接把backup恢复。哪怕有一千个job,一瞬间就好了。而且连证书什么都可以懒得搞,一键式。甚至像我这种心理变态,连build记录都全部恢复,看上去就像是没有迁过一样……
当然了,一般也没有那么多job,但是JenkinsFile在迁移问题上还有个缺陷,就是这玩意并不能恢复plugin……十分尴尬的缺陷……至少你要手动装个JenkinsFile的plugin吧?虽然用backup的确也要装插件,但是backup是装一个插件,然后点一下恢复。JenkinsFile不一样,不仅要JenkinsFile的plugin,用到的各种plugin都要全部重装。
<b>综上所述,JenkinsFile迁移方便的理由根本不成立,在这点上认为JenkinsFile根本就纯属胡扯……</b>

三、plugin(此项存疑,也许有什么骚操作?)####

<b>JenkinsFile完全是坑……因为JenkinsFile要用plugin的前提是这个plugin主动支持JenkinsFile!!!</b>
也就是说,比如我要传个包到nexus上,搞不好插件就不支持JenkinsFile。我们做好的假设,假设各个插件的开发者都对JenkinsFile有好感,但是比如我采用gogs做版本管理,gogs的Jenkins plugin本来就已经很咸鱼了,我完全没有信心说人家有时间去做这个工作。
也就是说JenkinsFile可能能获得大部分常见的plugin支持,但是仍然有一些需要的plugin没有支持……或者说,我们可以完全相信,git的支持是有的,但是对bitbucket的支持就会有些含糊,到了vnc插件就觉得可能五五开了,再到了Android自动配sdk,跑UI测试可能就觉得很可能不支持,想到gogs基本就准备自己写了。
就算能在groovy里随意调用Java代码,所以能调用插件,但是千万要注意了,slave有没有那个类?别人的插件是不是能完全理解?但是回过头想想,调用一个插件还要看插件的源码……
更可怕的,你项目采用了JenkinsFile,然后所有plugin都支持,然后项目走到一半,突然发现一个重要的plugin不支持,难道自己写支持么?这个时候,不仅要会Jenkins了,还要会JenkinsFile,技术要求一下就上来了,成本也就跟着上来了。
然后如果抛弃JenkinsFile,显然不会有这种问题,就算被逼无奈要自己写插件,怕是也比写一个插件然后再写JenkinsFile支持来的快吧,而且要求其实也低很多啊?看看gogs的webhook插件就知道了,几行就搞定了的东西……
<b>这个问题上,就目前的状况来看,缺陷明显。</b>
就未来的发展来看,假设有一天JenkinsFile内就能写明自己要哪些插件,那会是什么场景?由于JenkinsFile插件不同,插件版本不同,是不是每个job都会有自己的插件管理?是不是和现在的Jenkins只有global的插件很不同?想想Jenkins如何发展成这样?或者自带maven?

四、效率####

<b>这一点的前提是要使用stage,但是仍然没有优势……</b>
首先,stage不管怎么玩,都是顺序的。也就是前面的stage所在slave如果堵车,后面真正要跑的stage就算所在的slave完全空闲,仍然要等等忙的那个slave跑完,然后才能跑后面的,效率可想而知。虽然可以通过优化build的流程来避免上面这种情况,但是和一般的Jenkins比起来,JenkinsFile无论如何无法彻底避免这种浪费时间的情况,而Jenkins本身完全可以很容易的彻底避免这种问题。
<b>这里,至少效率上是没有优势的。因为对设计有要求,甚至展现出了较为显然的缺陷。</b>

结合上面这些,除非是为了“pipeline as code”的口号,我觉得完全有理由放弃JenkinsFile,不论是出于学习目的还是商业目的,中短期内根本没有采用和学习的必要,甚至有可以预见劣势。除非觉得口号是值钱的,但是我相信对于大多数人来说,实实在在的成本可比口号值钱多了……

然后后来发现,JenkinsFile的确具有上述缺陷和某些微弱的优势,因此的确出于商业目以及中短期的目的没有任何理由采用这个技术……但其实这些劣势的是因为我们试图把JenkinsFile用于这些Jenkins本身已经做得不错的工作,而Jenkins本身已经足够强大,所以指望JenkinsFile超越Jenkins的确挺扯淡的……难道要我们彻底删掉Jenkins来用JenkinsFile?
<b>那么我们其实可以假设,JenkinsFile肯定有什么特殊的特性光用Jenkins实现起来肯定很麻烦。</b>
JenkinsFile由于是直接写代码控制Jenkins的build,所以首先这种优势肯定不在于Jenkins global的任务,比如控制插件,备份等等build之外的事情。就个人来说,很难想象用JenkinsFile搞这些事情。
那么如果我们把视点转移到build之内。于是立刻发现当build十分复杂的时候,甚至带有逻辑处理比如if的时候,用普通的Jenkins简直令人发指。
比如说,我们要想有一个job来跑测试,然后我们有一个高性能的slave可以迅速完成编译等工作,有一个带显卡装了图形化桌面的slave,一个能访问外网的slave,然后我们要依次完成编译、单元测试、集成测试、UI测试、e2e测试。然后恶心的事情还没完,我们希望在集成测试通过后,自动开始部署流程。更过分的是,由于种种原因,我们会希望只跑集成测试,因为集成测试不稳定,当然UI测试也一样。
所以我们的需求自然是:

  • 显然编译和单元测试要放在高性能的slave上,因为跑得最快。
  • 集成测试由于要访问外网,所以当然是在能访问外网的slave。
  • UI测试当然是去图形化的slave。
  • e2e测试(额,我们这里的e2e采用临时启动一个应用,跑完就关。并不按照常理用部署好的环境)。当然要把应用临时部署到带外网的slave,然后客户端启动到带UI的slave。

于是如果不用JenkinsFile,由于一般job只能指定在哪个slave跑,但是中途想换slave似乎有点麻烦了。所以<b>不用JenkinsFile我们需要每个测试一个job。</b>也就是每个测试配包括git地址,trigger逻辑,是否执行这个build的parameter以及if判断等各种麻烦的事情……当然,也不是做不到就是了,就是各种麻烦……
但是有JenkinsFile就爽多了,配一个job,然后每种测试一个stage,然后游戏就结束了,简单干净的就完成了目标……

所以,就个人的调查来说,JenkinsFile有一个巨大的优势就是,可以强而有力的控制<b>一个</b>job的build逻辑,因此可以允许在一个job里实现各种复杂诡异的操作。因此,JenkinsFile的应用场景应该是,当一个job开始带有一定的逻辑,并且这种逻辑开始变得十分复杂的情况。
然而,问题在于,大多数的项目并不会有这么复杂的pipeline……这就是虽然我意识到这东西的确在某些方面有很高的价值,但是这些方面都需要情况非常复杂的时候才能体现出来……一般来说一个job其实没有之前例子那么苛刻的要求。
比如实际上我们的需求可能是:

  • 编译和单元测试以及集成测试我们可以在一个高性能并且能访问外网的slave执行。
  • 在部署完成后,在一个带UI的slave进行e2e测试,并且顺便把UI测试也做了。

在这种简单的case,不用JenkinsFile就三个job,测试、部署、e2e测试。用JenkinsFile也是三个job,测试、部署、e2e。除非有人会希望测试部署这些东西都混在一个job里管理(这样job的状态无法表示测试的状态)。
而事实上,绝大多数时候,我们在做某件事情的时候基本都能在一个slave里一步到位,比如测试,一般就直接跑完,中途并不需要切换slave,或者并不需要有什么if判断……因此虽然JenkinsFile的确在复杂的情况有很强的优势,但是……到底是多复杂的一个项目才会需要用到这么灵活强大的工具?

所以个人最终的结论是:<b>JenkinsFile能够轻松实现job里复杂的build逻辑,这是传统Jenkins不能轻松实现的。但是在决定采用JenkinsFile之前,我们应该仔细想想是不是这个build真的不得不复杂到这个地步,如果的确是需求复杂,才采用JenkinsFile;否则应当简化逻辑,而非直接采用JenkinsFile。</b>

    原文作者:青城废人
    原文地址: https://www.jianshu.com/p/e48ac2455763
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞