Jenkins 很酷,但是不完美,有历史局限性造成的问题。本文仅从“如何更好给研发团队赋能的角度”,剖析Jenkins, 探讨理想的持续交付平台, 不带货无广告~

不完美的Jenkins

  • Jenkins的前身是Hudson, Hudson是SUN公司时期就有的CI工具,后来因为ORACLE收购SUN之后的商标之争,创始人KK搞了新的分支叫Jenkins 。今天的Hudson还在由ORACLE持续维护,但风头已经远不如社区以及CloudBees驱动的Jenkins.
  • Hudson 被 Jenkins 取代后,不再维护,并于 2017 年 2 月宣布已过时。Hudson 网站 hudson-ci.org 于 2020 年 1 月 31 日关闭
  • 关于Hudson 和Jenkins的恩怨,有兴趣可查阅 https://www.oschina.net/news/63453/hudson-and-jenkins-grievances

提到DevOps/持续集成这些话题,由于开源免费,历史悠久,插件API丰富,群众基础好(可借鉴模仿案例实践资料多)等原因,Jenkins永远是那个最亮的“仔”,也是众多相关领域厂商或者企业**绕不开的“工具”。

不过,依然有很多“不完美”,仅仅是个没有“DevOps灵魂”的CI工具(理由如下),但不得不承认它又是“免费”又有“用户量”的CI工具。下面我通过以下几个方面详细做些剖析**

历史遗留问题

首先 Jenkins 是一个巨石系统,它是一个单体的结构。为什么到现在为止大家好像没有看过特别成熟的 Jenkins 集群级的方案,或者很少看到高可用的方案,大部分情况下大家看到的是给不同的团队或者是不同的部门分配多个 Master ,而不是共用一个大的 Master ,其实这个主要取决于 Jenkins 内部的实现原理和机制。

传统意义上来讲一个服务会有两层,一层是你的服务层,一层是你的数据层。但是 Jenkins 因为历史的一些原因,导致所有的存储都是以文件的方式存储在磁盘上,存储在磁盘上就会一个比较大的性能问题。在 Jenkins home 里有一个 jobs ,里面存储的就是大家构建的每一个任务,还会存构建任务的配置等等。一系列的东西都以文件的方式,以特定的目录结构存储在磁盘上。

当 Jenkins 第一个步骤,比如你重启 Jenkins 的时候,它会做什么?先把磁盘上 jobs 目录都扫一遍,加载到自己的内存里里,再去做后续的东西。比如刚才说的高可用的方案,假如用共享存储,现在在一台 Jenkins Master 上写了一个job,其实另一台 Jenkins 是没有感知的,因为没有加载这个job。

学习成本

Jenkins 的插件那么多,到底该选哪一个?而且出现很多问题是1+1小于2,有时候必须安装第二个插件来满足,两个插件组合的时候又可能达不到很好的合力,这导致很多业务场景不得不去装很多额外的插件来满足自己的需求。开发者对 Jenkins 熟识的程度大部分在于自己插件的使用经验。

可维护性

当jenkins支持的场景越复杂,你会发现你要管理很多插件,这是你构建Jenkins和复制Jenkins面对最大的问题;同时,插件由于是个人贡献维护,很多插件会有年久失修情况。


安全性

Jenkins的插件包括Jenkins本身,它是有一些漏洞的,当你去用一些插件的时候,你要不停的更新它。

性能

不知道有没有人在一个Jenkins中配200个人,你肯定碰到到第80个人的时候,整个用户配置界面会卡。

要想 Jenkins 用得好,插件不能少。但是 Jenkins 的插件会带来一些性能问题,每一个插件都是在项目启动的时候就会加载到内存里,当插件越大的时候,对性能的损耗越大。要选择自己合适的插件去构建自己的 Jenkins 。

  • 第一个是插件,要选择一些合适数量的插件,满足需求的插件,尽量少的插件会比较好;
  • 第二个是job,在 Jenkins 官方的文档上讲,当你的job超过1000个以上的时候, Jenkins 就会有一些性能问题。手动创建 user 80个以上就会有卡顿,job那个地方是第一次都加载进来的,而 user 是每次都会去扫盘,然后去加载XML;
  • 第三个是slaves;
  • 第四个是每一个节点上的 executor

