💯 作者: 俗世游子【谢先生】。 8年开发3年架构。专注于Java、云原生、大数据等领域技术。

💥 成就: 从CRUD入行,负责过亿级流量架构的设计和落地,解决了千万级数据治理问题。

📖 同名社区:​​51CTO​​​、 ​​github​​​、掘金​、​​gitee​​​。

📂 清单: ​​​goku-framework​​​、​【更新中】享阅读II

DevOps系列

​深入浅出DevOps:DevOps核心思想​

​深入浅出DevOps:版本控制Git&Gitlab​

​深入浅出DevOps:持续集成工具Jenkins​

​深入浅出DevOps:简易Docker入门​

​深入浅出DevOps:Jenkins实战之CI​

​深入浅出DevOps:SonarQube提升代码质量​

​深入浅出DevOps:SonarQube提升代码质量【下】​

​深入浅出DevOps:Jenkins构建器​

​深入浅出DevOps:私有镜像仓库Harbor​

​深入浅出DevOps:Jenkins基于Harbor部署​


前言

之前我们用来展示的案例都是通过自由风格的项目来构建的任务,通过查看我们会发现这几个问题:

  • 需要通过不同的配置项来完成整个任务的构建操作
  • 每个步骤流程都要通过不同的方式设置,并且构建过程中整体流程是不可见的,无法确认每个流程花费的时间
  • 每一个执行过程的日志都混放在一起,出现问题不方便定位

基于上述问题,接下来就来为大家提供对应的解决方案,那就是采用Jenkins的流水线任务

流水线任务

深入浅出DevOps:初识Pipline流水线任务_DevOps

什么是流水线任务

Jenkins的Pipeline可以让项目的发布整体流程可视化,明确执行的阶段,可以快速的定位问题。并且整个项目的生命周期可以通过一个Jenkinsfile文件管理,并且Jenkinsfile文件可以放在项目中维护。

在随后如果想要升级K8s,那么可以非常方便的切换到KubeSphere上

这样做的好处:

  • 自动地为所有分支创建流水线构建过程并拉取请求。
  • 在流水线上代码复查/迭代 (以及剩余的源代码)。
  • 对流水线进行审计跟踪。
  • 该流水线的真正的源代码, 可以被项目的多个成员查看和编辑。

所以在Jenkinsfile中定义并检查源代码控制是最佳实践,我们接下来也会采用同样的方式来进行操作

流水线语义

pipeline

流水线是用户定义的一个CD流水线模型 。流水线的代码定义了整个的构建过程, 他通常包括构建, 测试和交付应用程序的阶段。

​pipeline​​块是声明式流水线语法的关键部分

node

节点是一个机器 ,它是Jenkins环境的一部分 and is capable of执行流水线。

​node​​块是脚本化流水线语法的关键部分

stage

​stage​​ 块定义了在整个流水线的执行任务的概念性地不同的的子集(比如 "Build", "Test" 和 "Deploy" 阶段), 它被许多插件用于可视化 或Jenkins流水线目前的 状态/进展

step

本质上 ,一个单一的任务, a step 告诉Jenkins 在特定的时间点要做_what_ (或过程中的 "step")。

举个例子,要执行shell命令 ,请使用 ​​sh​​​ 步骤: ​​sh 'make'​​。当一个插件扩展了流水线DSL, 通常意味着插件已经实现了一个新的 step

流水线语法

接下来我们就来看一下关于流水线任务需要了解的语法:

  • 如果大家曾经开发过Groovy程序,那么这个对大家来说就是小意思

流水线脚本中所有的语法和表达式都遵循Groovy的语法,如果不会也不要着急。下面会为大家简单介绍一下。

深入浅出DevOps:初识Pipline流水线任务_Jenkins流水线任务_02

在流水线任务中也能看到相关的简单案例


pipeline块

还记得​​pipeline​​的作用吧,所有有效的声明式流水线必须包含在一个 ​​pipeline​​ 块中:

pipeline {
/*agent,stages都写在这里*/
}

agent块

Jenkins支持分布式,那么指定任务在某一个节点上就需要在agent中进行定义,比如

pipeline {
agent any
}

any表示在任何可用的节点上执行流水线或阶段。

agent指令应该使用在参数应用在​​pipeline​​块的顶层或 ​​stage​​ 指令内部

关于可执行节点的问题

之前并没有介绍过Jenkins的分布式部署,所以对于这块的内容并没有介绍过。

关于Jenkins在执行任务过程中可执行的节点信息,我们可以通过​​系统管理>节点管理​​中进行相关查看

深入浅出DevOps:初识Pipline流水线任务_Jenkins流水线任务_03

未来需要添加新的可执行节点也是通过当前界面来进行添加的

关于之后所说的有关label的定义,所匹配的也是此处节点,相当于为服务器节点打上了标签

好,那么接下来我们再来看看支持的其他参数

  • none

在​​pipeline​​块的顶层如果定义了​​agent none​​,表示没有定义全局代理,那么agent参数必须定义在​​stage​​部分

pipeline {
agent none
stages {
stage('Test') {
agent any
}
}
}
  • label

