zoukankan      html  css  js  c++  java
  • jenkins配合dockerfile部署项目

    前言

    本节需要对jenkinsfile有点了解,对dockerfile有点了解,对shell有点了解,对docker有点了解

    执行流程

    1. jenkins拉取代码仓库中的代码
    2. jenkins执行jenkinsfile文件(可指定文件名)
    3. 先在jenkins所在的服务器将拉取的项目build成docker镜像
    4. 将镜像发布到镜像仓库(我这里是腾讯云配置的私有仓库)
    5. 在应用服务器的节点上将该镜像拉取下来(私有仓库需要用户名/密码)
    6. 在应用服务器上执行该镜像

    一、jenkins配置

    创建一个Pipeline SCM项目 jenkins项目名为springboot-test (和发布的工程名保持一致)

    Definition选择 【Pipeline Script from SCM】

    Branch Specifier(blank for 'any'):选择分支

    Additional Behaviours: 添加邮箱通知的发送者 【这里没有写】

    Script Path: 填写使用项目中的Jenkinsfile文件的名字

    二、应用工程配置

    在工程的根目录下创建Dockerfile文件和Jenkins_docker文件

    jenkinsfile_docker文件内容如下

    // docker集成docker部署
    pipeline {
        agent {label 'master'}
        tools{
            maven 'maven'
        }
    
        environment {
            GIT_PROJECT_ADDR="git@gitee.com:uncleqiao/springboot-test.git" //项目的git地址
            JENKINS_WORKSPACE="/root/.jenkins/workspace"    //jenkins存放文件的地址
            PROJECT_NAME="${JOB_NAME}"  			        // 项目名
            JAR_NAME="springboot-test-0.0.1-SNAPSHOT.jar"   // 项目生成的jar的名字
            IMAGE_NAME="springboot-test"                    // 镜像名一般和项目名相同
            IMAGE_ADDR="ccr.ccs.tencentyun.com/qiao_namespace/${IMAGE_NAME}"    // 镜像的位置
            VERSION_ID="${BUILD_ID}"
        }
        stages {
            stage('pullCode'){
                steps{
                    echo 'This is a pullCode step'
                    //git branch: "${BRANCH}", credentialsId: '1001', url: "${GIT_PROJECT_ADDR}"
                    checkout scm
                }
            }
            stage('Build') {
                steps{
                    echo 'This is a Build step'
                    // 在有Jenkinsfile同一个目录下(项目的根目录下)
                    sh 'mvn clean package -Dmaven.test.skip=true'
                }
            }
            // 创建目录(如果不存在),并把jar文件上传到该目录下
            stage('ssh') {
                steps{
                    echo 'push jar to target server'
                    sh '''
                        ole_image_id=`docker images|grep ${IMAGE_NAME}|grep ${VERSION_ID}|awk '{print $3}'`
                        if [[ -n "${ole_image_id}" ]]; then
                            docker rmi -f ${ole_image_id}
                        fi
                        
                        docker build -f Dockerfile --build-arg jar_name=${JAR_NAME} -t ${IMAGE_NAME}:${VERSION_ID} .
                        
                        new_image_id=`docker images|grep ${IMAGE_NAME}|grep ${VERSION_ID}|awk '{print $3}'`
                        sudo docker tag ${new_image_id} ${IMAGE_ADDR}:${VERSION_ID}
                        sudo docker push ${IMAGE_ADDR}:${VERSION_ID}
                    '''
                }
            }
            stage('run') {
                // 在应用服务器节点 test
                agent {
                    node {
                        label 'test'
                        //customWorkspace "${SERVER_TARGET_PATH}"  //此参数会初始化目录 注意填写
                    }
                }
                options {
                    // 不让它切换到节点上自动从仓库拉取项目
                    skipDefaultCheckout()
                }
                steps {
                    echo 'pull image and docker run'
                    withEnv(['JENKINS_NODE_COOKIE=dontKillMe']) {
                        sh '''
                            sudo docker login --username=yourusername --password=yourpassword ccr.ccs.tencentyun.com
                            sudo docker pull ${IMAGE_ADDR}:${VERSION_ID}
    
                            container_id=`docker ps|grep ${IMAGE_ADDR}:${VERSION_ID}|awk '{print $1}'`
                            if [ -n "${container_id}" ]; then
                            	docker rm -f "${container_id}"
                            fi
                            
                            old_pid=`ps -ef|grep ${JAR_NAME}|grep -v grep|awk '{print $2}'`
                            if [[ -n $old_pid ]]; then
                                kill -9 $old_pid
                            fi
                            
                            old_image=`docker images|grep ${IMAGE_ADDR}|grep ${VERSION_ID}`
                            if [[ -n $old_image ]]; then
                                old_image_id=`echo ${old_image}|awk '{print $3}'`
                                docker rmi -f ${old_image_id}
                            fi
                            
                            sudo docker run --name "${PROJECT_NAME}_${VERSION_ID}" -p 9001:8081 -d ${IMAGE_ADDR}:${VERSION_ID}
                        '''
                    }
                }
            }
        }
    }
    

    注意:

    • if [ -n str ] 这个命令在使用的时候如果str为空,也是true,可以使用 if [ -n ${str} -a "${str}x" != "x" ]或者使用if [[ -n ${str} ]]来判断
    • shell语法中,$()` 和 `` (两个单引号) 可以在子shell中执行命令,但是这儿$()不支持
    • idea没有jenkinsfile的语法提示,很容易出错,这个很难受

    步骤一:拉取项目 在【pullCode】步骤中

    checkout scm , 这个scm是创建jenkins流水线时选择的,属于特殊变量,代表了你的仓库信息,自动从仓库中获取项目

    步骤二: 【Build】

    将拉取下来的项目进行编译并打包
    

    步骤三:【build_image】 将打包好的项目build成docker镜像,然后推送到镜像仓库(这里可以分成两步)

    # 获取已经存在的镜像
    ole_image_id=`docker images|grep ${IMAGE_NAME}|grep ${VERSION_ID}|awk '{print $3}'`
    # 删掉存在的镜像
    if [[ -n "${ole_image_id}" ]]; then
    	docker rmi -f ${ole_image_id}
    fi
    # 通过项目根目录下的Dokcerfile来构建镜像 -f filename --build-arg <key=value> 给Dockerfile传递参数
    # -t 镜像的名称:版本  这里我将jenkins的构建次数当作镜像的版本
    docker build -f Dockerfile --build-arg jar_name=${JAR_NAME} -t ${IMAGE_NAME}:${VERSION_ID} .
    
    # 获取构建好的镜像的id
    new_image_id=`docker images|grep ${IMAGE_NAME}|grep ${VERSION_ID}|awk '{print $3}'`
    
    # 根据生成的镜像,tag出一个名称空间不同的镜像(腾讯云能识别的镜像)
    sudo docker tag ${new_image_id} ccr.ccs.tencentyun.com/qiao_namespace/${IMAGE_NAME}:${VERSION_ID}
    
    # 将镜像仓库能够试别的镜像推送到仓库
    sudo docker push ccr.ccs.tencentyun.com/qiao_namespace/${IMAGE_NAME}:${VERSION_ID}
    

    步骤四:【run】应用服务器拉取项目并且运行, 这一步要选择节点(应用服务器,如果是集群,就不用节点用scp登陆吧)

    # 登陆到镜像仓库
    sudo docker login --username=yourusername --password=yourpassword ccr.ccs.tencentyun.com
    # 从仓库中拉取刚才生成的镜像
    sudo docker pull ccr.ccs.tencentyun.com/qiao_namespace/${IMAGE_NAME}:${VERSION_ID}
    
    # 查看已经存在的容器, 存在则删掉  存在则删掉 这里应该是一个数组,有点小问题,待修改
    container_id=`docker ps|grep ${IMAGE_ADDR}:${VERSION_ID}|awk '{print $1}'`
    if [ -n "${container_id}" ]; then
    	docker rm -f "${container_id}"
    fi
    # 查看已经运行的同版本的项目, 存在则删掉 这里应该是一个数组,有点小问题,待修改
    pid=`ps -ef|grep ${JAR_NAME}|grep -v grep|awk '{print $2}'`
    if [[ -n $pid ]]; then
    	kill -9 $pid
    fi
    # 查看已经存在的镜像, 存在则删掉 这里应该是一个数组,有点小问题,待修改
    old_image=`docker images|grep ${IMAGE_ADDR}|grep ${VERSION_ID}`
    if [[ -n $old_image ]]; then
    	old_image_id=`echo ${old_image}|awk '{print $3}'`
        docker rmi -f ${old_image_id}
    fi
    # 运行容器
    sudo docker run --name "${PROJECT_NAME}_${VERSION_ID}" -p 9001:8081 -d ${IMAGE_ADDR}:${VERSION_ID}
    

    Dockerfile

    文件内容如下

    FROM ccr.ccs.tencentyun.com/qiao_namespace/myjdk8:v1
    
    # 默认jar包的名字 注意分隔符为 :-  这里是由jenkinsfile中build dockerfile时传递过来的
    ARG jar_name={jar_name:-springboot-test-0.0.1-SNAPSHOT.jar}
    
    # RUN 用于容器内部执行命令
    RUN mkdir -p /usr/local/project
    WORKDIR /usr/local/project
    
    
    # 将项目放到/usr/local/project下
    COPY ./target/springboot-test-0.0.1-SNAPSHOT.jar ./
    
    EXPOSE 8081
    
    CMD java -jar -Dserver.port=8081 springboot-test-0.0.1-SNAPSHOT.jar
    

    执行完毕后我们登陆到应用服务器

    看到容器已经启动,docker exec 进入到容器看到文件是存在的

  • 相关阅读:
    Security headers quick reference Learn more about headers that can keep your site safe and quickly look up the most important details.
    Missing dollar riddle
    Where Did the Other Dollar Go, Jeff?
    proteus 与 keil 联调
    cisco router nat
    router dhcp and dns listen
    配置802.1x在交换机的端口验证设置
    ASAv931安装&初始化及ASDM管理
    S5700与Cisco ACS做802.1x认证
    playwright
  • 原文地址:https://www.cnblogs.com/qiaozhuangshi/p/11762330.html
Copyright © 2011-2022 走看看