其他问题

  • 对于不熟悉DevOps的工程师,学习成本其实不低,或者说离最佳实践差的太远
  • 没有“DevOps最佳实践”规范约束Jenkinsfile
  • 项目隔离/权限分配方案的缺陷
  • 集成配置比较“散乱”
  • Jenkins的能力来源于插件,需要额外配置,部分插件过于老旧/兼容性
  • UI丑陋,无法满足复杂UI交互

现实中持续交付对平台的要求

抛开Jenkins上面的缺点不谈,回到现实场景中,我们需要从更大的视角(即持续交付)来理解一个“持续交付平台”需要扮演的角色。

从上图中可以看出,从开发人员写下代码到服务最终用户是一个漫长过程,整体可以分成三个阶段:

  1. 从代码(Code)到制品库(Artifact):这个阶段主要对开发人员的代码做持续构建并把构建产生的制品集中管理,是为部署系统准备输入内容的阶段。
  2. 从制品到可运行服务:这个阶段主要完成制品部署到指定环境,是部署系统的最基本工作内容。
  3. 从开发环境到最终生产环境:这个阶段主要完成一次变更在不同环境的迁移,是部署系统上线最终服务的核心能力。

如果从持续交付角度看,其最核心诉求就是要让上图三个阶段能够无缝连接并自动化运行起来,从而达到持续交付的两个核心目标:提高交付频率(部署次数)和降低部署延时(从代码提交到上线的时间差)。

参照如上持续交付的流程,可以发现持续交付对于一个部署系统的要求绝对不仅仅是一个自动化的部署过程,这也是在有了Jenkins和其相关部署插件后仍然需要搭建独立部署系统的原因所在。具体来说,我们可以从下面几点分析:

解耦构建和部署过程

尽管持续交付希望自动化完成从代码到部署上线的整个流程。但是整个持续交付过程有多个不同角色的人参与其中(开发、测试、运维甚至还经理及市场人员)。其中有些角色(如开发/测试)需要关心构建过程,而更多的角色(如运维等)绝大时候都是从制品开始部署工作。这也就要求构建和部署过程相互解耦,能够独立操作。
构建和部署这两个过程通过制品(Artifact,又称为部署包)连接(制品是构建过程的产出,同时是部署过程的输入)。如果它们相互解耦,自然就需要有统一的地方管理存储和管理这些制品,即统一制品库。
有了统一制品库后,构建过程自动提交产生的制品到此,而部署过程则主动到制品库拉取需要的制品进行部署,从而实现构建和部署的完整解耦。

管理复杂的部署环境

服务上线需要涉及到很多不同目的环境(开发、测试、预发、生产、演示等)。在云化基础设施中,环境内部的资源会频繁变化(例如,Auto-Scaling时刻都有可能添加或者减少你的云主机)。

这时候需要对部署流程隔离部署环境差异以及环境内频繁变化的基础设施。当需要执行一个部署时,操作人员只需要指定部署到哪个环境(即环境名称或者ID号),而不需要关心环境内部的任何信息,只需把部署请求分发到指定环境内的每台主机并自动执行。

如果基于Jenkins来直接部署,则必然把环境管理的很多复杂度引入到部署流程内部。

支持多种部署策略

为保障服务的高可用,落实部署和发布的解耦以及其他业务需要,用户常需要支持如灰度发布、A/B测试发布等部署需求。一个独立的部署系统在此可以提供多种部署策略,并结合环境管理等其他功能满足业务上对部署和发布的各种需求。同样,Jenkins及其部署插件并没有提供这样的能力

落实部署流程规范

在一个公司内部经常有不同的项目,使用不同的编程语言,而部署流程也五花八门。从控制风险,减少重复操作,降低部署自动化难度等多重考量,公司都倾向制定一套标准的部署流程。

这时候,独立的部署系统就可以帮助用把这些规范落实下去并在日常的部署过程中时刻校验(在软件工程领域,几乎所有的规范落实都得靠工具来助一臂之力,否则基本都会变成纸面上的规范而已)。

如果基于Jenkins来直接部署,如何落实这些部署规范仍然是一个很困难的事情,因为Jenkins及其部署插件并未对此提供任何实质性的支持

获取研发过程数据

