pipline官方介绍:
jenkins2.X官方介绍
官方pipline示例
pipline是帮助Jenkins实现CI到CD转变的重要角色,是运行在jenkins2.X版本的核心插件,简单来说Pipline就是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程,从而实现单个任务很难实现的复杂流程编排和任务可视化。
什么是Jenkins的流水线?
Jenkins 流水线 (或简单的带有大写"P"的"Pipeline") 是一套插件,它支持实现和集成 continuous delivery pipelines 到Jenkins。
_continuous delivery (CD) pipeline_是你的进程的自动表达,用于从版本控制向用户和客户获取软件。 你的软件的每次的变更 (在源代码控制中提交)在它被释放的路上都经历了一个复杂的过程 on its way to being released. 这个过程包括以一种可靠并可重复的方式构建软件, 以及通过多个测试和部署阶段来开发构建好的软件 (c成为 “build”) 。
流水线提供了一组可扩展的工具,通过 Pipeline domain-specific language (DSL) syntax. 对从简单到复杂的交付流水线 “作为代码” 进行建模。
对Jenkins 流水线的定义被写在一个文本文件中 (成为 Jenkinsfile),该文件可以被提交到项目的源代码的控制仓库。 这是"流水线即代码"的基础; 将CD 流水线作为应用程序的一部分,像其他代码一样进行版本化和审查。 创建 Jenkinsfile
并提交它到源代码控制中提供了一些即时的好处:
- 自动地为所有分支创建流水线构建过程并拉取请求。
- 在流水线上代码复查/迭代 (以及剩余的源代码)。
- 对流水线进行审计跟踪。
- 该流水线的真正的源代码, 可以被项目的多个成员查看和编辑。
While定义流水线的语法, 无论是在 web UI 还是在 Jenkinsfile 中都是相同的, 通常认为在Jenkinsfile
中定义并检查源代码控制是最佳实践。
pipeline中几个重要概念:
- pipeline 流水线是用户定义的一个CD流水线模型 。流水线的代码定义了整个的构建过程, 他通常包括构建, 测试和交付应用程序的阶段 。
pipeline 块
是声明式流水线语法
的关键部分- Stage:阶段,一个pipeline可以划分为若干个stage,每个stage都是一个操作步骤,比如clone代码、代码编译、代码测试和代码部署,阶段是一个逻辑分组,可以跨多个node执行。
- Node:节点,每个node都是一个jenkins节点,可以是jenkins master也可以是jenkins agent,node是执行step的具体服务器。另外,
node块
是脚本化流水线语法
的关键部分- Step:步骤,step是jenkins pipeline最基本的操作单元,从在服务器创建目录到构建容器镜像,由各类Jenkins插件提供实现,一个stage中可以有多个step,例如:sh “make”
可持续性:jenkins的重启或者中断后不影响已经执行的pipeline Job
支持暂停:pipeline可以选择停止并等待人工输入或批准后再继续执行
可扩展:通过groovy的编程更容易的扩展插件
并行执行:通过groovy脚本可以实现step,stage间的并行执行,和更复杂的相互依赖关系。
新建pipeline(流水线)任务
由于pipeline在语法中指定节点,所以不用选择执行节点
可以看到任务是分阶段顺序执行的
jenkins为我们提供了片段生成器
可以看到在节点机上下载了脚本文件
[root@k8s-node-02 ~]# ll /var/lib/jenkins/workspace/New-world-pipeline
total 4
-rw-r--r--. 1 root root 39 Feb 9 11:42 echo.py
类似可以补充上相关的阶段任务
Jenkinsfile 能使用两种语法进行编写 - 声明式和脚本化。
声明式和脚本化的流水线从根本上是不同的。 声明式流水线的是 Jenkins 流水线更近的特性:
- 相比脚本化的流水线语法,它提供更丰富的语法特性,
- 是为了使编写和读取流水线代码更容易而设计的。
在声明式流水线语法中, pipeline 块定义了整个流水线中完成的所有的工作。
Jenkinsfile (Declarative Pipeline)
pipeline { agent any //在任何可用的代理上,执行流水线或它的任何阶段。 stages {stage('Build') { //定义 "Build" 阶段。steps { //执行与 "Build" 阶段相关的步骤。// }}stage('Test') { //定义"Test" 阶段。steps { //执行与"Test" 阶段相关的步骤。// }}stage('Deploy') { steps {// }}}
}
示例
def getversion(){def version = '1.0.0'return version;
}
pipeline{agent anytools{maven 'MAVEN_HOME'}options {}environment{{}parameters {}triggers{}stages {stage('编译打包') {environment {DEBUG_FLAGS = '-g'}echo '编译打包'}stage('部署') {steps {echo '部署'}}}post {always {}success {}failure{}}
}
在脚本化流水线语法中, 一个或多个 node 块在整个流水线中执行核心工作。 虽然这不是脚本化流水线语法的强制性要求, 但它限制了你的流水线的在node
块内的工作做两件事:
- 通过在Jenkins队列中添加一个项来调度块中包含的步骤。 节点上的执行器一空闲, 该步骤就会运行。
- 创建一个工作区(特定为特定流水间建立的目录),其中工作可以在从源代码控制检出的文件上完成。
Caution: 根据你的 Jenkins 配置,在一系列的空闲后,一些工作区可能不会自动清理 。参考 JENKINS-2111 了解更多信息。
Jenkinsfile (Scripted Pipeline)
node { //在任何可用的代理上,执行流水线或它的任何阶段。stage('Build') { //定义 "Build" 阶段。 stage 块 在脚本化流水线语法中是可选的。 然而, 在脚本化流水线中实现 stage 块 ,可以清楚的显示Jenkins UI中的每个 stage 的任务子集。// //执行与 "Build" 阶段相关的步骤。}stage('Test') { // }stage('Deploy') { // }
}
Jenkins Pipeline编码声明式和脚本式的区别
agent 指定了整个流水线或特定的阶段, 会在Jenkins环境中执行的位置(master节点或其它从节点运行)。可以在 pipeline 块的顶层被定义, 也可以在 stage 内定义。选项,包括
- any,在任何可用的代理上执行流水线或阶段。例如: agent any
- none,当在 pipeline 块的顶部没有全局代理, 该参数将会被分配到整个流水线的运行中并且每个 stage 部分都需要包含他自己的 agent 部分。比如: agent none
- label,在提供了标签的 Jenkins 环境中可用的代理上执行流水线或阶段。 例如: agent { label ‘my-defined-label’ }
- node,agent { node { label ‘labelName’ } } 和 agent { label ‘labelName’ } 一样, 但是 node 允许额外的选项 (比如 customWorkspace )。
Global Tool Configuration(全局工具配置)中配置的工具, tool指令能帮助我们自动下载并安装所指定的构建工具,并将其加入 PATH 变量中。这样,我们就可以在sh步骤里直接使用了。但在agent none的情况下不会生效。
tools指令默认支持3种工具:JDK、Maven、Gradle。通过安装插件,tools 指令还可以支持更多的工具。
tools {
git ‘Default’
jdk ‘JAVA_HOME’
maven ‘MAVEN_HOME’
}
可在在 pipeline中 或 stage配置
- 在 pipeline 中定义 environment, 表示 pipeline 全局使用的环境变量
- 在 stage 中定义 environment, 表示当前 stage 的环境变量
有三种引用方式:
使用环境变量
Jenkins 流水线通过全局变量 env 提供环境变量,它在 Jenkinsfile 文件的任何地方都可以使用。Jenkins 流水线中可访问的完整的环境变量列表记录在 ${YOUR_JENKINS_URL}/pipeline-syntax/globals#env
,包括:
内置的环境变量
变量 | 说明 |
---|---|
BUILD_ID | 当前构建的 ID,与 Jenkins 版本 1.597+ 中创建的构建号 BUILD_NUMBER 是完全相同的。 |
BUILD_NUMBER | 当前构建号,比如 “153”。 |
BUILD_TAG | 字符串 jenkins-${JOB_NAME}-${BUILD_NUMBER} 。可以放到源代码、jar 等文件中便于识别。 |
BUILD_URL | 可以定位此次构建结果的 URL(比如 http://buildserver/jenkins/job/MyJobName/17/ ) |
EXECUTOR_NUMBER | 用于识别执行当前构建的执行者的唯一编号(在同一台机器的所有执行者中)。这个就是你在“构建执行状态”中看到的编号,只不过编号从 0 开始,而不是 1。 |
JAVA_HOME | 如果你的任务配置了使用特定的一个 JDK,那么这个变量就被设置为此 JDK 的 JAVA_HOME。当设置了此变量时,PATH 也将包括 JAVA_HOME 的 bin 子目录。 |
JENKINS_URL | Jenkins 服务器的完整 URL,比如 https://example.com:port/jenkins/ (注意:只有在“系统设置”中设置了 Jenkins URL 才可用)。 |
JOB_NAME | 本次构建的项目名称,如 “foo” 或 “foo/bar”。 |
NODE_NAME | 运行本次构建的节点名称。对于 master 节点则为 “master”。 |
WORKSPACE | workspace 的绝对路径。 |
用于配置Pipeline本身
buildDiscarder
为最近的流水线运行的特定数量保存组件和控制台输出。例如: options { buildDiscarder(logRotator(numToKeepStr: ‘1’)) }
disableConcurrentBuilds
不允许同时执行流水线。 可被用来防止同时访问共享资源等。 例如: options { disableConcurrentBuilds() }
overrideIndexTriggers
允许覆盖分支索引触发器的默认处理。 如果分支索引触发器在多分支或组织标签中禁用, options { overrideIndexTriggers(true) } 将只允许它们用于促工作。否则, options { overrideIndexTriggers(false) } 只会禁用改作业的分支索引触发器。
skipDefaultCheckout
在agent
指令中,跳过从源代码控制中检出代码的默认情况。例如: options { skipDefaultCheckout() }
skipStagesAfterUnstable
一旦构建状态变得UNSTABLE,跳过该阶段。例如: options { skipStagesAfterUnstable() }
checkoutToSubdirectory
在工作空间的子目录中自动地执行源代码控制检出。例如: options { checkoutToSubdirectory(‘foo’) }
timeout
设置流水线运行的超时时间, 在此之后,Jenkins将中止流水线。例如: options { timeout(time: 1, unit: ‘HOURS’) }
retry
在失败时, 重新尝试整个流水线的指定次数。 For example: options { retry(3) }
timestamps
预谋所有由流水线生成的控制台输出,与该流水线发出的时间一致。 例如: options { timestamps() }
参数类型包括:单行文本、布尔、 多行文本、选项、密码
parameters {
// 单行文本参数
string(name: 'user', defaultValue: '', description: '用户参数')
// 布尔参数
booleanParam(name: 'is_build', defaultValue: true, description: '是否构建')
// 多行文本参数
text(name: 'welcome_text', defaultValue: 'One\nTwo\nThree\n', description: '多行文本参数')
// 选项参数
choice(name: 'select', choices:['请选择','编译打包','部署','启动','关闭','回滚'],description: '操作(请选择操作:编译打包、部署、启动、关闭、状态)')
// 密码参数
password(name: 'psw', defaultValue: '123456', description: '密码')
}
其它参数可以通过安装插件实现,比如Extended Choice Parameter(复选框插件)。
extendedChoice(description: '服务器(仅在部署、启动、关闭、状态操作时需要选择)', value: '192.168.1.100,192.168.1.101',descriptionPropertyValue: '192.168.1.100(测试),192.168.1.101(正式)',multiSelectDelimiter: ',', name: 'servers', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', visibleItemCount: 5)
在阶段中调用上边设置的参数
pipeline{agent anystages {stage('编译打包') {steps {script {if (params.is_build == true) {echo "build"}else{echo "=====跳过编译打包"}}}
}
stage('部署') {steps {script {if ("${params.select}".trim() == "部署") {echo "deploy"}}}
}}
}
input会暂停Pipeline的执行,直到用户输入参数
配置选项
message(必需):提示的文本内容;
id(可选):可选标识符,默认为stage名称。
ok(可选):“ok” 按钮的显示的文本。
submitter(可选):允许操作的用户ID或角色名,默认允许任何用户。
submitterParameter(可选):环境变量的可选名称。如果存在,用 submitter 名称设置。
parameters(可选):可选的参数列表。
stages {stage('部署') {input '是否确认部署或停止?'steps {deploy(ip)}}
}
input支持内部使用普通参数(单行文本、布尔、选项参数等)
stages {stage('Example') {stages {stage('部署') {message "是否确认部署或停止?"ok '部署'submitter "alice,bob"parameters {extendedChoice(name: 'servers', description: '服务器', value: '192.168.1.100,192.168.1.101',descriptionPropertyValue: '192.168.1.100(测试),192.168.1.101(正式)',multiSelectDelimiter: ',', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', visibleItemCount: 5)string(name: 'myparam', defaultValue: 'dev', description: '自定义参数')}steps {deploy(ip)}}}}}
Jenkins内置支持cron、pollSCM、upstream三种方式
定时执行就像cronjob一样,一到时间点就执行。Jenkins采用了UNIX任务调度工具CRON的配置方式,用5个字段代表5个不同的时间单位(中间用空格隔开),语法如下:
字段 | * | * | * | * | * |
含义 | 分钟 | 小时 | 日期 | 月份 | 星期 |
取值范围 | 0-59 | 0-23 | 1-31 | 1-12 | 0-7 |
pipeline{......triggers{cron('0 * * * *')}......
}
定期到代码仓库轮询代码是否有变化,如果有变化就执行。
pipeline{......triggers{pollSCM('H/1 * * * *')}......
}
其它事件触发了pipeline执行,这个事件可以是在界面上手动触发、其它job触发、Http API Webhook触发等。
可以利用上游Job的运行状态来进行触发
pipeline{agent any//说明:当test_1或者test_2运行成功的时候,自动触发triggers { upstream(upstreamProjects: 'test_1,test_2', threshold: hudson.model.Result.SUCCESS) }stages{stage("stage1"){steps{echo "hello"}}}
}
hudson.model.Result是一个枚举,包括以下值:
注意:这种需要手动构建当前任务一次,让jenkins加载pipeline后,trigger指令才生效
当gitlab发现源代码有变化时,触发jenkins执行构建。
pipeline {
agent any
triggers {gitlab(triggerOnPush: true,triggerOnMergeRequest: true,branchFilterType: "All",secretToken: "rvgtcxwufgbcsr56lftzr5a74vhjko0")
}
stages {stage('pull') {steps {echo '拉取代码'}}
}
}
根据stages执行结果预定义的执行条件
post支持的条件块
需要安装插件Qy Wechat Notification,唯一不足当前插件不支持自定义文本。
post {always {qyWechatNotification mentionedId: '', mentionedMobile: '', webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxxxxx'}
}
需要安装插件HTTP Request,与第三方系统集成的常用方式
post {always {httpRequest requestBody: '{\'build\':\'${env.BUILD_ID}\'}', responseHandle: 'NONE', url: 'http://192.168.1.100:8080/noti'}
}
Pipeline支持的基本步骤(内置步骤),详细可查看(https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/):
- catchError: 捕捉错误和设置构建结果为失败。
- deleteDir: 在工作区内递归删除当前目录
- dir: 设置当前工作目录。
- echo: 打印信息
- error: 设置构建结果和阶段结果为异常,并打印设置的信息,可以中断流水线的执行,也可以抛出新的Exception(),但是这个步骤不会打印堆栈信息。
- fileExists: 检查文件是否存在,返回true|false。
- isUnix: 检查是否运行在类unix节点上
- mail: 邮件通知
- pwd: 以字符串形式返回当前目录路径。
- readFile: 从相对路径读取文件(通常是工作空间),并以普通字符串的形式返回其内容。
- retry: 重试内部代码N次。
- sleep: 暂停管道构建,直到给定的时间过期。
- stash: 在构建的阶段中把文件保存起来,这个文件可以给当前构建中的其它阶段使用。
- step: 一般的构建步骤
- timeout: 设置执行超时时间,如果块内的代码执行时间超出限制,会抛出异常。
- tool: 使用预定义的工具安装中的工具
- unstable: 设置构建结果和阶段结果设置为不稳定。并打印日志信息。
- unstash: 取出之前stash保存的文件。
- waitUntil: 反复运行它的内部代码块,直到返回true。如果返回false,等待一段时间并再次尝试。
- warnError: 捕获错误并将构建和阶段结果设置为不稳定
- withEnv: 设置环境变量
- wrap: 一般构建包装
- writeFile: 将给定的内容写入当前目录中。
- archive: 把构建中输出的内容存档,供以后其它构建使用。Jenkins 2.x后,提供archiveArtifacts代替archive,该步骤已弃用。
- getContext: G从内部api获取上下文对象。
- unarchive: 将存档的工件复制到工作区中。
- withContext: 在块内部使用上下文对象 API。
Jenkins Pipelin支持的所有步骤列表:https://www.jenkins.io/doc/pipeline/steps/
文件上传,支持SSH文件上传的插件目前主要有Publish Over SSH、SSH Pipeline Steps
需要先在全局配置中配置远程服务器信息
Jenkinsfile中脚本代码:
stage('部署和启动') {sshPublisher(publishers: [sshPublisherDesc(configName: "192.168.28.129_test1",transfers: [sshTransfer(cleanRemote: false,excludes: '',execCommand: """cd ${deploy_dir} // 远程执行的shell""",execTimeout: 120000,flatten: false,makeEmptyDirs: false,noDefaultExcludes: false,patternSeparator: '[, ]+',remoteDirectory: "upload", // 远程目录remoteDirectorySDF: false,removePrefix: "penneo/", // 删掉的去缀sourceFiles: "penneo/test.zip") // 上传的文件],usePromotionTimestamp: false,useWorkspaceInPromotion: false,verbose: true)])}
node {def remote = [:]remote.name = ‘test’remote.host = ‘192.168.28.129’remote.user = ‘penngo’remote.password = ‘123456’remote.allowAnyHosts = truestage(‘Remote SSH’) {writeFile file: ‘abc.sh’, text: ‘ls’sshCommand remote: remote, command: ‘ls -al’sshPut remote: remote, from: ‘abc.sh’, into: ‘.’sshGet remote: remote, from: ‘abc.sh’, into: ‘bac.sh’, override: truesshScript remote: remote, script: ‘abc.sh’sshRemove remote: remote, path: ‘abc.sh’}}
也可以结合withCredentials使用
stages {stage('部署') {steps {script{def ip = '192.168.28.132'withCredentials([sshUserPrivateKey(credentialsId: "${ip}_pk", keyFileVariable: 'identity', usernameVariable: 'username')]) {def remote = [:]remote.name = ipremote.host = ipremote.allowAnyHosts=trueremote.user = usernameremote.identityFile = identitysshCommand remote: remote, command: """pwdls -al"""// 把远程主机文件下载到本地工作区sshGet remote: remote, from: 'build_id.txt', into: 'build2_id.txt', override: true// 本地工作区文件上传到远程主机目录sshPut remote: remote, from: 'JApiTest.zip', into: '/data/upload/'}withCredentials([usernamePassword(credentialsId: "${ip}", passwordVariable: 'password', usernameVariable: 'username')]) {def remote = [:]remote.name = ipremote.host = ipremote.user = usernameremote.password = passwordremote.allowAnyHosts=truesshCommand remote: remote, command: """cd /usr/localpwdls -al"""sshGet remote: remote, from: 'build_id.txt', into: 'build2_id.txt', override: truesshPut remote: remote, from: 'JApiTest.zip', into: '/data/upload/'
// sshScript remote: remote, script: 'server.sh'sshRemove remote: remote, path: '/root/ttt_test'}}}}}
视图可用于归档job进行分组显示,比如将一个业务的视图放在一个视图显示,安装完成build pipeline插件之后将会有一个+
号用于创建视图
安装build pipeline
插件
另外还有“列表视图”及“我的视图”,自行查看吧
上一篇:docker拉取mysql
下一篇:【C++】static成员