转载

Jenkins管道最佳实践Top 10

【编者的话】Andy Pemberton领导CloudBees的解决方案架构团队。CloudBees是一家依赖Jenkins实现云化持续集成平台的创业公司,目前已经得到C轮融资。Andy拥有超过十年的软件交付经验,同时他也是经常发表演讲和撰写博客。本文是Andy做为Jenkins专家给出的10条Jekins管道化使用的最佳实践。

Jenkins的管道化插件对于其用户来说是个变局者。依赖于域领域语言(DSL)Groovy,管道化插件实现了脚本化。这对于开发复杂且步骤繁多的DevOps管道非常有帮助。本文提供了你最应该知道的关于Jekins管道化插件中“要做”和“不要做”的最佳实践-并且包含代码示例。

Jenkins管道最佳实践Top 10

1.要做:使用真正的Jenkins管道化插件

不要使用诸如Build Pipeline和Buildflow等老插件。应该使用真正的 Jenkins管道化插件套件 。

为什么呢?因为管道化插件是在底层任务上的一种改善。与那些自由式的插件不同,管道化插件对于Jenkins主节点重启是有感知能力的,并且包含了一些內建的功能。这些功能在构建多步骤、复杂的发布管道时,效果大大超越了之前的老式插件。

更多关于管道化的内容: https://jenkins.io/solutions/pipeline/

2.要做:像写代码一样开发你的管道

使用这种方法你可以在SCM中存储Jenkinsfile。并且像写其他软件一样的去版本化和测试它。

为什么要这么做呢?把你的管道作为代码会强化一种约束,并且得到GitHub和BitBucket提供的多种新功能,诸如:多分支,pull request检查和组织扫描。

Jenkins管道最佳实践Top 10

你需要给你的管道脚本一个默认名字:Jenkinsfile,并且以如下的内容作为脚本头,这样的话你的IDE,GitHub和其他工具会识别出来脚本是Groovy,并提供语法高亮功能:

!groovy

3.要做:所有工作都要放到Stage中

你的管道中任何非初始化的任务都要放到一个Stage块中。

为什么呢?因为Stage是管道的逻辑段。将任务分拆到不同Stage中等同于你将管道拆分成一个个独立的任务段。

例子:

stage 'build'
//build
stage 'test'
//test

并且有福利哦:Pipeline Stage View插件可以将管道中的一个个段进行可视化:

Jenkins管道最佳实践Top 10

4.要做:将重量级的任务放到单独节点中执行

任何管道中重量级的工作需要放到node块中执行。

为什么呢?因为默认情况下,Jenkinsfile脚本运行在Jenkins的主节点中,并且为了减少资源的消耗而使用了轻型的执行器。任何重量级的工作,例如从Git上下载代码或编译Java应用,需要使用Jenkins的分布式构建能力并且运行在代理节点中。

例子:

stage 'build'
node{
checkout scm
sh 'mvn clean install'
}

5.要做:可以将任务放到并行步骤中

管道提供了一个向前(straight-forward)的语法来支持将你的管道拆分成并行的步骤。推荐使用它。

为什么呢?因为将任务转为并行可以加快你的管道运行,将你的管道步骤放到“left”中,开发者和团队其他的成员会更快的得到反馈。

例子

parallel 'shifting':{
//everything
}, 'left':{
//I can
}

提示:使用 并行测试执行插件 可以使Jenkins自动决定如何在可选的并行桶中运行你的单元测试!获取详细信息请阅读 Parallel Test Execution on the CloudBees Blog 。

6.要做:在节点中执行并行步骤

为什么呢?管道并行化最大的好处是:做更多的重量级任务(参见最佳实践4)!通常情况下你需要在管道并行分支内部使用一个节点。

例子:

parallel 'integration-tests':{
node('mvn-3.3'){ ... }
}, 'functional-tests':{
node('selenium'){ ... }
}

7.不要做:在node块中使用input

你千万不要在node块内部使用input语句。

为什么呢?因为输入会暂停管道的执行,去等待自动的或手动的输入。自然这类等待一定会占用时间。而另一方面,node语句在工作区上获取并持有锁和重型的Jenkins执行器,去获取这么昂贵的资源而仅仅为了停下来等待输入是不合适的。

所以,请在node的外部创建input输入。

例子:

stage 'deployment'
input 'Do you approve deployment?'
node{
//deploy the things
}

8.要做:为你的输入设置超时时间

管道有一套很简单的机制来应对任务的超时。这其中的最佳实践是:你应该总是为你的输入规划好超时时间。

为什么呢?为了管道的健康清理,这就是原因。当输入的内容在指定时间窗口内没有送达时,将你的输入包装到一个超时内部可以使它们被清理掉(例如:被暂停)。

例子:

timeout(time:5, unit:'DAYS') {
input message:'Approve deployment?', submitter: 'it-ops'
}

9.不要做:使用env全局变量设置环境变量

如果你想在env全局变量中编辑一些设置时,你应该使用withEnv语法来这么做。

为什么呢?因为env变量是全局的,直接改变它是不被鼓励的,因为它改变了全局的环境。所以withEnv语法是被推荐使用的。

例子:

withEnv(["PATH+MAVEN=${tool 'm3'}/bin"]) {
sh "mvn clean verify"
}

10.要做:选择暂存文件而不是归档文件

在暂存能力被添加到管道化DSL之前,归档是在node和stage之间共享文件的最佳方案。如果你仅仅是想在stage和node之间共享文件,那么你应该使用stash/unstash,而不是archive。

为什么呢?因为暂存是被设计为共享文件的,例如:在stage和node之间共享你的应用源代码。而另外一方面,归档是被设计为长期存储文件的(例如:你的构建的中间二进制文件)。

例子:

stash excludes: 'target/', name: 'source'
unstash 'source'

总结

感谢您的阅读!新的Jenkins管道化插件已经获得了越来越多的关注,特别是在 Jenkins 2.0 发布后。我也同时相信随着全世界的开发者使用Jenkins开发他们的DevOps管道,将会有越来越多的最佳实践产生出来。

原文链接: Top 10 Best Practices for Jenkins Pipeline (翻译:高洪涛)

===========================================

译者介绍

高洪涛,当当网架构师,开源数据库分库分表中间件Sharding-JDBC作者。目前从事Docker相关研究工作。

原文  http://dockone.io/article/1531
正文到此结束
Loading...