一、什么是pipeline?
Pipeline,简而言之,就是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排与可视化;
Pipeline 是Jenkins 2.X 的最核心的特性,帮助Jenkins 实现从CI 到 CD 与 DevOps的转变。
Pipeline 是一组插件,让jenkins 可以实现持续交付管道的落地和实施。持续交付管道是将软件从版本控制阶段到交付给用户/客户的完整过程的自动化表现。
二、pipeline的概念
Pipeline 是一个用户定义的 CD 流水线模式。Pipeline 代码定义了通常包含构建、测试和发布步骤的完
整的构建过程。
三、Pipeline任务
3.1、创建Pipeline任务
新增任务,选择pipeline(流水线)
#Pipeline定义有两种方式:
一种是Pipeline Script ,是直接把脚本内容写到脚本对话框中;
另一种是 Pipeline script from SCM (Source Control Management–源代码控制管理,即从gitlab/github/git上获得pipeline脚本–JenkisFile)
3.2 、流水线语法
脚本式语法格式:
pipeline{
agent any
stages{
stage("get code"){
steps{
echo "get code from scm"
}
}
stage("package"){
steps{
echo "packge code"
}
}
}
}
----------------------------------------------------------------------------------------------------
#解读
pipeline: 这是Pipeline脚本的开始,表示你正在定义一个Jenkins Pipeline。
agent any: 这是在Pipeline中定义的一个指令,它指定了运行Pipeline的代理(节点)。any 表示可以在任何可用的代理节点上运行。
stages: 在Jenkins Pipeline中,工作流被组织为一个或多个阶段(stages),每个阶段代表一个特定的构建或部署步骤。
stage("get code"): 这是定义一个名为 "get code" 的阶段。这个阶段将用来获取代码。
steps: 在阶段内部,你可以定义一个或多个步骤(steps),每个步骤执行特定的操作。
echo "get code from scm": 这是一个步骤,它使用 echo 命令在控制台输出文本。在这个例子中,输出的文本是 "get code from scm",表示从源代码管理系统(SCM)获取代码。
3.3、配置Gitlab地址
脚本代码:
pipeline{
agent any
stages{
stage("下拉代码"){
steps{
git 'git@gitlab.driverzeng.com:root/hello.git'
}
}
stage("代码质量检测"){
steps{
sh '''/usr/lib/maven/bin/mvn clean verify sonar:sonar \\
-Dsonar.projectKey=java \\
-Dsonar.projectName=\'java\' \\
-Dsonar.host.url=http://10.0.0.83:9000 \\
-Dsonar.token=squ_abd87057be010b87265b82779d9342234f3d2065'''
}
}
stage("构建"){
steps{
sh '/usr/lib/maven/bin/mvn clean package'
}
}
stage("推送代码"){
steps{
sh 'scp ${WORKSPACE}/target/hello-world-war-6.0.0.war root@172.16.1.7:/hello-version'
}
}
stage("远端解压代码"){
steps{
sh 'ssh root@172.16.1.7 "unzip -n /hello-version/hello-world-war-6.0.0.war -d /hello-version/hello-world-war-6.0.0"'
}
}
stage("部署代码"){
steps{
sh 'ssh root@172.16.1.7 "rm -f /usr/share/tomcat/webapps/ROOT && ln -s /hello-version/hello-world-war-6.0.0 /usr/share/tomcat/webapps/ROOT "'
}
}
stage("重启服务"){
steps{
sh 'ssh root@172.16.1.7 systemctl restart tomcat'
}
}
}
}
脚本中定义了7个阶段(stage)
运行任务,可以看到分为7个部分,如下图所示:
四、Pipeline script from SCM 通过代码库运行任务
将pipeline代码(Jenkinsfile)保存到代码库中,然后通过指定代码位置(脚本位置)的方式来运行pipeline任务。
1、创建Jenkinsfile,由Groovy语言实现。一般是存放在项目根目录,随项目一起受源代码管理软件控制。
4.1、准备工作
首先,确保你的 Jenkins 服务器已经搭建好并且可以正常访问。如果你还没搭建 Jenkins服务器,可以参考 官方文档 进行安装
4.2、第一步:创建 JenkinsFile 集中存放仓库
在这个步骤中,我们将创建一个 Git 仓库,用于集中存放所有项目的 JenkinsFile 文件。你可以把这个仓库当成 JenkinsFile 的乐园,各个JenkinsFile 在这里自由地玩耍和交流。
# 创建一个名为 "jenkinsfile" 的仓库
[root@gitlab jenkins-pipelinefile]# git init .
Initialized empty Git repository in /jenkins-pipelinefile/.git/
[root@gitlab jenkins-pipelinefile]# git config --global user.name "Administrator"
[root@gitlab jenkins-pipelinefile]# git config --global user.email "admin@example.com"
[root@gitlab jenkins-pipelinefile]# git remote add origin git@gitlab.driverzeng.com:root/pipeline-file.git
# 创建一个 README.md 文件,简要介绍项目
echo "# Jenkinsfile Collection" > README.md
#创建代码
git add README.md
git commit -m "Initial commit"
4.3、第二步:将各项目 JenkinsFile 放入集中仓库
在这个步骤中,我们将把各个项目的 JenkinsFile 文件放入集中仓库的对应子目录中。这就像把孩子们接到幼儿园,每个孩子有自己的小房间和小床。
假设我们有1个项目:project-a 别有名为:Jenkinsfile-a JenkinsFile 文件。
# 在集中仓库中为每个项目创建子目录
[root@gitlab jenkins-pipelinefile]# mkdir java-maven_pipelin
# 将项目的 JenkinsFile 文件复制到对应子目录/也可另行创建
[root@gitlab jenkins-pipelinefile]# vim java-maven_pipelin/jenkinsline
pipeline {
agent any
stages {
stage("下拉代码") {
steps {
git 'git@gitlab.driverzeng.com:root/hello.git'
}
}
stage("代码质量检测") {
steps {
script {
sh '/usr/lib/maven/bin/mvn clean verify sonar:sonar ' +
'-Dsonar.projectKey=java ' +
'-Dsonar.projectName=\'java\' ' +
'-Dsonar.host.url=http://10.0.0.83:9000 ' +
'-Dsonar.token=squ_abd87057be010b87265b82779d9342234f3d2065'
}
}
}
stage("构建") {
steps {
sh '/usr/lib/maven/bin/mvn clean package'
}
}
stage("推送代码") {
steps {
sh 'scp ${WORKSPACE}/target/hello-world-war-6.0.0.war root@172.16.1.7:/hello-version'
}
}
stage("远端解压代码") {
steps {
sh 'ssh root@172.16.1.7 "unzip -n /hello-version/hello-world-war-6.0.0.war -d /hello-version/hello-world-war-6.0.0"'
}
}
stage("部署代码") {
steps {
sh 'ssh root@172.16.1.7 "rm -f /usr/share/tomcat/webapps/ROOT && ln -s /hello-version/hello-world-war-6.0.0 /usr/share/tomcat/webapps/ROOT "'
}
}
stage("重启服务") {
steps {
sh 'ssh root@172.16.1.7 systemctl restart tomcat'
}
}
}
}
# 将更改提交到 Git 仓库
[root@gitlab jenkins-pipelinefile]# git add .
[root@gitlab jenkins-pipelinefile]# git commit -m 'pipelinev1.0'
[master c0cc8b3] pipelinev1.0
1 file changed, 47 insertions(+)
create mode 100644 java-maven_pipeline/jenkinsline
[root@gitlab jenkins-pipelinefile]# git tag -a 'v1.0' -m 'v1.0'
[root@gitlab jenkins-pipelinefile]# git push --all
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 871 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To git@gitlab.driverzeng.com:root/pipeline-file.git
e20f7a0..c0cc8b3 master -> master
[root@gitlab jenkins-pipelinefile]# git push --tag
Counting objects: 1, done.
Writing objects: 100% (1/1), 155 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@gitlab.driverzeng.com:root/pipeline-file.git
* [new tag] v1.0 -> v1.0
注意:确保每个 JenkinsFile 文件内有正确的构建、测试和发布流程
4.4、第三步:在 Jenkins 中创建 Pipeline 项目
接下来,我们需要在 Jenkins 服务器上创建一个新的 Pipeline 项目,用于驱动集中仓库中的 JenkinsFile
文件执行。这就像请了一个老师来管理这个幼儿园,负责每天的课程和活动。
- 登录到 Jenkins 服务器,点击左侧的 “New Item”。
- 输入项目名称,例如 “java-构建-pipeline”,选择 “Pipeline” 类型,然后点击 “OK”。
- 在项目配置页面的 Pipeline 部分,选择 “Pipeline script from SCM” 选项,并填写 “jenkinsfile-collection” 项目的仓库地址。
4.5、构建测试
五、pipeline参数化构建
5.1、参数添加
5.2、脚本编写
获取Git仓库路径:
代码如下:
pipeline{
agent any
stages{
stage("下拉代码"){
steps{
checkout([$class: 'GitSCM', branches: [[name: "${gittag}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'git@gitlab.driverzeng.com:root/hello.git']]])
}
}
stage("代码质量检测"){
steps{
sh '''/usr/lib/maven/bin/mvn clean verify sonar:sonar \\
-Dsonar.projectKey=java \\
-Dsonar.projectName='java' \\
-Dsonar.host.url=http://10.0.0.83:9000 \\
-Dsonar.token=squ_abd87057be010b87265b82779d9342234f3d2065'''
}
}
stage("构建"){
input {
message "是否继续构建?"
ok "构建"
}
steps{
sh '/usr/bin/sh -x /var/lib/jenkins/scripts/pipeline.sh'
}
}
}
}
脚本内容:
[root@jenkins scripts]# vim /var/lib/jenkins/scripts/pipeline.sh
#!/bin/bash
#-----------------------------变量定义-------------------
#版本号
version=$(awk -F '[<> ]' 'NR==6{print $3}' ${WORKSPACE}/pom.xml)
#历史版本目录
his='/hello-version'
#测试:user ip
test_user=root
test_ip=172.16.1.7
#开发:user ip
dev_user=root
dev_ip=172.16.1.8
#生产:user ip
pord_user=root
pord_ip=172.16.1.9
#-----------------------------函数定义---------------------
pull(){
# 检查解压后的目录是否存在同名文件
file_exists=$(ssh $1 "ls ${his}/hello-world-war-${version}")
if [ -z "$file_exists" ]; then
#文件不存在进入workspacemul 推送至下拉机器
scp ${WORKSPACE}/target/hello-world-war-${version}.war $1:${his}
#远端解压
ssh $1 "unzip -n ${his}/hello-world-war-${version}.war -d ${his}/hello-world-war-${version}"
sleep 5
ssh $1 "rm -f /usr/share/tomcat/webapps/ROOT"
ssh $1 "ln -s ${his}/hello-world-war-${version} /usr/share/tomcat/webapps/ROOT"
ssh $1 "systemctl restart tomcat"
else
#跳过解压操作
sleep 5
ssh $1 "rm -f /usr/share/tomcat/webapps/ROOT"
ssh $1 "ln -s ${his}/hello-world-war-${version} /usr/share/tomcat/webapps/ROOT"
ssh $1 "systemctl restart tomcat"
fi
}
#-----------------------------代码运行----------------------
if [[ $env == test ]]; then
pull ${test_user}@${test_ip}
elif [[ $env == dev ]]; then
pull ${dev_user}@${dev_ip}
elif [[ $env == pord ]]; then
pull ${pord_user}@${pord_ip}
else
exit
fi