Jenkins - Pipeline详解

1 - Jenkins Pipeline

在Jenkins 2.0中,基于 Jenkins Pipeline,用户可以在一个 JenkinsFile 中快速实现一个项目的从构建、测试以到发布的完整流程,灵活方便地实现持续交付,并且可以保存和管理这个流水线的定义。
也就是说,Jenkins 2.0把Jenkins1.0中相关配置信息都转换成Code形式,即Pipeline as Code。

Jenkinsfile 定义了流水线的各个阶段,在每个阶段可以执行相应的任务,实现了构建步骤代码化、构建过程视图化。
不同的Jenkins Plugin 扩展了Pipeline DSL可用的步骤和操作。

1.1 使用条件

  • Jenkins 2.x或更高版本
  • 安装了Pipeline插件

1.2 创建方式

以流水线任务为例:
在Jenkins job配置页面的pipeline部分,可以选择pipeline script 或者 pipeline script from SCM
点击“Pipeline Syntax”可以查看Pipeline内置文档。

  • pipeline script : 直接script输入框里面输入pipeline script语句即可
  • pipeline script from SCM : 配置代码存储地址,并指定Jenkinsfile路径

2 - 脚本式(Scripted Pipeline)

在Scripted Pipeline的JenkinsFile 中可以定义多个 Groovy 函数来扩展 Jenkins Pipeline 的能力
因此这种方式受 Jenkins 的限制较少,可以灵活控制和定义一个流水线,实现复杂的功能。

  • Node: Jenkins 节点,是执行 Step 的具体运行环境
  • Stage: 每个 Stage 代表一组操作,是一个逻辑分组的概念,可以跨多个 Node
  • Step: 最基本的操作单元,例如:执行Shell脚本、构建Docker镜像等。

3 - 声明式(Declarative Pipeline)

使用预定义的结构,Jenkins 已经预置了很多描述流水线的结构,可以快速建立流水线
虽然同样支持写 Groovy 脚本,官方推荐将Groovy 脚本内容定义在 Shared Libraries 中
由于需要使用预定义的结构,对于复杂性的功能难以有效支持
为与BlueOcean脚本编辑器兼容,通常建议使用Declarative Pipeline的方式进行编写,这种语法结构也会是未来的趋势。

3.1 常用结构

所有有效的Declarative Pipeline必须包含在一个pipeline块内。
除了个别限定外,Declarative Pipeline中的基本语句和表达式遵循与Groovy语法相同的规则。

pipeline {
    agent {}
	options {}
	parameters {}
    stages {
        stage {
		    when {}
            steps {}
		}
		parallel {
		    stage {}
			stage {}
		}
	}
    post {
	   always {}
	}
}

stages

  • 是stage的集合,Pipeline完成的所有实际工作都将包含在一个或多个stage指令中
  • 一般情况下,stages至少包含一个stage指令,用于连接各个交付过程,如构建,测试和部署等

stage

  • 用来区分pipeline的各个阶段
  • 包含的steps部分定义了具体操作内容
  • stage与stages可以互相嵌套,stage中可以包含stages

