随着Jenkins2的推广,Jenkinsfile的使用愈加地广泛,这篇文章介绍一下Jenkinsfile最基础的Stage的使用示例。
Jenkinsfile的实践场景:
在DevOps实践中,经常会提及的一个概念是是“IaaS”,我们进行持续集成和部署,最终的实现很有可能是Jenkins上的一个Job,有可能是FreeStyle的和有可能是其他形式的,通过插件或其他方式我们打通了Jenkins和其他组件,可以使得用户在Jenkins上通过使用Gitlab拉取分支代码,使用Maven进行构建,将结果上传至二进制私库Nexus上,使用SonarQube进行代码扫描,通过Docker进行镜像生成,将镜像推送至Harbor镜像私库上,使用Ansible进行服务部署等常见操作。
而这些操作大部分都是共通的,而不同的大多是这些组件工具的URL和用户名/密码或者Token有所不同,而Jenkins的打通过程,传统方式往往以手工方式为主,持续集成和持续交付本身是为了带来效率的,这个打通的过程自身一旦稳定往往并不像应用程序变更那样频繁,但是作为软件开发生命周期不可获取的一个环节,这些流水线手工设定的过程也应该以代码的形式保存起来,这样才能保证持续集成环境的一致性和可扩展性。而Jenkinsfile就是将持续集成和持续交付流水线以代码形式进行保存的一种方式。
本文示例:
将流水线分按照功能分为逻辑上的三段:构建(Build) 、测试(Test)、部署(Deploy),顺序如下所示。
这里使用Easypack的Jenkins 2.176.1来创建验证用的Jenkins环境。使用如下步骤即可完成。
事前准备docker和docker-compose,版本要求如下所示:
liumiaocn:~ liumiao$ docker version
Client:
Version: 18.03.1-ce
API version: 1.37
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:13:02 2018
OS/Arch: darwin/amd64
Experimental: false
Orchestrator: swarm
Server:
Engine:
Version: 18.03.1-ce
API version: 1.37 (minimum version 1.12)
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:22:38 2018
OS/Arch: linux/amd64
Experimental: true
liumiaocn:~ liumiao$
liumiaocn:~ liumiao$ docker-compose --version
docker-compose version 1.21.1, build 5a3f1a3
liumiaocn:~ liumiao$
使用Easypack中准备好的LTS的Jenkins镜像,启动Jenkins。
命令:git clone https://github.com/liumiaocn/easypack.git
命令:
cd easypack/containers/alpine/jenkins
docker-compose up -d
liumiaocn:jenkins liumiao$ cat docker-compose.yml
version: '2'
services:
# jenkins service based on Jenkins LTS version
jenkins:
image: liumiaocn/jenkins:2.176.1
ports:
- "32002:8080"
- "50000:50000"
environment:
- JENKINS_ADMIN_ID=root
- JENKINS_ADMIN_PW=liumiaocn
- JENKINS_MODE=master
volumes:
- ./data/:/data/jenkins
restart: "no"
liumiaocn:jenkins liumiao$
liumiaocn:jenkins liumiao$ docker-compose up -d
Creating network "jenkins_default" with the default driver
Creating jenkins_jenkins_1 ... done
liumiaocn:jenkins liumiao$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------------------------------
jenkins_jenkins_1 /bin/tini -- /usr/local/bi ... Up 0.0.0.0:50000->50000/tcp, 0.0.0.0:32002->8080/tcp
liumiaocn:jenkins liumiao$
使用如下示例代码获取Jenkins-Crumb,为使用API方式生成三个Stage的Pipeline示例作准备。
liumiaocn:jenkins liumiao$ jenkins_host_url=http://localhost:32002
liumiaocn:jenkins liumiao$ user_passwd="root:liumiaocn"
liumiaocn:jenkins liumiao$ jenkins_crumb=`curl -u $user_passwd ${jenkins_host_url}'/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)' 2>/dev/null`
liumiaocn:jenkins liumiao$ echo $jenkins_crumb
Jenkins-Crumb:83d748ee92512c4dccd589aaa5c55a9a
liumiaocn:jenkins liumiao$
使用如下代码示例创建Job
liumiaocn:jenkins liumiao$ ls demo/pipeline/stage/config.xml
demo/pipeline/stage/config.xml
liumiaocn:jenkins liumiao$ cat demo/pipeline/stage/config.xml
<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job@2.32">
<actions>
<org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobAction plugin="pipeline-model-definition@1.3.8"/>
</actions>
<description>Pipeline Job Sample</description>
<keepDependencies>false</keepDependencies>
<properties>
<hudson.plugins.jira.JiraProjectProperty plugin="jira@3.0.7"/>
<com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty plugin="gitlab-plugin@1.5.12">
<gitLabConnection></gitLabConnection>
</com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty>
</properties>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@2.69">
<script>pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'echo Build stage ...'
}
}
stage('Test'){
steps {
sh 'echo Test stage ...'
}
}
stage('Deploy') {
steps {
sh 'echo Deploy stage ...'
}
}
}
}</script>
<sandbox>false</sandbox>
</definition>
<triggers/>
<disabled>false</disabled>
</flow-definition>
liumiaocn:jenkins liumiao$ curl -X POST -u $user_passwd -H ${jenkins_crumb} -H "Content-Type:application/xml" --data-binary "@demo/pipeline/stage/config.xml" ${jenkins_host_url}/createItem?name=pipeline_job_noparam
liumiaocn:jenkins liumiao$ echo $?
0
liumiaocn:jenkins liumiao$
本文示例所使用的Jenkinsfile信息如下所示,内容非常简单易读,简单说明如下:
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'echo Build stage ...'
}
}
stage('Test'){
steps {
sh 'echo Test stage ...'
}
}
stage('Deploy') {
steps {
sh 'echo Deploy stage ...'
}
}
}
}
使用如下命令或者直接在Jenkins上点击构建
liumiaocn:jenkins liumiao$ curl -X POST -u $user_passwd -H ${jenkins_crumb} ${jenkins_host_url}/job/pipeline_job_noparam/build
liumiaocn:jenkins liumiao$ echo $?
0
liumiaocn:jenkins liumiao$
使用如下命令可以确认相关的执行日志信息
liumiaocn:jenkins liumiao$ curl -u $user_passwd ${jenkins_host_url}/job/pipeline_job_noparam/1/consoleText
Started by user root
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /data/jenkins/workspace/pipeline_job_noparam
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Build)
[Pipeline] sh
+ echo Build stage ...
Build stage ...
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] sh
+ echo Test stage ...
Test stage ...
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Deploy)
[Pipeline] sh
+ echo Deploy stage ...
Deploy stage ...
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
liumiaocn:jenkins liumiao$
同时也可以通过Jenkins的BlueOcean插件(Easypack集成)来确认,可以更为清晰地进行可视化结果的展示。
除了在Jenkins中直接使用Jenkinsfile,还可以结合SCM进行管理,简单来说,Jenkinsfile在Gitlab等SCM上进行管理,Jenkins与SCM进行关联来获取生成Job的流水线。详细可参看:
在Jenkins中使用Jenkinsfile可以通过API方式,Jenkinsfile支持Groovy语法,写起来非常方便,非常适合“流水线即代码”的实践思路的落地。