在指定的标签节点上指定对应的流水线任务或者阶段,可执行节点的标签在节点管理下设置,此时在流水线任务中只需要进行如下配置

pipeline {
agent {
label 'master'
}
}

深入浅出DevOps:初识Pipline流水线任务_Pipeline_04

  • node

直接来看和label的不同之处,但意义是一样的

pipeline {
agent {
node {
/* 这里的配置和上面label的定义是一样的性质 */
label 'master'
/* 自定义工作区 */
customWorkspace '/some/other/path'
}
}
}

本人jenkins:2.332.1-lts,但是根据官网语法并无法配置agent docker等相关信息,会报出如下错误,所以agent的介绍就到这里

深入浅出DevOps:初识Pipline流水线任务_Pipeline_05

stages块

深入浅出DevOps:初识Pipline流水线任务_Jenkins流水线任务_06

包含一个或多个 stage 指令, stages 部分是流水线描述的大部分任务工作的位置。 并且建议stages至少包含一个stage指令用于连续交付过程的每个离散部分,比如构建、测试、部署等每个流程。

pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Build'
}
}
stage('Test') {
steps {
echo 'Test'
}
}
stage('Deploy') {
steps {
echo 'Deploy'
}
}
}
}

以上代码块就属于一个非常简单的案例, 其中stage属于一个指令,可以通过标识说明当前指令的工作内容

stage('Build') {
steps {
echo 'Build'
}
}

并且在stage中我们也可以定义关于agent、environment等相关的指令集。

steps属于固定写法,记住就好

environment

定一个键-值对序列,该序列将被定义为所有步骤的环境变量,或者是特定于阶段的步骤, 这取决于 ​​environment​​ 指令在流水线内的位置:

  • 如果environment在pipeline位置,属于全局属性值。
  • 如果environment在stage位置,属于局部属性值,只能在当前stage下使用

用来定义属性常量使用

pipeline {
agent any
// 此处定义的environment的属性值可以使用在整个流水线任务中的各个stage中
environment {
harborHost = '192.168.10.201'
}
stages {
stage('Test') {
// 此处定义的environment只能使用在当前stage中
environment {
git = 'root'
}
steps {
echo ${harborHost}
echo ${git}
}
}
}
}

post

可以定义在stage中,也可以定义在整体的最后。post支持通过状态块的方式来定义后续的执行操作,其中包含如下几种状态

比如任务构建通知,异常处理等

  • always

无论流水线或阶段的完成状态如何,都允许在 post 部分运行该步骤。

  • changed

只有当前流水线或阶段的完成状态与它之前的运行不同时,才允许在 post 部分运行该步骤。

  • failure

只有当前流水线或阶段的完成状态为"failure",也就是构建出现了问题才允许在 post 部分运行该步骤。

  • success

只有当前流水线或阶段的完成状态为"success",整个构建成功才允许在 post 部分运行该步骤。

  • unstable

只有当前流水线或阶段的完成状态为"unstable",才允许在 post 部分运行该步骤, 通常由于测试失败,代码违规等造成。

  • aborted

只有当前流水线或阶段的完成状态为"aborted",才允许在 post 部分运行该步骤, 通常由于流水线被手动的aborted。

pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Build'
}
post {
success {
echo 'Build success'
}
}
}
stage('Test') {
steps {
echo 'Test'
}
}
stage('Deploy') {
steps {
echo 'Deploy'
}
}
}
post {
always {
echo 'stage exec'
}

success {
echo 'stages success '
}
}
}

when

当前指令允许流水线根据给定的条件决定是否应该执行阶段。 when 指令必须包含至少一个条件。 如果 when 指令包含多个条件, 所有的子条件必须返回True,阶段才能执行。 这与子条件在 allOf 条件下嵌套的情况相同。

pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Build'
}
post {
success {
echo 'Build success'
}
}
}
stage('Deploy') {
when {
branch 'feature'
}
steps {
echo 'Deploy'
}
}
}
}

以下都是关于when所支持的条件选项:

  • branch

当正在构建的分支与模式给定的分支匹配时,执行当前阶段。

when {
branch 'feature'
}
  • environment

当指定的环境变量是给定的值时,执行当前阶段

when {
environment name: 'DEPLOY_TO', value: 'production'
}
  • expression

当指定的Groovy表达式评估为true时,执行当前阶段

when { 
expression { return params.DEBUG_BUILD }
}
  • not

当嵌套条件是错误时,执行这个阶段。当前指令必须包含至少一个条件

when { 
not { branch 'master' }
}
  • allOf

当所有的嵌套条件都正确时,执行这个阶段。当前指令必须包含至少一个条件

when {
allOf {
branch 'master';
environment name: 'DEPLOY_TO', value: 'production'
}
}
  • anyOf

当至少有一个嵌套条件为真时,执行这个阶段。当前指令必须包含至少一个条件

when { 
anyOf {
branch 'master';
branch 'staging'
}
}

最后

整个流水线语法我们就先介绍到这里,通常情况下,本章的语法已经足够我们在工作中的使用。

但是如果还有设计到其他的语法需要查找的,可以点击​​进入官网​​,对相关语法进行查阅

后面我们会使用流水线的方式对任务进行改造,并且加入构建通知等。