阅读更多
高效可靠的CI/CD流水线是一个IT组织实现软件服务快速交付的基础,现如今大量企业采用jenkins集群来搭建其交付流水线。然而,如何管理大量Jenkins Slave的差异化?如何简单快速实现Jenkins能力的横向扩展?如何实现流水线的高可用?如何有效利用闲置的Jenkins Slave资源?上述这些问题一直困拢着集群管理员,近两年随着虚拟化技术突飞猛进的发展,Docker, Kubernetes 等现代化工具彻底颠覆了交付团队的交付流程,同时也为CI/CD流程水线的搭建与管理提供了全新思路。

Setup

目前流行的CI工具很多,鉴于本文讨论CI/CD流水线在企业中的应用,考虑到企业不会有意愿将源代码的访问权开放给第三方,像Travis CI等这些基于SaaS的CI工具自然被pass,由于Jenkins在CI领域的主导性地位,所以本文的CI工具只涉及Jenkins。另外,本文默认您对Jenkins, Docker, Kubernetes 等工具有一些基础的了解。

持续交付流水线简介

简单介绍一下持续交付流水线,如下图所示,简单来说流水线工作流程是这样的,当代码库有代码变更的时候持续集成服务器(Jenkins)会监听到代码变更并自动触发第一个阶段 — 持续集成阶段,这个阶段做的事情是自动构建,单元测试,静态代码分析以及生成报告。如果所有步骤都如预期成功通过的话会自动进入下一个阶段 — 自动化测试阶段,在跑自动化测试套件之前,首先要把成功通过第一阶段的产出物(artifact), 如果选择java做为开发语言的话就是生成的war包,ruby的话就是gem文件,部署到测试服务器上,部署完成之后触发自动化测试套件,包括验收测试,容量测试,性能测试等会自动执行,如果所有测试用例都顺利通过(有些公司还需要做一些手工测试如探索性测试等)的话,那么这个版本就会被标记成一个可发布的侯选版本。一旦业务需要,就会通过一键部署的方式将相应的侯选版本发布到生产环境上去。如果你想更多的了解持续交付相关的知识请阅读David Farley and Jez Humble的名著《Continues Delivery》。

实践与痛点

上述这个过程实现起来需要这样做,首先需要把上图中各个阶段的工作脚本化,说具体一点就是需要写一个构建脚本来完成编译,单元测试,静态代码分析,生成报告等步骤,从而完成持续集成阶段的工作,然后是自动化测试脚本,这个脚本可以触发自动化测试套件并生成相关报告,最后需要写一个部署脚本,用于将持续集成阶段的产出物部署到测试环境上(当然最后的发布阶段也会重用这个脚本),这里需要注意的是要确保部署都是可重复的,重复部署同一个产出物N次的效果与只部署一次的效果相同,也就是大家常说的幂等。接下来就轮到Jenkins出场了,首先我们需要配置一下Jenkins来监听代码库的变更,这就意味着只要有代码迁入就会触发相对应的流水线,然后我们用Jenkins job或pipeline将这几个阶段的脚本串联起来(下图是以job为例),这样一个简单的CI/CD流水线就搭建完成了。

如上图所示,每一个Job负责运行某一阶段的脚本,可以简单类比为Job1运行持续集成阶段的脚本将源代码从代码库中迁出,编译,单元测试,静态代码分析以及生成报告,Job2首先将持续集成阶段的产出物部署到测试环境并运行自动化测试套件,生成报告并标记产出物,Job3用于按需发布。每个Job所运行的脚本依赖的语言或运行环境会有所不同,可以通过label方式选择到相应的Slave上运行。

但在企业级大规模的应用CI/CD流水线时,由于企业中多团队多产品的存在,不同的团队会根据产品自身的特点来选择不同的技术实现方式,这就意味着产品实现语言会有很多种,比如java, C#, ruby, python, nodejs ...那么相对应的CI/CD流水线就需要提供所有语言的编译环境并安装相关的依赖包,当然为了减少依赖,避免冲突以及更好的管理这些编译环境聪明的管理员会选择让每一个slave只能运行特定编程语言的Job, 如下图所示:

上图这个Jenkins集群Maser只用来调度和收集log,所有的Job都会由Master根据不同的label导流到对应的Slave上运行。这种集群的实现方式是我们在VM时代不得已的选择,虽然能解决大部分问题,但也带来了很多困扰。
  • 单点依赖 Jenkins Master成为单点,一旦Jenkins Master down机,那将是灾难性的,整个CI/CD流水线都将处于不可用的状态。
  • 不易维护 大量差异化的Jenkins Slave管理起来难度很大,由于差异化的存在,维护升级几乎都需要手动完成,人力成本投入很高。
  • 不易扩展 举个例子,我们发现流水线对Java7这个Slave发出的请求量比较大,经常出现排队现像。为了缓解这种情况,管理员需要增加一个可以编译Java7应用的Slave,那么管理员需要怎么做呢?首先需要准备一台VM,然后安装java7以及所有依赖的软件包,最后配置Slave相关信息label等并将新安装好的Slave注册到Master,基本上都需要人为干预,扩展起来非常不方便。
  • 资源浪费 每一台Jenkins Slave Server都是一台实实在在运行的VM, 当Slave Sever空闲时也不能将它所占用的资源释放,因为随时可能需要这个Slave完成相关的Job。
解决痛点

下面我们来看一下虚拟化技术带来了的福音,下图是一个基于Kubernetes, Docker搭建起来的Jenkins集群,为了避免混淆我略去了Kubernetes集群中的Master node。我们看到Jenkins Mater以Docker container的形式运行在Kubernetes一个Node上并将所有Jenkins相关数据存储到一个volume中,Jenkins Slave也以Docker container的形式运行在各个Node中,之所以用虚线来表现Slave是因为Slave不是一直存在的,它会被动态的按需创建并自动删除。简单介绍一下这种动态创建注册Slave的方式,它的工作流程是,当Jenkins Master收到一个build的请求时,会用按照label的要求动态的创建一个运行在Docker container中的Jenkins Slave并注册到Master上, 然后运行相应的Job,当Job运行完成后这个Slave会被注销,所在的Docker container也会被自动删除。

这种基于Docker, Kubernetes搭建的CI/CD流水线给Jenkins集群带来了诸多益处:
  • 高可用 Jenkins Master被部署在Kubernetes集群上,一旦container运行异常意外退出,那么Kubernetes会自动用相同的Docker image帮我们从新起动一个新的Jenkins,并将volume attach给新创建的Docker container,从而保证不会丢失任何数据,实现了Jenkins集群的高可用性。
  • 自动伸缩 由于每一次运行Job时,Jenkins Master都会动态创建一个Jenkins slave,Job完成之后Slave会被注销所在的Docker container也会被自动删除,所占用的资源就会被自动释放。也就是说当同时请求的Job数量越多,生成的Slave container就会越多,占用的资源也就越多,反之亦然,而且这种动态伸缩是完全不需要人为干预的。
  • 完全隔离 由于每一次运行Job都是在一个全新的Jenkins slave中运行,避免了同时运行的Job与Job之间发生冲突的可能性。
  • 容易维护 对比之前每一个Jenkins Slave是一台固定VM的做法,以这种方式搭建的集群维护的不再是固定的VM而是创建动态Slave所需要的Docker image,我们可以很容易通过Docker File来build适用于我们自已的Docker image并将它们存储在私有的Docker registry中,非常易于维护。
  • 容易扩展 当我们发现Jenkins的Queue中存在大量等待执行的Job是因为kubernetes集群的资源不足时,能够很容易的初始化一个kubernetes node并将它添加到集群中来,实现横向扩展非常的方便。
简单实现

下面我们来完成一个简单的实现:

1、首先你需要安装一个Kubernetes cluster,请参考https://kubernetes.io/docs/setup/ Kubernetes安装完成之后,首先需要用下面两条命令和文件部署一个Jenkins到Kubernetes集群:
kubectl create -f jenkins-deployment.yaml
kybectl create -f jenkins-service.yaml


tip: 标红的部分很重要,开放8080端口是用来访问Jenkins web portal用的;而动态创建的Jenkins slave会默认通过50000(可修改)端口与master建立连接。
检查jenkins安装运行情况:

2、查看Jenkins log,用管理员密码登录Jenkins并安装Kubernetes plugin。
3、 配置Kubernetes cloud
Manage Jenkins/Configure System/ Add a new cloud/ Kubernetes:

Add pod template/Kubernetes Pod Template:

点击Save之后大功告成。

牛刀小试

下面我们来测试一下这个动态注册Slave的Jenkins集群是否工作正常,首先登录Jenkins创建一个简单的free style job,指定这个Job只能在Label为“jnlp”的agent上运行。点击build now,你会发现奇迹发生了,原来没有注册任何Slave的Jenkins动态的创建一个Slave并注册到Master上,然后运行相应的Job,当Job运行结束后这个Slave被自动清除了。

PS:这只是一个简单的实现,在企业的实践中,我们需要不同的build环境,需要我们基于jenkinsci/jnlp-slave这个Image构建我们自己的Jenkins slave Image并保存到私有的Registry中,相对应的Kubernetes需要从私有Registry拉取Image。

参考文献:
  • 大小: 30.8 KB
  • 大小: 126.6 KB
  • 大小: 64.4 KB
  • 大小: 101.5 KB
  • 大小: 330.7 KB
  • 大小: 29 KB
  • 大小: 72.8 KB
  • 大小: 117 KB
  • 大小: 33.4 KB
来自: 邸富杰
0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • .NET 2.0与3.5

    自用的CF包,包含了2.0与3.5,WinCE端需要的基本都有,有需要的就下载吧

  • *** Framework 2.0:简体中文版深入解析

    本文还有配套的精品资源,点击获取 简介:*** Framework 2.0是微软推出的强大开发平台,它简化了应用程序开发流程,引入了创新功能和性能优化。该平台的核心架构包括CLR和FCL,促进了不同编程语言之间的互操作性,并且提供了改进的编译器和调试工具。在Web和桌面应用开发方面,引入了母版页、皮肤和AJAX支持等新特性,以及增强了事件模型和控件库。安全性方面,.NET ...

  • Win10离线安装.net2.0/.net3.0/.net3.5

    使用dism命令安装cab文件的方式,注意命令中文件路径要和实际放置cab文件的路径一致。1. 下载.net3.5的cab文件,改名为"netfx3.cab",放在C:\Windows目录下。如上图所示,安装成功以后打开windows功能,可以看到.net3.5已经自动被勾选上了。

  • .NET 2.0 环境安装包

    .NET 2.0 环境安装包 【下载地址】.NET2.0环境安装包 本仓库提供了一个.NET 2.0 环境安装包,安装该程序后,您的电脑将支持.NET 2.0 环境。.NET 2.0 是微软开发的一个重要的软件开发平台,广泛应用于各种应用程序的开发和运行 ...

  • Microsoft .NET Framework 2.0(亲测成功)

    Microsoft .NET Framework 2.0 Service Pack 1 针对 Microsoft .NET Framework 2.0 发布后客户报告的问题提供了累积的汇总更新。此外,该更新还可帮助改进安全性,且提供了用于 .NET Framework 3.0 Service Pack 1 和 .NET Framework 3.5 的系统必备功能支持。

  • Win10 安装 .NET 2.0 相对简单了

    Win10 安装 .NET 2.0 相对简单了 以前版本,在 \Sources\sxs 目录下是一堆文件,现在,精简成了一个压缩包文件: "\\Server\Distribution\Operating Systems\Windows 10 Enterprise x64\sources\sxs\microsoft-windows-netfx3-ondemand-package.cab"

  • 探索经典:轻松搭建.NET 2.0环境

    探索经典:轻松搭建.NET 2.0环境 【下载地址】.NET2.0环境安装包 本仓库提供了一个.NET 2.0 环境安装包,安装该程序后,您的电脑将支持.NET 2.0 环境。.NET 2.0 是微软开发的一个重要的软件开发平台,广泛应用于各种应用程序的开发和运行 ...

  • Windows 10\11 离线安装.NET Framework 3.5(包括.NET 2.0和3.0)

    文章目录前言一、检查Windows 版本有镜像文件以后离线安装打开镜像总结 前言 在联网的情况下Windows 10安装.NET Framework 3.5只需要启动Windows 功能即可,如图: 勾选所需要的功能,点击确定,选择下载安装即可完成.NET Framework 3.5的安装。 由于Windows 10系统已经不支持通过.Net 3.5安装包安装. 故需要手动来完成安装 在此之前呢,也是在网上找了很多方法,尝试了很多,根据网上下载的资源都不成功! 一、检查Windows 版本 Win+R键

  • .NET Framework 3.5(包括.NET 2.0和3.0)离线安装

    参考 Windows无法安装以下功能:.NET Framework 3.5(包括 .NET 2.0 和 3.0)解决方法 WIN10无法安装以下功能 .net framework 3.5解决办法 .cab文件 DISM 概述 解决windows10下无法安装.net framework 3.5,错误代码0x800F081F ...

  • .NET Framework各个版本(1.0 - 2.0)

    .NET1.0与1.1新特性 公共语言运行库CLR 1.0 CLR(Common Language Runtime)公共语言运行时,是.NET运行的环境 为什么叫公共语言呢? 因为它能够运行多种语言,比如C#,VB,C++,F#等 在CLR上运行的是中间语言(MSIL),上述的语言能够被编译器编译成中间语言。 BCL类库 BCL(Base Class Library) 基础类库,为.NET...

  • net2.0插件

    net2.0插件 知道用的就不需要我多说什么了吧...自己搞定

  • .net 2.0 的 system.dll

    win7 上安装VMware exsi client 需要用的.NET 2.0 的SYSTEM.dll。

  • flownet2.0

    视频超分的入门经典作品,最新的结果,世界前沿的技术。

  • NET Framework V2.0

    NET Framework V2.0运行环境,真的拥有。

  • .NET Framework 2.0

    Microsoft .NET Framework 版可再发行组件包将安装运行针对 .NET Framework 2.0 版开发的应用程序时所需的 .NET Framework 运行库及相关文件。 .NET Framework版改进了缓存,从而提高了应用程序的可扩展性和性能;使用 ClickOnce 改进了应用程序部署和更新;通过 ASP.NET 2.0 控件和服务对各种浏览器和设备提供更强大的支持。有关 .NET Framework 2.0 的详细信息,请单击此处。 重要事项:不能在同一台计算机上安装两种不同语言版本的 .NET Framework。试图安装第二种语言版本的 .NET Framework 时,将会导致出现以下错误:“安装程序无法安装 Microsoft .NET Framework,因为已经安装了该产品的其他版本。”如果您要使用非英语的平台或要以另一种语言查看 .NET Framework 资源,则必须下载相应语言版本的 .NET Framework 语言包。

  • ASP.Net 2.0 基础(经典).rar

    《ASP.Net 2.0 基础》首先介绍了ASP.NET 2.0新特性以及VS.NET 2005的开发环境;接下来介绍了.NET中Web页面设计的基础知识和ASP.NET2.0服务器端控件的使用方法;作为ASP.NET数据库开发的准备内容,本书也介绍了些SQL语言的基础知识。此外,还介绍了ASP.NET中的常用对象、数据访问技术、数据源控件、数据源绑定控件等ADO.NET技术;最后综合了前几章的知识,提供了一个登录系统的实例供读者学习和借鉴。 《ASP.Net 2.0 基础》适合于 ASP.NET 开发的初学者及广大网络设计和开发人员阅读,对高级开发人员也有一定的参考价值。

  • ASP.NET 2.0入门经典(第4版)

    《ASP.NET 2.0 入门经典》将逐步引导您使用 ASP.NET 2.0 创建动态的、数据驱动的、复杂的Web站点。在本章结束时,我们将解释一些基本的想法并介绍一个完整的示例站点。然后将学习怎样使用 Visual Web Developer Express(VWD)构建 ASP.NET 2.0 站点。 具体地说,本书包含以下5个主题: 1.简单介绍 ASP.NET 2.0 2.回顾 ASP.NET 2.0解决的 Internet 编程问题 3.解释 ASP.NET 2.0是怎样适应其他技术的 4.浏览一个由 ASP.NET 2.0构建的站点的动态功能 5.理解创建 ASP.N

  • .net 2.0 博客

    本系统管理员用户名为:tsoft,密码为:111。

  • Net framework3.5(包含.Net2.0/.Net3.0)(离线安装)

    windows server 2012 r2,2010 r2 安装 Net framework3.5(包含.Net2.0/.Net3.0)

Global site tag (gtag.js) - Google Analytics