Jenkins Pipeline In Docker - Spr

2022-12-13  本文已影响0人  heichong
  • 上篇文章中,我们安装了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. 准备

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 测试下

image.png

说明部署成功!

上一篇 下一篇

猜你喜欢

热点阅读