Jenkins 2 创建流水线

Jenkinsfile:

在Jenkins 2中,流水线配置可以从Jenkins中分离出来。在以前版本的Jenkins中,任务配置都是以配置文件的形式保存在Jenkins的主目录中的。这就意味着所有的配置变更都依赖于Jenkins可以识别和管理这些文件(除非你想直接修改XML文件,但这是非常有挑战性的事情)。在Jenkins 2中,你可以在Web可视化界面的文本区中以DSL脚本来编写流水线配置。当然,你同样可以将这些文本形式的DSL代码和其他保存源码的文本文件一起保存在外部的版本控制系统中。这使得你可以像管理其他源码一样通过文件的形式来管理Jenkins任务,支持历史追溯、差异对比等功能。

Jenkins 2推荐使用名为Jenkinsfile的文件保存任务配置和流水线信息。不同的项目和分支都会有自己的Jenkinsfile,其内容各不相同。你可以将全部代码写在一个Jenkinsfile中,也可以通过共享库的方式调用外部代码。另外,DSL语句也允许在脚本中加载外部代码。

enkinsfile可以起到标记文件(marker file)的作用,这意味着只要Jenkins发现你的工程源码中包含了Jenkinsfile文件,那么这个项目或分支就可以被Jenkins自动解析和运行。Jenkins同样可以识别出需要用到的源码版本控制管理(SCM)项目和分支,并加载和执行Jenkinsfile中的代码。如果你熟悉Gradle构建工具,这个理念与应用中定义的build.gradle文件类似。
在这里插入图片描述
在这里插入图片描述

新的任务类型和插件:

在这里插入图片描述
当选择在Jenkins 2中创建一个新的工作项时,屏幕中会提示选择新建任务的类型。你会看到一些熟悉的类型,比如,自由风格类型项目,同时还有一些你以前没见过的类型
在这里插入图片描述

流水线:

顾名思义,流水线类型的项目旨在创建流水线。这是通过Jenkins DSL编写代码来实现的。流水线项目是我们在本书中主要讨论的项目类型。正如已经指出的,流水线既可以用“脚本式”语法风格编写,也可以用“声明式”语法风格编写。这种项目类型的流水线可以很容易地转换成Jenkinsfile。

文件夹:

这是一种可以把多个项目归类到一起的方式,而不是项目本身的类型。请注意,这并不像Jenkins仪表板上传统的“视图”选项卡那样,让你按照项目列表筛选。更确切地说,它就像操作系统中的目录文件夹。文件夹名称是项目路径的一部分。

组织:

有些源码版本控制平台提供了将多个代码库聚合成“组织”的机制。Jenkins集成允许将Jenkins流水线脚本存储为组织内代码库中的Jenkinsfile文件,并基于这些库执行。目前已经支持GitHub和Bitbucket平台的组织功能,未来将会逐步支持其他的平台。为简单起见,在本书中主要以GitHub的组织项目作为例子。假设有足够的访问权限,Jenkins可以在代码托管侧自动建立一个组织的webhook(来自网站的通知),从而任何代码库中的变更都会通知Jenkins实例。当Jenkins收到通知时,它会检测代码库中作为一种标记而使用的Jenkinsfile文件,并执行其中的命令来运行流水线。

多分支流水线:

在这种类型的项目中,Jenkins再次使用Jenkinsfile作为标记的功能。在一个有Jenkinsfile的项目中,如果创建了一个新的分支,Jenkins将自动基于这个新分支创建一个新项目。此类型项目可应用于任何Git或SVN代码库。

新版本特性:

· 流水线被视为“一等公民”。这意味着流水线在应用程序中是作为实体被设计和支持的,而不是通过在Jenkins中连接一堆任务而形成流水线。
· 流水线可以通过编码编程,而不是仅仅通过配置接口来描述。这就允许使用额外的逻辑和工作流,以及在传统Jenkins中不可用或不存在的编程架构。
· 有专门用于流水线编程的结构化DSL。
· 流水线可以直接作为一个脚本在任务中创建,而不需要任何大量的Web表单交互。此外,它们可以完全在Jenkinsfile中单独创建。
· 存储为Jenkinsfile的流水线现在可独立于Jenkins和源码存储在一起。
· DSL有在工作空间中轻松共享文件的功能。
· 有更先进的、内置的使用Docker容器的支持。

当我们在Jenkins中编辑流水线时,有两种不同的语法样式:脚本式语法(scriptedsyntax)和声明式语法(declarative syntax)。

脚本式语法(scriptedsyntax):