steps

  • 包含一个或多个具体操作步骤
  • 可以使用Steps reference(https:///pipeline-syntax/html)中的所有可用步骤
  • script步骤可以提供一个有效的功能增强

3.2 常用语法

# agent
- 通过 agent 定义整个Pipeline或特定阶段的执行环境,实现灵活调度资源
- Agent在Pipeline中必需存在
- 参数
    - any : 在任何可用的agent 上执行Pipeline或stage
    - none : 当在pipeline块的顶层使用none时,将不会为整个Pipeline运行分配全局agent ,每个stage部分将需要包含其自己的agent部分
    - label : 指定具体的 Jenkins Slave Node,也可以单独指定Stage的执行环境
    - docker : 执行Pipeline或stage时会动态启动一个docker节点执行Pipelines,还可以接受一个args,直接传递给docker run调用
    - dockerfile : 使用从Dockerfile源存储库中包含的容器来构建执行Pipeline或stage 
	- node : 在node中可以定义 label 和 customWorkspace(自定义运行的工作空间)等

	
# 环境变量
- 可以为全局或stage定义变量,例如`environment { aaa = 'bbb' }`
- 通过 env 访问自定义的和Jenkins预置的环境变量,例如`${env.JOB_NAME}`


# 参数
- 通过 parameters 定义参数,例如`parameters { string(defaultValue: "xxx", description: 'yyy', name: 'zzz') }`
- 通过 params 访问构建时的参数,例如`${params.xxx}`
- 支持booleanParam, choice, credentials, file, text, password, string等参数类型


# options
- 在Pipeline本身内配置Pipeline专用选项
- buildDiscarder : pipeline保持构建的最大个数
- disableConcurrentBuilds : 不允许并行执行Pipeline,可用于防止同时访问共享资源等
- skipStagesAfterUnstable : 一旦构建状态进入了“Unstable”状态,就跳过此stage
- timeout : 设置Pipeline运行的超时时间,例如`options { timeout(time: 1, unit: 'HOURS') }`
- retry : 失败后,重试整个Pipeline的次数,例如`options { retry(3) }`
- timestamps : 预定义由Pipeline生成的所有控制台输出时间,例如`options { timestamps() }`


# tools
- 通过tools可自动安装工具,并放置环境变量到PATH。如果agent none,将被忽略。
- 工具名称必须在Jenkins的全局工具配置中存在。
- 示例`tools { maven 'apache-maven-3.5.2' }`


# when
- 通过 when 根据给定的条件确定是否执行该阶段,控制流程走向
- 必须至少包含一个条件
- 多种内置条件
    - branch : 当正在构建的分支与给出的分支模式匹配时执行(仅适用于多分支Pipeline)
    - environment : 当指定的环境变量设置为给定值时执行
    - expression : 当指定的Groovy表达式求值为true时执行
    - not : 当嵌套条件为false时执行。必须包含一个条件
    - allOf : 当所有嵌套条件都为真时执行。必须至少包含一个条件
    - anyOf : 当至少一个嵌套条件为真时执行。必须至少包含一个条件

# Parallel	
- 通过 parallel 定义并发步骤
- 对耗时长,相互不存在依赖的stage可以使用此方式提升运行效率
- 除了parallel stage,单个parallel里的多个step也可以使用并行的方式运行

	
# 超时、重试
- 通过 timout 定义超时时间,例如`timeout(time: 3, unit: "MINUTES") { xxxyyyzzz }`
- 通过 retry 定义重试次数,例如`retry(3) { xxxyyyzzz }`


# post
- 通过 post 定义资源清理、通知等,也就是定义Pipeline或stage运行结束时的操作
- 与Stages平级
- 有多种不同的condition: always、success、failure、unstable、changed
    - always : 总是运行,无论Pipeline运行的完成状态如何。
    - changed : 只有当前Pipeline运行的状态与先前完成的Pipeline的状态不同时,才能运行。
    - failure : 仅当前Pipeline处于“失败”状态时才运行,通常在Web UI中用红色指示表示。
    - success : 仅当前Pipeline具有“成功”状态时才运行,通常在具有蓝色或绿色指示的Web UI中表示。
    - unstable : 仅当前Pipeline具有“不稳定”状态时才运行,通常在具有黄色指示的Web UI中表示。
    - aborted : 只有当前Pipeline处于“中止”状态时,才会运行,通常在具有灰色指示的Web UI中表示。


# 触发方式
- 通过 triggers 定义Pipeline自动化触发的方式
- cron : 以cron风格来定义Pipeline触发的常规间隔
- pollSCM : 以cron风格来定义Jenkins检查SCM源更改的常规间隔。如果存在新的更改,则Pipeline将被重新触发

4 - 声明式与脚本式的比较

都是pipeline代码的持久实现,都能够使用pipeline内置的插件或者插件提供的steps,两者都可以利用共享库扩展。
不同之处在于语法和灵活性:

  • Declarative pipeline对用户来说,语法更严格,有固定的组织结构,更容易生成代码段,使其成为用户更理想的选择。但是
  • Scripted pipeline更加灵活,因为Groovy本身只能对结构和语法进行限制,对于更复杂的pipeline来说,用户可以根据自己的业务进行灵活的实现和扩展。

5 - pipeline-syntax

5.1 变量

  • 环境变量: https://<jenkins-server-url>/env-vars.html/
  • Global Variable Reference: https://<jenkins-server-url>/pipeline-syntax/globals

5.2 代码段生成器

  • Snippet Generator: https://<jenkins-server-url>/pipeline-syntax/
  • 内置的“Snippet Generator”程序有助于为单个步骤生成代码段。
  • 只需要选择所需的步骤并配置,然后单击生成Pipeline脚本以创建一个可以复制并粘贴到Pipeline中的Pipeline代码段。

6 - 参考信息

posted @ 2020-09-17 23:31  Anliven  阅读(76)  评论(0编辑  收藏