部署是一个团队从代码到服务的关键路径,这上面的所有操作数据都值得记录并用于各种运营支持(包括安全审计、部署记录查询、部署频率和失败率分析等等)。基于Jenkins直接部署当然也可以获取这些数据,但是把它做在独立的系统内会更灵活和方便。

让部署操作服务化

如之前提到,部署不仅仅开发和测试人员需要,要努力让部署服务化,从而让团队内任何一个人都可以随时触发一次部署。Jenkins的操作界面对于开发或者测试人员可能还比较方便,但是对于其他人员来说则过于复杂。

当然,除了上面列出的这些原因外,你还要解决部署版本的管理等,这里就不一一列举。

持续交付平台的特质

如前所述,一个理想的持续交付系统需要包括的内容是非常丰富的,特别是要面临各种复杂场景,不同技术栈的团队,异构的各种内部系统(绝对不仅仅是Jenkins插件要做的那些事情)。

如下图所示,持续交付系统需要连接项目中涉及的人、代码,制品库,以及环境等,Jenkins仅仅起到了简单的连接作用。

  • 对于简单的场景,或者较小团队来说,通过Jenkins各种插件来完成持续交付活动,是足够的。
  • 对于更大的团队,或更高要求的组织,它最终希望的目标是打通从代码(甚至需求)到最终服务的整个流程(如下图)。



所以,能够给研发过程赋能的“持续交付平台”需要具备如下特点

  • 能够管控好“代码”,“制品”,和“环境”,整个过程都是围绕这些做文章的
  • 隐藏底层的细节,对不同角色要友好,提供自助式的服务
  • 控制好和外部系统的集成,少侵入,多融合
  • 控制好过程的“输入”和“输出”,聚焦体系化流程框架
  • 正向引导用户做正确的事,赋能组织,而不是“让用户困扰”

期待更好的持续交付平台

DevOps持续交付涉及的工具如同各类不同形状的积木,你的目标是建造一个房子,可能你现在手中只有很少的积木,或者你有很多重复的积木,但是唯独缺少三角形完成屋顶部分。

  • 想清楚房子要多大?多豪华?
  • 自己手里有什么,缺什么?
  • 工具搭配是否合适?是否漂亮?
  • 谁是主角,谁是配角?
  • 谁是从别人那里借来的,未来可能要还的
  • 一个房子也能玩,多个房子玩的更好,先搭建哪个?

想清楚不迷路,不同的人搭建方法不同,只要最后搭建合理漂亮实用,恰到好处就可以,期待更好赋能研发过程的持续交付平台~