脚本式语法(scripted syntax)是Jenkins最开始实现的流水线即代码方式。这是一种命令式风格,也就是在流水线脚本中定义逻辑和程序流程。它也更依赖于Groovy语言和结构,特别是对于错误检查和异常处理来说。

声明式语法(declarative syntax):

声明式语法(declarative syntax)是Jenkins提供的一种新的选择。声明式风格的流水线代码被编排在清晰的段落中,相对于只关注实现逻辑,这些流水线的主要区域描述(或“声明”)了我们所期望的流水线的状态和输出。在下面的代码示例中,上面是脚本式语法,下面是对应的声明式语法。

在这里插入图片描述
脚本式流水线更像是一种脚本或编程语言,像其他命令式语言一样可以运行程序和处理逻辑,而声明式流水线则更像Jenkins的传统实现方式,在Web表单的预定义字段中输入关键信息,代表了特定目标和预期行为。与传统的Web表单类似,当执行声明式流水线时,每一个段落定义了基于用户输入数据的执行内容和方式。

我们可以通过分析每种类型的优缺点,获取普遍规律和一些参考指导。
简而言之,脚本式流水线具有以下优点:
· 更少的代码段落和弱规范要求。
· 更强大的程序代码能力。
· 更像编写代码程序。
· 传统的流水线即代码模型,用户熟悉并向后兼容性。
· 更灵活的自定义代码操作。
· 能够构建更复杂的工作流和流水线。
脚本式流水线具有以下缺点:
· 普遍要求更高的编程水平。
· 语法检查受限于Groovy语言及环境。
· 和传统Jenkins模型有很大差异。
· 与声明式流水线的实现相比,同一工作流会更复杂。
声明式流水线具有以下优点:
· 更结构化,贴近传统的Jenkins Web表单形式。
· 更强大的声明内容能力,高可读性。
· 可以通过Blue Ocean图形化界面自动生成。
· 段落可映射到常见的Jenkins概念,比如通知。
· 更友好的语法检查和错误识别。
· 提升流水线间的一致性。声明式流水线具有以下缺点。
· 对迭代逻辑支持较弱(相比程序而言)。
· 仍在开发完善中(对于传统Jenkins中的部分功能缺乏支持)。
· 更严格的结构(更难实现自定义流水线代码)。
· 目前对于复杂的流水线和工作流难以胜任。

简而言之,对于新用户和那些希望流水线具备传统Jenkins一样可读性的用户来说,声明式流水线更容易学习和维护。这是以灵活性为代价换取结构不支持的功能。脚本式流水线更加灵活,提供了“超级用户”的选项,即允许用户不受结构约束实现更多功能。不过,总的来说,任何一种流水线类型对大多数场景而言都同样适用。

系统(system):主节点(master)、节点(node)、代理节点(agent)和执行器(executor)

… 不管我们使用脚本式语法还是声明式语法,每条Jenkins流水线都必须具备一个或多个系统用于执行代码。术语系统(system)在这里作为一种通用方法描述了我们所有需要讨论到的项目(item)。请记住,在任何给定的系统或机器上都可能运行着多个Jenkins实例。
…在传统Jenkins中只有两类节点:主节点(master)和从节点(slave),你可能已经非常熟悉这些概念了。下面是对一些相似概念的描述,主要为了对比突出差异点。

主节点:

…Jenkins主节点是一个Jenkins实例(instance)的主要控制系统。它能够完全访问所有Jenkins配置选项和任务(job)列表。如果没有指定其他系统(system),它也是默认的任务执行节点。不过并不推荐在主节点上执行高负载任务,任何需要大量处理的任务都应该在主节点之外的系统上运行。这样做的另一个原因是,凡是在主节点上执行的任务,都有权限访问所有的数据、配置和操作,这会构成潜在的安全风险。同样值得注意的是,在主系统上不应该执行任何包含潜在阻塞的操作,因为主系统需要持续响应和管理各类操作过程。

节点:

… 在Jenkins 2中,节点是一个基础概念,代表了任何可以执行Jenkins任务的系统。节点中包含主节点和代理节点,有的时候也用于指代这些概念。此外,节点也可以是一个容器,比如Docker。在任何Jenkins实例中主节点都会存在,但是由于上述原因,我们并不推荐在主节点上执行任务。

代理节点:

… 在早先版本的Jenkins中,代理节点被称为从节点(slave),其代表了所有非主节点的系统。这类系统由主系统管理,按需分配或指定执行特定的任务。例如,我们可以分配不同的代理节点针对不同的操作系统构建任务,或者可以分配多个代理节点并发地运行测试任务。为了减少系统负载,降低安全风险,通常在子系统上只会安装一个轻量级的Jenkins客户端应用来处理任务,这个客户端应用对资源访问是受限的。随着代理节点和节点之间关系的演进,代理节点在节点上运行。在脚本式流水线中,“节点”特指一个运行代理节点的系统,而在声明式流水线中,其指代一个特定的代理节点来分配节点。

指令与步骤:

… 根据节点和代理节点在声明式语法和脚本式语法中的使用方式,我们可以得出这两个概念之间的高层次的差异。node用于脚本式流水线,从技术层面上看它是一个步骤,代表可以用于流水线中执行活动的资源。它在一个运行代理节点的节点上面分配一个执行器,并进一步在定义的代码块上运行代码。下面的代码片段展示了一个指定node步骤的简单示例:
在这里插入图片描述
而相对于声明式流水线中的agent,它作为一个指令用来分配节点,除非使用了特殊用法agent none。下面是一个简单的agent声明的示例:
在这里插入图片描述

执行器:

…执行器同上述所有系统都有关系。让我们来看看Jenkins如何定义这个术语。简单地说,执行器只是节点/代理节点用于执行任务的一个插槽。一个节点可以有任意多个执行器。执行器的数量定义了该节点可以执行的并发任务数量。当主节点将任务分配给特定节点时,该节点上必须有可用的执行器插槽来立即执行该任务,否则任务会一直处于等待状态,直到一个执行器变为可用。执行器的数量和其他参数可以在创建节点的时候进行配置,后面会介绍这一主题。

在这里插入图片描述

创建节点:

在传统版本的Jenkins中,任务可以在主节点实例或者从节点实例上执行。在Jenkins 2的术语中,这些实例被统一成通用术语“节点”。建立新节点和过去添加从节点的方法是完全一样的。下面是一个简单的示例。
在这里插入图片描述
在管理节点界面中,选择新节点并填写表单,包括执行器数量:
在这里插入图片描述
在管理节点界面中,选择新节点并填写表单,包括执行器数量:
在这里插入图片描述
在这里插入图片描述
注意,在界面底部有环境变量和工具路径两个复选框。勾选这些复选框可以为该节点定义特殊变量和工具。只有当你希望使用与主节点不同的配置时,才会用到这些复选框;
标签可以满足系统和用户的不同需求,比如可以用于以下场景。
· 识别一个特定的节点(通过一个专有标签)。
· 对一类节点进行分组(通过分配相同的标签)。
· 识别节点的特征,方便使用(通过一个有意义的标签,比如“Windows”或者“West Coast”)。上面的最后一个场景是推荐场景。
更多关于不同启动方法和节点配置的信息,请查看Jenkins在线文档。一旦节点准备就绪,我们就可以专注于创建流水线了。我们将通过Jenkins DSL结构化程序来实现这一点。

Jenkins DSL和Groovy语言:

Jenkins流水线的DSL基于Groovy语言实现。这意味着我们可以按照需求在流水线中使用Groovy语言的结构和习惯用法。但在通常情况下,我们倾向于避免使用过于复杂的Groovy代码,或者至少将其与主脚本分开。这样做的原因是,使用过多的Groovy代码会降低脚本的可读性和可维护性,尤其是对那些不了解Groovy的人来说。声明式流水线禁止使用定义结构之外几乎所有的Groovy代码,并且还提供了更多类似于传统Jenkins特性的功能,因此你必须尽量减少使用自定义Groovy代码。
下面是一个非常简单的Jenkins DSL流水线表达式:
在这里插入图片描述

节点:

…节点在管理Jenkins→管理节点界面中定义,操作方法和之前添加从节点的方法完全一致。每一个节点都会自动安装Jenkins代理节点来执行任务(注意,这里假设在Jenkins实例中已经添加了一个节点,并打上了worker1标签):

节点和代理节点:

…在之前的Jenkins术语部分,我们已经介绍了节点和代理节点的区别。在这一部分中,代理节点特指在“非主节点”上运行Jenkins代码。这一行告诉Jenkins应该在哪个节点上运行这部分流水线。它将代码与节点上运行的Jenkins代理程序绑定起来。通过将定义的名称作为参数(标签)传递进来指定特定节点。这个节点或系统必须已被定义,并且Jenkins系统知晓它的存在。在这里你可以选择不提供标签,但是如果忽略标签,则需要了解它的运作机制。
· 如果master被配置为默认的执行节点,那么Jenkins会在master上执行任务(可以配置master为不执行任何任务)。
· 否则,节点标签为空(或者在声明式语法中使用agent any),Jenkins会在任意节点上找到第一个可用的执行器来执行任务。换言之,如果在这里指定多个名称(使用逻辑运算符)也是完全有效的,尤其当你需要基于多个维度来选择节点的时候(如地点、类型等)很有意义。下面的扩展内容介绍了如何使用这项功能。
为一个节点打多重标签:
你可以使用标准的逻辑运算符来指定多个标签,比如,“||”表示或,“&&”表示与:
为什么要这么做呢?假设你分别在美国的东西海岸拥有两套Linux系统。基于某些特定的操作场景,你可能希望某些Jenkins任务被发送到东海岸,而另一些则在西海岸执行。
那么在这个场景中,你可以为所有节点添加Linux标签,同时附加一个新的标签来表示所在地域,如east或west。一旦标签就绪,你就可以通过操作符和标签的组合来指定节点。例如,一个任务需要在东海岸的Linux节点执行,可以这样描述:在这里插入图片描述
这种大括号结构({})被称为Groovy闭包,标记了流水线中与该节点关联的代码起止段落。闭包也类似于程序中传递的实体,最后一个语句代表了返回值。(请参阅Groovy文档以获取更多关于闭包的信息。)
节点和映射:
除了定义节点来执行指定阶段任务,节点还可以通过映射指定其他部分代码的执行位置,比如,下面是一个parallel结构的示例:
在这里插入图片描述

阶段:

…在节点的定义中,我们可以将个人设置、DSL命令和逻辑组合在一个stage闭包中。阶段必须指定一个name,这提供了一种机制,可以用来描述这个阶段的职责。现有的阶段实质上并没有在脚本中做什么事情,仅在运行流水线时在输出中标识出这个阶段的位置。研发人员可以决定在一个特定阶段中包含多少流水线逻辑。然而,一个通用的实践是创建阶段来模仿传统流水线中的任务片段。例如,我们可以设计一个阶段来获取源码,一个阶段来编译源码,一个阶段来执行单元测试,一个阶段来执行集成测试等.

步骤:

…阶段中包含了实际的Jenkins DSL命令,这在Jenkins术语中被称为步骤(step)。一个步骤是DSL定义中最基本的功能。它虽然不是Groovy命令,但是可以和Groovy命令搭配使用。在以下示例中,我们通过初始步骤来获取源码:
在这里插入图片描述
这种语法非常简单易懂,调用git指令并传递给它拉取代码的地址参数(使用安全的HTTP协议)。对完整的步骤语法而言,这是一种缩写格式。当在脚本中使用DSL时,步骤的缩写格式和完整格式语法都会碰到,所以有必要花点时间来更好地理解语法模型的细节。

理解步骤语法:

Jenkins DSL中的步骤总是期望映射(命名)参数。为了说明这一点,下面有另一个版本的git步骤的定义:
在这里插入图片描述
请注意,在这里有两个命名参数,其映射到期望的值:branch等于’test’,url等于:
在这里插入图片描述
实际上,这种语法本身是Groovy所使用的映射语法的一种简写形式。[命名参数:value,命名参数:value]等同于[key: value, key: value]的Groovy映射语法。其中命名参数函数作为映射的关键字。
Groovy还允许跳过参数的圆括号。如果没有这些快捷方式,较长版本的步骤将是这样的:
在这里插入图片描述
在本例中只有url参数是必选参数。如果没有命名参数,那么默认的参数就是script对象。下面的示例是一个bat步骤,在Windows系统上运行批处理或shell脚本。按照标准完整版语法,命令类似如下:
在这里插入图片描述
这个命令可以简写:
在这里插入图片描述
在这里插入图片描述
现在我们已经理解了脚本式流水线的基本结构,接下来让我们创建一个Jenkins流水线任务,并使用相关工具创建一个脚本:
…不管是哪个版本的Jenkins,我们都是通过新建一个指定类型的项目来开始一个新项目的。Jenkins 2内置了流水线类型的项目支持。这种类型的项目提供了编写代码来定义流水线的环境。在刚开始接触这类项目的时候,理解如何配置和使用环境创建、编辑、运行和监控流水线是很有帮助的。Jenkins的流水线脚本既可以在流水线类型的Jenkins任务中创建,也可以定义在一个叫作Jenkinsfile的外部文件中。Jenkinsfile可以同代码保存在一起。我们会采用在流水线任务中创建脚本的方式来学习创建DSL脚本。Jenkinsfile可以在任何文本编辑器中创建,当然也可以从流水线任务中复制生成。然而,在调用外部资源等任务时,流水线也需要进行相关调整。
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焱宣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值