Jenkins实现CICD之流水线pipline
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.Jenkins Pipeline概述
1.pipeline介绍
流水线生产,又叫流水生产流水作业,指劳动对象按一定的工艺路线和统一的生产速度,连续不断地通过各个工作地,按顺序地进行加工并生产出产品的一种生产组织形式。
它是对象专业化组织形成的进一步发展,是劳动分工较细,生产效率较高的一种生产组织形式。亨利·福特(Henry Ford)于1913年在密歇根州的Highland Park,建立的生产系统。
所谓的pipeline流水线,其实就是将之前的一个任务或者一个脚本昨完的工作,用pipeline语法划分为多个子任务然后分别执行,两者实现的最终效果是一样的,但是由于原始任务划分为多个子任务之后,以流水线的方式来执行,那么就可以随时查看任意子任务的执行结果,即使在某个阶段出现问题,我们也可以随时直接定位问题的发生点,大大提高项目的效率,即模块化完成复杂任务的思想体现。
pipeline是帮助Jenkins实现CI到CD转变的重要角色,是运行在Jenkins 2.x版本的核心插件,简单来说pipeline就是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程,从而实现单个任务很难实现的复杂流程编排和任务可视化。
pipeline基于Groovy DSL(领域特定语言Domain Specific Language)实现,任何发布流程都可以表述为一段Groovy脚本。
Groovy是一种基于JVM虚拟机的敏捷开发语言,它结合了Python,Ruby和Smalltalk的许多强大的特性,Groovy语法和Java语法类似。
Groovy代码不仅能够与Java代码很好结合,也能用于扩展现有代码,由于其运行在JVM上的特性,Groovy也可以使用其他非Java语言编写的库。
pipeline官网地址:
https://www.jenkins.io/zh/doc/book/pipeline/
https://www.jenkins.io/zh/2.0/
groovy官网地址:
https://www.groovy-lang.org/learn.html
https://groovy-lang.org/syntax.html
2.pipeline优势
- 一致性:
pipeline用统一的语法的代码的方式实现各个CICD阶段的任务,不仅可以被纳入版本控制,还可以通过编辑代码实现目标效果。
- 直观性:
构建过程中每一步都可以直接的图形化显示输出,比如每个阶段的执行实现,直观友好,pipeline帮助我们快速定位哪个阶段的任务出现错误。
- 可持续性:
Jenkins的重启或者中断后不影响已经执行的pipeline Job。
- 支持暂停:
pipeline可以选择停止并等待人工输入或批准后再继续执行。
- 支持回放:
如果失败,可以使用回放,进行临时性的修改job,在调试执行,如果成功,再真正修改任务即可。
- 可扩展性:
通过groovy的编程更容易扩展插件。
- 并行执行:
通过groovy脚本可以实现step,stage间并行执行,和更复杂的相互依赖关系。
- 多功能:
支持复杂CD要求,包括fork/join子进程,条件判断,循环和并行执行工作的能力。
二.pipeline语法
1.pipeline语法介绍和结构
1.1 pipeline语法类型概述
当前Jenkins 2.x支持两种语法的流水线: 声明式和脚本式。
- 脚本式(Scripted Pipeline)语法:
此语法是Jenkins最先支持pipeline语法,它采用命令式风格,直接在流水线中定义逻辑和程序流程。
- 声明式:
后来cloudBees公司为Jenkins引入的一种"流水线即代码"的pipeline语法。
它允许用户在pipeline中定义将更多的精力关注于期望pipeline的状态和输出之上,而非实现逻辑。
声明式和脚本式的流水线从根本上是不同的。声明式流水线是Jenkins流水线更新一些的特性:
- 相比脚本化的流水线语法,它提供更丰富的语法特性;
- 是为了使编写和读取流水线代码更容易而设计的;
官网地址:
https://www.jenkins.io/zh/doc/book/pipeline/syntax/
1.2 pipeline的基本结构
- Pipeline:
流水线的最外层结构,代表整条pipeline,包含着pipeline的完整逻辑,是声明式流水线语法的关键特性。
- environment
声明全局变量,方便后续使用。
- node和agent:
用于定义任务在哪里执行。
每个node都是一个Jenkins节点,可以是Jenkins master也可以是Jenkins agent,node是执行step的具体服务器。
node代码块也是脚本式pipline语法的关键特性,声明式pipeline使用agent关键字。
- stages:
用于包含所有stage的定义。
- stage:
指定stage的名称,用于定义每个阶段stage的主要任务。
一个pipeline可以划分为若干个stage,每个stage都是一个完整的操作。
比如: clone代码,代码编译,代码测试和代码部署,阶段是一个逻辑分组,可以跨多个node执行。
- steps:
每个阶段需要执行哪些命令。
步骤steps是Jenkins pipeline最基本的操作单元,从在服务器创建目录到构建容器镜像,由各类Jenkins插件提供实现,例如: sh "make"。
- post:
用在stage代码块或者整个pipeline执行完成后的附加步骤,此指令非必须项。
1.3 pipeline常用指令
无论是脚本式语法还是声明式语法,他们本质上都是执行各种命令,对于不同的命令都需要采用专用的语法来实现特定的功能。
常见的语法命令及其样式如下:
- echo:
输出信息,例如: echo "Building"。
- sh:
执行命令,例如: sh 'COMMAND' sh([script:'echo hello'])。
- git:
克隆代码,例如: git branch: 'develop',credentialsld:'a1d2c3db',url:'git@10.0.0.11:yinzhengjie/bms.git'。
- env:
设置变量,例如: env.PATH="/usr/local/java/bin:$PATH"。
Jenkins内置语法帮助:(需要安装pipeline插件并且是pipeline风格的任务)
http://jenkins-server:8080/job/<job-name>/pipeline-syntax/
2.pipeline语法
2.1 脚本式pipeline语法
脚本式pipeline语法特点: 最外层是"node {}"。
参考案例如下:
node {
stage('Source') {
//
}
stage('Build') {
//
}
stage('Test') {
//
}
stage('Deploy'){
//
}
}
2.2 声明式pipline语法
声明式流水线是在"Pipline plugin"的2.5版本添加到Jenkins流水线的,它在流水线子系统上提供了一种更简单,更有主见的语法。
声明式pipline语法特点: 最外层是"pipeline {}"。
pipline的声明式语法要点:
- steps内部的命令,每一条单独的命令都在当前任务的工作目录下执行。
即使A命令切换到了一个新的目录,接下来的B命令并不会在对应的新目录中执行,而是在当前任务的工作目录下执行。
如果非要在切换后的目录下执行命令B,那么采用shell的"&&"符号将多条命令拼接在一起即可。
- 默认情况下,不支持shell里面的复杂语法,因为groovy有自己的条件表达式。
- 如果Jenkins的工作目录下存在同名目录,则获取失败。
参考案例如下:
pipeline {
agent any
environment{
url='http://www.yinzhengjie.com'
}
stages {
stage('Source'){
steps {
echo "Access ${url}"
}
}
stage('Build'){
steps {
//
}
}
stage('Test'){
steps {
//
}
}
stage('Deploy'){
steps {
//
}
}
}
}
3.基本案例
3.1 脚本式案例
node {
stage('Get code'){
echo '获取代码'
}
stage('Build'){
echo '构建项目代码'
}
stage('Test'){
echo '测试项目功能'
}
stage('Deploy'){
echo '部署项目'
}
}
3.2 声明式案例
pipline {
agent any
statges {
stage('获取代码'){
steps {
echo '获取代码'
}
}
stage('构建代码'){
steps {
echo '构建项目代码'
}
}
stage('代码测试'){
steps {
echo '测试项目功能'
}
}
stage('项目部署'){
steps {
echo '项目部署'
}
}
}
}
三.官方pipeline Job测试样例
1.安装pipeline插件
如上图所示,安装pipeline和pipeline Stage View插件。
如下图所示,插件安装成功啦。
2.创建pipeline Job
如上图所示,创建一个pipeline的Job任务。
3.定义脚本式流水线配置
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
}
}
4.执行Pipeline Job
如上图所示,任务执行结果在阶段视图中一放款的形式显示:
- 一次构建用一行方块来表示,其中每个方块代表流水线中的stage;
- 每个方块都代表了一个特定阶段的一次执行结果;
方块颜色的意义:
- 蓝色条纹:
stage运行中。
- 白色条纹:
stage尚未运行。
- 红色条纹:
stage执行失败。
- 绿色:
stage执行成功。
- 浅红色:
stage执行成功,但是下游的某个stage出现失败。
如下图所示,将鼠标移动到某个方块上方,会弹出"logs",点击后就可以看到对应的日志信息啦。
5.自定义流水线任务测试样例
// 所有的脚本命令都放在pipeline中
pipeline {
// 指定任务构建在哪个Jenkins节点中执行,any表示任意节点均可。
agent any
// 声明全局变量,方便后续使用
environment {
blog = 'https://www.cnblogs.com/yinzhengjie'
videos = 'https://space.bilibili.com/600805398/channel/series'
name = '尹正杰'
title = '杰哥讲运维'
gitee = 'https://gitee.com/jasonyin2020/cloud-computing-stack'
}
// 定义阶段任务列表
stages {
// 定义拉取代码的仓库
stage('项目信息说明'){
// 定义具体的步骤,可以引用上面我们定义的变量
steps {
// 使用sh可以调用我们想要执行的命令,如果直接使用echo,可能变量会原样输出哟~
sh 'echo 项目地址: $gitee, 姓名: $name, B站昵称: $title, b站视频: $vidos, 博客地址: $blog'
}
}
stage('拉取gitee仓库代码'){
steps {
echo '拉取gitee仓库代码成功- Successfully!'
}
}
stage('基于maven构建项目'){
steps {
echo '基于maven编译Java项目- Successfully!'
}
}
stage('基于SonarQube进行代码质量检测'){
steps {
echo '基于SonarQube进行代码质量检测- Successfully!'
}
}
stage('基于Dockerfile构建镜像'){
steps {
echo '基于Dockerfile构建镜像- Successfully!'
}
}
stage('推送镜像到Harbor仓库'){
steps {
echo '推送镜像到Harbor仓库- Successfully!'
}
}
stage('K8S更新deployments资源'){
steps {
echo 'K8S更新deployments资源- Successfully!'
}
}
stage('钉钉机器人告警通知,邮箱记录信息'){
steps {
echo '钉钉机器人告警通知,邮箱记录信息- Successfully!'
}
}
}
}
四.pipeline使用技巧
1.查看pipeline的官方文档
如上图所示,我们可以直接查看官方为我们提供的pipeline语法生成工具。
2.checkout示例步骤
如上图所示,我们选择"checkout: Check out from version control",并填写对应的git信息。
如下图所示,点击按钮就自动生成了pipeline的语法啦~
checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[url: 'https://gitee.com/jasonyin2020/cloud-computing-stack.git']])
3.将示例代码进行克隆测试
// 所有的脚本命令都放在pipeline中
pipeline {
// 指定任务构建在哪个Jenkins节点中执行,any表示任意节点均可。
agent any
// 声明全局变量,方便后续使用
environment {
blog = 'https://www.cnblogs.com/yinzhengjie'
videos = 'https://space.bilibili.com/600805398/channel/series'
name = '尹正杰'
title = '杰哥讲运维'
gitee = 'https://gitee.com/jasonyin2020/cloud-computing-stack'
}
// 定义阶段任务列表
stages {
// 定义拉取代码的仓库
stage('项目信息说明'){
// 定义具体的步骤,可以引用上面我们定义的变量
steps {
// 使用sh可以调用我们想要执行的命令,如果直接使用echo,可能变量会原样输出哟~
sh 'echo 项目地址: $gitee, 姓名: $name, B站昵称: $title, b站视频: $vidos, 博客地址: $blog'
}
}
stage('拉取gitee仓库代码'){
steps {
checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[url: 'https://gitee.com/jasonyin2020/cloud-computing-stack.git']])
}
}
stage('基于maven构建项目'){
steps {
echo '基于maven编译Java项目- Successfully!'
}
}
stage('基于SonarQube进行代码质量检测'){
steps {
echo '基于SonarQube进行代码质量检测- Successfully!'
}
}
stage('基于Dockerfile构建镜像'){
steps {
echo '基于Dockerfile构建镜像- Successfully!'
}
}
stage('推送镜像到Harbor仓库'){
steps {
echo '推送镜像到Harbor仓库- Successfully!'
}
}
stage('K8S更新deployments资源'){
steps {
echo 'K8S更新deployments资源- Successfully!'
}
}
stage('钉钉机器人告警通知,邮箱记录信息'){
steps {
echo '钉钉机器人告警通知,邮箱记录信息- Successfully!'
}
}
}
}
五.Jenkinsfile
1.在gitee项目中添加Jenkinsfile文件
如上图所示,我们可以在项目对应分支中添加Jenkinsfile文件,里面的内容可以是pipeline语法。
2.配置Jenkins设置项目路径
如上图所示,依次添加我们存放Jenkinsfile的代码仓库地址。
如下图所示,我们需要填写Jenkinsfile的文件路径。
3.Jenkins开始编译
如上图所示,我们可以开始编译Jenkins,不难发现编译成功了,在所有项目之前多了一个从SCM中拉取项目的过程。
本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/18621604,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费)
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。