放弃"Jenkins"的种种理由,期待更好赋能研发的持续交付平台的更多相关文章

  1. SonarQube+Jenkins,搭建持续交付平台

    前言 Kurt Bittner曾说过,如果敏捷仅仅只是开始,那持续交付就是头条! "If Agile Was the Opening Act, Continuous Delivery is ...

  2. [持续交付实践] Jenkins Pipeline 高可用设计方法

    前言 这篇写好一段时间了,一直也没发布上来,今天稍微整理下了交下作业,部分内容偷懒引用了一些别人的内容.使用Jenkins做持续集成/持续交付,当业务达到一定规模的时候,Jenkins本身就很容易成为 ...

  3. Jenkins自动化部署-----持续交付【转】

    感谢之前带领过我的leader,让我能够知道什么是好的开发方法. 在很早之前就接触过敏捷开发.什么是敏捷开发,简单来说就是让软件可靠地,快速地发布出来的一种开发方法和技巧. 而敏捷开发中有许多的实践, ...

  4. 利用jenkins和docker实现持续交付

    利用jenkins和docker实现持续交付 一.什么是持续交付 让软件产品的产出过程在一个短周期内完成,以保证软件可以稳定.持续的保持在随时可以发布的状况.它的目标在于让软件的构建.测试与发布变得更 ...

  5. Jenkins自动化部署——持续交付

    感谢之前带领过我的leader,让我能够知道什么是好的开发方法. 在很早之前就接触过敏捷开发.什么是敏捷开发,简单来说就是让软件可靠地,快速地发布出来的一种开发方法和技巧. 而敏捷开发中有许多的实践, ...

  6. Jenkins学习总结(4)——持续集成,持续交付,持续部署之间的区别

    经常会听到持续集成,持续交付,持续部署,三者究竟是什么,有何联系和区别呢? 假如把开发工作流程分为以下几个阶段: 编码 -> 构建 -> 集成 -> 测试 -> 交付 -> ...

  7. 再见Jenkins,从Gitlab代码提交到k8s服务持续交付只需七毛三(走过路过不要错过)

    Gitlab runner 快速搭建CICD pipeline 背景 日常开发中,相信大家已经做了很多的自动化运维环境,用的最多的想必就是利用Jenkins实现代码提交到自动化测试再到自动化打包,部署 ...

  8. 基于Jenkins的持续交付全流程设计与实践

    1 从理论开始 什么是DevOps? 近年来,随着DevOps理念的逐渐深入人心,企业逐渐意识到从看似重复的手工劳动中实现自动化流程处理,对于提高企业劳动生产力已经非常重要,尤其是面向互联网的开发者, ...

  9. 基于Kubernetes/K8S构建Jenkins持续集成平台(上)-2

    基于Kubernetes/K8S构建Jenkins持续集成平台(上)-2 Kubernetes实现Master-Slave分布式构建方案 传统Jenkins的Master-Slave方案的缺陷 Mas ...

  10. 使用jenkins构建持续集成平台

    jenkins +   Maven + svn/git + tomcat 的持续集成平台 项目管理流程: 需求分析----原型设计----开发代码----提交测试-----内部测试-----确认上线( ...

随机推荐

  1. node: #!/usr/bin/env node

    声明 windows中不支持Shebang,它是通过文件的扩展名来确定使用什么解释器来执行脚本 参考链接: https://juejin.cn/post/6844903826344902670

  2. mysql注释的方法

    单行注释:"#", "--", 多行注释:/**/ 参考链接:https://www.cnblogs.com/JiangLe/articles/6897403. ...

  3. DHorse v1.3.0 发布,基于k8s的发布平台

    综述 DHorse是一个简单易用.以应用为中心的云原生DevOps系统,具有持续集成.持续部署.微服务治理等功能,无需安装依赖Docker.Maven.Node等环境即可发布Java.Vue.Reac ...

  4. FreeRTOS 基于 ARMv8-M 对 MPU 的应用

    一.前言 ARMv8-M 支持 MPU,FreeRTOS 也添加了对这些 MPU 的应用代码.这里用来记录 FreeRTOS 对 MPU 应用方式的探究结果. 二.ArmV8-M MPU 介绍 ARM ...

  5. 解决Avalonia 11.X版本的中文字体问题

    网上搜索的方法使用接口"IFontManagerImpl"这个方法目前只能用于Avalonia 10.X版本,因为11版本后官方把这个接口的成员都设置成了非plubic,所以之前的 ...

  6. 从头到尾说一次 Spring 事务管理(器)

    事务管理,一个被说烂的也被看烂的话题,还是八股文中的基础股之一.​ 本文会从设计角度,一步步的剖析 Spring 事务管理的设计思路(都会设计事务管理器了,还能玩不转?) 为什么需要事务管理? 先看看 ...

  7. fastapi启动后访问docs不显示页面的问题

    笔者之前正常使用fastapi的docs接口进行各种接口调试,使用很正常,之前安装也都是正常安装流程,没有做任何修改,可以突然有一天不知道为啥,docs接口打开是空白的,接口也没有报错,就是空白,摸索 ...

  8. .NET开源最全的第三方登录整合库 - CollectiveOAuth

    前言 我相信很多同学都对接过各种各样的第三方平台的登录授权获取用户信息(如:微信登录.支付宝登录.GitHub登录等等).今天给大家推荐一个.NET开源最全的第三方登录整合库:CollectiveOA ...

  9. springboot下载文件 范围下载

    springboot下载文件 范围下载 关键词:springboot,download,Range,Content-Range,Content-Length,http code 206 Partial ...

  10. CodeIgniter 视图篇

    什么是视图 简单来说,一个视图其实就是一个 Web 页面,或者页面的一部分,像页头.页脚.侧边栏等. 实际上,视图可以很灵活的嵌在另一个视图里,然后这个视图再嵌在另一个视图里,等等, 如果你想使用这种 ...