- 上篇文章中,我们安装了jenkins,也编写了一个pipeline任务进行了测试。
pipeline任务默认在jenkins所在主机上执行的pipeline任务(agent:any),实际使用时将会导致jenkins主机要安装很多build相关的软件,以springboot项目为了,需要安装git、maven、jdk等,如果项目使用了多个JDK版本,还需要安装多个JDK。- 这将会导致编译环境非常复杂,是否有一种方案,不同类型的项目使用不通的编译环境,互不干扰?编译springboot时,只有springboot相关的环境;编译VUE时,只有VUE相关的环境
有,那就是pipeline in docker!
即不通类型的项目,对应不同的docker镜像,把pipeline的任务脚本放在docker镜像内执行。
1. 准备
- 安装jenkins环境,可以参考:https://www.jianshu.com/p/b92eb10cacf2
- 准备springboot项目需要的镜像
springboot需要安装git、maven、jdk,maven官方已经提供了对应的镜像,拿来即可使用
docker pull maven:3.8.2-openjdk-8
更多maven镜像,可参考 https://hub.docker.com/_/maven/tags
注意:docker 18.xx版本的,使用此镜像会报错,请升级到docker 20.xx版本
2. 创建一个springboot项目
我们创建了一个简单的springboot项目,只提供一个hello接口做测试,并把此项目上传到gitlab上的dev分支
package com.example.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@GetMapping("/hello")
public String hello(){
return "Hello World" ;
}
}
3. jenkins中创建job并编写pipeline
def createVersion() {
// 版本号
return new Date().format('yyyyMMddHHmmss') + "_${env.BUILD_ID}"
}
pipeline {
options {
timeout(time: 1, unit: 'MINUTES')
}
agent {
// pipeline任务都在此docker容器内执行
docker {
image 'maven:3.8.2-openjdk-8'
args '-v $HOME/.m2:/root/.m2'
}
}
environment {
// 自定义版本号
_APP_VERSION=createVersion()
// 服务器登录凭证
_APPSERVER_CREDS=credentials('dev_root')
}
stages {
stage('Git pull') {
steps {
echo '开始拉取代码 ..'
checkout([$class: 'GitSCM', branches: [[name: '*/dev']], extensions: [], userRemoteConfigs: [[credentialsId: '67f1f5b0-d6fb-40fa-9799-4a6dbc85a328', url: 'https://gitlab.****.com.cn/****/test.git']]])
echo '代码拉取成功'
}
}
stage('Test') {
steps {
echo 'Testing..'
}
}
stage('Build Project') {
steps {
echo '开始编译代码..'
sh "mvn --version"
sh "mvn clean package -D maven.test.skip=true"
sh "ls ./target/"
echo '代码编译成功'
}
}
stage('Deploy') {
steps {
echo 'Deploying....'
script {
// SSH Pipeline Steps plugin
def remoteServer = [:]
remoteServer.name = 'test'
remoteServer.host = '10.3.23.191'
remoteServer.allowAnyHosts = true
remoteServer.user = "${_APPSERVER_CREDS_USR}"
remoteServer.password = "${_APPSERVER_CREDS_PSW}"
echo '把target下的jar包复制到目标服务器内'
sh 'mv ./target/*.jar ./target/test_${_APP_VERSION}.jar'
sh 'ls -al ./target/'
sshPut remote: remoteServer, from: "./target/test_${_APP_VERSION}.jar", into: "/root/"
echo '开始删除已运行的jar'
sshCommand remote: remoteServer, command: """
PROCESS=`ps -ef|grep /root/test_ |grep -v grep|awk '{print \$2}'`
if [[ -n \$PROCESS ]];
then
echo "test running... start kill..."
kill -15 `ps -ef|grep /root/test_ |grep -v grep|awk '{print \$2}'`
else
echo "test not running"
fi
"""
echo '运行jar'
sshCommand remote: remoteServer, command: """
nohup java -jar /root/test_${_APP_VERSION}.jar >/dev/null 2>&1 &
"""
}
}
}
}
post {
always {
// 清理工作区
cleanWs()
}
}
}
其中1:
agent {
// pipeline任务都在此docker容器内执行
docker {
image 'maven:3.8.2-openjdk-8'
args '-v $HOME/.m2:/root/.m2'
}
}
- 代表pipeline在docker镜像内执行,
image
为镜像名称,最好提前通过pull命令下载好镜像;args
为镜像启动时的参数,这里目的是为了maven下载的依赖jar包保留在宿主机上,这样下次编译时就不需要重复下载依赖包了
其中2:
_APPSERVER_CREDS=credentials('dev_root')
......
remoteServer.user = "${_APPSERVER_CREDS_USR}"
remoteServer.password = "${_APPSERVER_CREDS_PSW}"
......
- 这里是在引用jenkins中定义的用户名密码,
dev_root
必须要对应jenkins创建凭据的唯一标识
image.png_APPSERVER_CREDS
我们可以自定义任何名字,他对应的账号和密码则是在这个名字上加上_USR
、_PSW
后缀
其中3:
echo '开始拉取代码 ..'
checkout([$class: 'GitSCM', branches: [[name: '*/dev']], extensions: [], userRemoteConfigs: [[credentialsId: '67f1f5b0-****-40fa-9799-4a6dbc85a328', url: 'https://gitlab.****.com.cn/****/test.git']]])
echo '代码拉取成功'
name: '*/dev'
代表要拉取dev分支
credentialsId: '67f1f5b0-****-40fa-9799-4a6dbc85a328'
标识使用jenkins中哪个用户凭证信息来访问gitlab(同上面的dev_root)
4. 执行pipeline
点击【立即构建】按钮,我们先去jenkins宿主机上查看是否启动了maven容器:
image.png
可以看到,maven:3.8.2-openjdk-8容器已经启动了
稍微一会:
image.png
可以看到pipeline执行成功,我们可以访问http://10.3.23.191:9999/hello 测试下
说明部署成功!
网友评论