Jenkins

时间:2022-05-29 01:29:44

一、Jenkins的安装

1、首先在服务器安装好Docker

安装Docker参考:https://blog.51cto.com/u_15410237/6066776

2、在Docker中运行Jenkins

docker run  -u root -d -p 8080:8080  -p 50000:50000 -v jenkins-data:/var/jenkins_home -v /etc/localtime:/etc/localtime:ro -v /var/run/docker.sock:/var/run/docker.sock --restart=always  jenkinsci/blueocean

-v jenkins-data:/var/jenkins_home:jenkins的家目录以匿名卷的方式挂载到宿主机 -v /etc/localtime:/etc/localtime:ro:宿主机和容器的时间显示一致 -v /var/run/docker.sock:/var/run/docker.sock:宿主机的/var/run/docker.sock被映射到了容器内,有以下两个作用: 1、在容器内只要向/var/run/docker.sock发送http请求就能和Docker Daemon通信了 2、如果容器内有docker文件,那么在容器内执行docker ps、docker port这些命令,和在宿主机上执行的效果是一样的,因为容器内和宿主机上的docker文件虽然不同,但是他们的请求发往的是同一个Docker Daemon --restart=always:开机时启动

3、访问jenkins界面

当首次访问新的Jenkins实例时,系统会要求使用自动生成的密码

访问地址:http://localhost:8080 localhost为服务地址

Jenkins

查看容器日志:docker logs 容器ID

Jenkins

  • 安装推荐的插件

Jenkins

JenkinsJenkins

先退出一下,再登录进去,会避免很多小bug

二、Jenkins实战

准备一个git项目进行测试

1、在IDEA创建一个项目

JenkinsJenkinsJenkins

2、在IDEA安装gitee插件

JenkinsJenkins

3、在gitee创建仓库

注册并登录:https://gitee.com/ JenkinsJenkins

4、创建本地git仓库(如果没有装gitee插件)

项目交给git管理 JenkinsJenkins出现commit表示设置git管理成功 Jenkins

git提交时忽略的文件设置 Jenkins

5、推送代码

JenkinsJenkinsJenkins

设置提交代码和拉取代码的地址,地址从步骤3获取

JenkinsJenkinsJenkinsJenkins

6、开发项目基本功能,并在项目中创建一个Jenkinsfile文件

在jenkins里面创建一个项目 JenkinsJenkinsJenkins

在项目里面创建一个Jenkinsfile文件 Jenkins的基础语法框架如下

//流水线有两种形式:声明式、脚本式
//声明式
pipeline{
//全部的CICD流程都需要在这里定义
    //任何一个代理可用就可以执行流水线
    agent any
    //定义一些环境信息

    //定义流水线的加工流程
    stages {
    //流水线的所有阶段
    //根据git地址拉取代码
    //1、编译代码
    stage('编译') {
                steps {
                 echo "编译"
                }
            }
    //2、测试代码
     stage('测试') {
                steps {
                    //
                    echo "测试"
                }
            }

    //3、打包代码
    stage('打包') {
                    steps {
                        //
                         echo "打包"
                    }
                }

       //4、部署代码
         stage('部署') {
                         steps {
                             //
                             echo "部署"
                         }
                     }
    }

}

提交代码后,我们来到Jenkins Jenkins选择Blue Ocean后选择自己的项目,选择运行后即可构建,出现绿色的则表示构建成功 Jenkins此时,提交代码后还需要手动构建,我们期望的效果是: 远程的github代码提交了,jenkins流水线自动触发构建。

Jenkins

配置构建触发器

JenkinsJenkins

Jenkins配置一个新用户

JenkinsJenkinsJenkinsJenkinsJenkins

配置gitee中的webhoots的URL URL组成http://新创建的用户名:新用户生成的token@服务ip:jenkins端口号/项目构建触发器中提示的地址

JenkinsJenkins

配置完成后保存,回到jenkinns后,我们已经发现项目被重新构建,此时,已经可以实现IDEA向git提交代码后,jenkins就开始构建。

Jenkins

7、Jenkins的工作流程

我们准备一个web项目来打包,Jenkins文件如下

//流水线有两种形式:声明式、脚本式
//声明式
pipeline{
//全部的CICD流程都需要在这里定义
    //任何一个代理可用就可以执行流水线
    agent any
    //定义一些环境信息

    //定义流水线的加工流程
    stages {
    //流水线的所有阶段
    //根据git地址拉取代码
    //1、编译代码
    stage('编译') {
    //执行docker命令的前提是Jenkins安装docker、docker pipeline插件
    //Jenkins原本不支持maven命令,加上自定义代理基础镜像,才可以支持maven命令
    agent{
    docker 'maven:3-alpine'
    }
                steps {
                    //可以定义要做的所有事情
                    //查看当前目录,在干什么
                    sh 'pwd && ls -alh'
                    sh 'printenv'
                    //检测maven命令是否可以执行
                    sh 'mvn -version'
                    //跳过单元测试打包。-Dmaven.test.skip=true:跳过单元测试
                    //运行mvn clean package时默认是从maven*仓库下载
                    sh 'mvn clean package -Dmaven.test.skip=true'

                }
            }
    //2、生成镜像
    stage('生成镜像') {
                    steps {
                        //
                         echo "生成镜像"
                         //检测docker命令是否可以正常运行
                         sh 'docker version'
                         sh 'pwd && ls -alh'
                    }
                }

       //4、部署代码
         stage('部署') {
                         steps {
                             //
                             echo "部署"
                         }
                     }
    }
}

自动部署后,我们发现下载Maven依赖是从maven*仓库下载的,下载速度非常慢

Jenkins

我们把平常配置的setting.xml文件挂载到宿主机,工作原理图如下

JenkinsJenkins

  • 首先,我们进到找到Jenkins的家目录,进到家目录下面 :docker inspect 容器ID ,查询到挂载在宿主机的Jenkins家目录为:/var/lib/docker/volumes/jenkins-data/_data

Jenkins

  • 然后在家目录下创建appconfig目录,来放所有jenkins构建时需要的配置文件,由于在此处,我们需要的是maven的配置文件,我们再在appconfig目录下创建一个maven目录,把setting.xml文件放到此目录下,配置阿里云加速器
<?xml version="1.0" encoding="UTF-8"?>
<settings
    xmlns="http://maven.apache.org/SETTINGS/1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

    <!-- localRepository

   | The path to the local repository maven will use to store artifacts.

   |

   | Default: ${user.home}/.m2/repository

  <localRepository>H:\Devsoft\apache-maven-3.6.1\repository</localRepository>

用户目录下的.m2是所有jar包的地方; maven容器内jar包的位置

  -->
    <localRepository>/root/.m2</localRepository>
    <pluginGroups></pluginGroups>
    <proxies></proxies>
    <servers></servers>
    <mirrors>
        <mirror>
            <id>nexus-aliyun</id>
            <mirrorOf>central</mirrorOf>
            <name>Nexus aliyun</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
        </mirror>
    </mirrors>
    <profiles>
        <profile>
            <id>jdk-1.8</id>
            <activation>
                <activeByDefault>true</activeByDefault>
                <jdk>1.8</jdk>
            </activation>
            <properties>
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
                <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
            </properties>
        </profile>
    </profiles>
</settings>
  • 在Jenkinsfile文件中用-s指定要用的settings.xml文件

打包 Jenkinsfile

//流水线有两种形式:声明式、脚本式
//声明式
pipeline{
//全部的CICD流程都需要在这里定义
    //任何一个代理可用就可以执行流水线
    agent any
    //定义一些环境信息

    //定义流水线的加工流程
    stages {
    //流水线的所有阶段
    //根据git地址拉取代码
    //1、编译代码
    stage('编译') {
    //执行docker命令的前提是Jenkins安装docker、docker pipeline插件
    //Jenkins原本不支持maven命令,加上自定义代理基础镜像,才可以支持maven命令
    agent{
    docker 'maven:3-eclipse-temurin-8-alpine'
    }
                steps {
                    //可以定义要做的所有事情
                    //查看当前目录,在干什么
                    sh 'pwd && ls -alh'
                    sh 'printenv'
                    //检测maven命令是否可以执行
                    sh 'mvn -version'
                    //跳过单元测试打包。-Dmaven.test.skip=true:跳过单元测试
                    //运行mvn clean package时默认是从maven*仓库下载
                    //-s /var/jenkins_home :指定settings.xml文件的位置, /var/jenkins_home/appconfig/maven/settings.xml 是容器里面的路径,在指定的settings.xml文件中配置阿里云加速下载
                    sh 'mvn clean package  -s "/var/jenkins_home/appconfig/maven/settings.xml"  -Dmaven.test.skip=true '

                }
            }
    //2、生成镜像
    stage('生成镜像') {
                    steps {
                        //
                         echo "生成镜像"
                         //检测docker命令是否可以正常运行
                         sh 'docker version'
                         sh 'pwd && ls -alh'
                    }
                }

       //4、部署代码
         stage('部署') {
                         steps {
                             //
                             echo "部署"
                         }
                     }
    }

}

Jenkins

  • 此时还存在一个问题,就是每次构建都会重新下载maven依赖,我们在代理里面加一个maven的映射仓库,映射到宿主机 Jenkinsfile
//流水线有两种形式:声明式、脚本式
//声明式
pipeline{
//全部的CICD流程都需要在这里定义
    //任何一个代理可用就可以执行流水线
    agent any
    //定义一些环境信息

    //定义流水线的加工流程
    stages {
    //流水线的所有阶段
    //根据git地址拉取代码
    //1、编译代码
    stage('编译') {
    //执行docker命令的前提是Jenkins安装docker、docker pipeline插件
    //Jenkins原本不支持maven命令,加上自定义代理基础镜像,才可以支持maven命令
    agent{
    //用完就会杀掉
     docker
     {
            image 'maven:3-eclipse-temurin-8-alpine'
            //将maven容器的仓库挂载到宿主机,避免每次下载
            args '-v /var/jenkins_home/appconfig/maven/.m2:/root/.m2'
     }

    }
                steps {
                    //可以定义要做的所有事情
                    //查看当前目录,在干什么
                    sh 'pwd && ls -alh'
                    sh 'printenv'
                    //检测maven命令是否可以执行
                    sh 'mvn -version'
                    //跳过单元测试打包。-Dmaven.test.skip=true:跳过单元测试
                    //运行mvn clean package时默认是从maven*仓库下载
                    //-s /var/jenkins_home :指定settings.xml文件的位置, /var/jenkins_home/appconfig/maven/settings.xml 是容器里面的路径
                    sh 'mvn clean package  -s "/var/jenkins_home/appconfig/maven/settings.xml"  -Dmaven.test.skip=true '

                }
            }
    //2、生成镜像
    stage('生成镜像') {
                    steps {
                        //
                         echo "生成镜像"
                         //检测docker命令是否可以正常运行
                         sh 'docker version'
                         sh 'pwd && ls -alh'
                    }
                }

       //4、部署代码
         stage('部署') {
                         steps {
                             //
                             echo "部署"
                         }
                     }
    }

}

构建一次后,在此构建,已经没有了下载maven依赖的动作

Jenkins

Jenkins

构建镜像

  • 临时容器导致的问题
    • 1、第一次检出代码的目录:/var/jenkins_home/workspace/java-devops-demo
    • 2、使用代理agent时,会运行一个临时的maven容器,临时的容器会被放到一个临时的目录:/var/jenkins_home/workspace/java-devops-demo@2,默认就是workspace的内容
    • 3、在临时容器里面,运行的 sh 'mvn clean package -s "/var/jenkins_home/appconfig/maven/settings.xml" -Dmaven.test.skip=true '命令会在临时目录进行工作/var/jenkins_home/workspace/java-devops-demo@2
    • 4、此时package的工作目录是:/var/jenkins_home/workspace/java-devops-demo@2,所以在临时目录生成了jar包
    • 5、每一个stage的开始,工作目录都会回到workspace目录,所以生成镜像阶段又回到了/var/jenkins_home/workspace/java-devops-demo目录,这个目录没有jar包,所以需要在打包前先把目录切换到workspace目录
    • 6、生成镜像阶段需要在项目的根目录下放一个Dockerfile文件

JenkinsJenkinsJenkinsJenkins

FROM openjdk:8-jre-alpine
LABEL maintainer="lori@qq.com"

COPY target/*.jar /app.jar
#设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo  'Asia/Shanghai' >/etc/timezone && touch /app.jar
ENV JAVA_OPTS=""
ENV PARAMS=""
ENTRYPOINT [ "sh", "-c", "java -Djava.security.egd=file:/dev/./urandom  $JAVA_OPTS -jar /app.jar $PARAMS" ]

Jenkinsfile

//流水线有两种形式:声明式、脚本式
//声明式
pipeline{
//全部的CICD流程都需要在这里定义
    //任何一个代理可用就可以执行流水线
    agent any
    //定义一些环境信息
    environment{
        WS = "${WORKSPACE}"
    }

    //定义流水线的加工流程
    stages {

     stage('检查') {
         steps {
     //查看当前目录
     sh 'pwd && ls -alh'
     }
     }
    //流水线的所有阶段
    //根据git地址拉取代码
    //1、编译代码
    stage('编译') {
    //执行docker命令的前提是Jenkins安装docker、docker pipeline插件
    //Jenkins原本不支持maven命令,加上自定义代理基础镜像,才可以支持maven命令
    agent{
    //用完就会杀掉
     docker
     {
            image 'maven:3-eclipse-temurin-8-alpine'
            //将maven容器的仓库挂载到宿主机,避免每次下载
            args '-v /var/jenkins_home/appconfig/maven/.m2:/root/.m2'
     }

    }
                steps {
                    //可以定义要做的所有事情
                    //查看当前目录,在干什么
                    sh 'pwd && ls -alh'
                    sh 'printenv'
                    //检测maven命令是否可以执行
                    sh 'mvn -version'
                    //跳过单元测试打包。-Dmaven.test.skip=true:跳过单元测试
                    //运行mvn clean package时默认是从maven*仓库下载
                    //在sh 'printenv'命令下,我们可以看到workspace的目录是一个默认的环境变量,所以我们可以取到以后切换目录:${WORKSPACE},但是我们发现cd以后还是临时的目录,没有切换过来,此时,我们需要设置一个全局的环境变量,WS = "${WORKSPACE}"
                    //-s /var/jenkins_home :指定settings.xml文件的位置, /var/jenkins_home/appconfig/maven/settings.xml 是容器里面的路径
                    sh 'cd ${WS} &&  mvn clean package  -s "/var/jenkins_home/appconfig/maven/settings.xml"  -Dmaven.test.skip=true '
                }
            }
    //2、生成镜像
    stage('生成镜像') {
                    steps {
                        //
                         echo "生成镜像"
                         //检测docker命令是否可以正常运行
                         sh 'docker version'
                         sh 'pwd && ls -alh'
                         sh 'docker build -t java-devops-demo .'
                    }
                }

       //4、部署代码
         stage('部署') {
                         steps {
                             //
                             echo "部署"
                         }
                     }
    }
}

部署

  • 在部署环节里加docker run命令启动服务容器

Jenkinsfile

//流水线有两种形式:声明式、脚本式
//声明式
pipeline{
//全部的CICD流程都需要在这里定义
    //任何一个代理可用就可以执行流水线
    agent any
    //定义一些环境信息
    environment{
        WS = "${WORKSPACE}"
    }

    //定义流水线的加工流程
    stages {

     stage('检查') {
         steps {
     //查看当前目录
     sh 'pwd && ls -alh'
     }
     }
    //流水线的所有阶段
    //根据git地址拉取代码
    //1、编译代码
    stage('编译') {
    //执行docker命令的前提是Jenkins安装docker、docker pipeline插件
    //Jenkins原本不支持maven命令,加上自定义代理基础镜像,才可以支持maven命令
    agent{
    //用完就会杀掉
     docker
     {
            image 'maven:3-eclipse-temurin-8-alpine'
            //将maven容器的仓库挂载到宿主机,避免每次下载
            args '-v /var/jenkins_home/appconfig/maven/.m2:/root/.m2'
     }

    }
                steps {
                    //可以定义要做的所有事情
                    //查看当前目录,在干什么
                    sh 'pwd && ls -alh'
                    sh 'printenv'
                    //检测maven命令是否可以执行
                    sh 'mvn -version'
                    //跳过单元测试打包。-Dmaven.test.skip=true:跳过单元测试
                    //运行mvn clean package时默认是从maven*仓库下载
                    //在sh 'printenv'命令下,我们可以看到workspace的目录是一个默认的环境变量,所以我们可以取到以后切换目录:${WORKSPACE},但是我们发现cd以后还是临时的目录,没有切换过来,此时,我们需要设置一个全局的环境变量,WS = "${WORKSPACE}"
                    //-s /var/jenkins_home :指定settings.xml文件的位置, /var/jenkins_home/appconfig/maven/settings.xml 是容器里面的路径
                    sh 'cd ${WS} &&  mvn clean package  -s "/var/jenkins_home/appconfig/maven/settings.xml"  -Dmaven.test.skip=true '
                }
            }
    //2、生成镜像
    stage('生成镜像') {
                    steps {
                        //
                         echo "生成镜像"
                         //检测docker命令是否可以正常运行
                         sh 'docker version'
                         sh 'pwd && ls -alh'
                         sh 'docker build -t java-devops-demo .'
                    }
                }

       //4、部署代码
         stage('部署') {
                         steps {
                             //
                             echo "部署"
                             sh 'docker rm -f java-devops-demo-dev'
                             sh 'docker run -d -p 8888:8080 --name java-devops-demo-dev java-devops-demo'
                         }
                     }
    }

}

JenkinsJenkins

8、Jenkins部署完成后发送邮件通知

  • 发送用邮件流程
    • 首先在Jenkins的系统管理->系统配置里配置邮件相关信息,配置来源信息如下,在QQ邮箱中获取(我们以QQ邮箱为例)
    • 登录QQ邮箱在设置里配置POP3,如果是开启状态,先点关闭,再开启,然后发送短信后会得到一个授权码
    • 根据QQ邮箱中【如何使用 Foxmail 等软件收发邮件?】手册操作获取SMTP服务器和端口号

Jenkins

JenkinsJenkinsJenkinsJenkins

Jenkins

Jenkins

JenkinsJenkins

Jenkins

  • 我们在Jenkinsfile配置发送邮件内容,内容可以去jenkins的流水线语法里去生成 加到我们的Jenkinsfile文件里 Jenkins
//流水线有两种形式:声明式、脚本式
//声明式
pipeline{
//全部的cicd流程都需要在这里定义
    //任何一个代理可用就可以执行流水线
    agent any
    //定义一些环境信息
    environment{
        ws = "${workspace}"
    }

    //定义流水线的加工流程
    stages {

     stage('检查') {
         steps {
     //查看当前目录
     sh 'pwd && ls -alh'
     }
     }
    //流水线的所有阶段
    //根据git地址拉取代码
    //1、编译代码
    stage('编译') {
    //执行docker命令的前提是jenkins安装docker、docker pipeline插件
    //jenkins原本不支持maven命令,加上自定义代理基础镜像,才可以支持maven命令
    agent{
    //用完就会杀掉
     docker
     {
            image 'maven:3-eclipse-temurin-8-alpine'
            //将maven容器的仓库挂载到宿主机,避免每次下载
            args '-v /var/jenkins_home/appconfig/maven/.m2:/root/.m2'
     }

    }
                steps {
                    //可以定义要做的所有事情
                    //查看当前目录,在干什么
                    sh 'pwd && ls -alh'
                    sh 'printenv'
                    //检测maven命令是否可以执行
                    sh 'mvn -version'
                    //跳过单元测试打包。-dmaven.test.skip=true:跳过单元测试
                    //运行mvn clean package时默认是从maven*仓库下载
                    //在sh 'printenv'命令下,我们可以看到workspace的目录是一个默认的环境变量,所以我们可以取到以后切换目录:${workspace},但是我们发现cd以后还是临时的目录,没有切换过来,此时,我们需要设置一个全局的环境变量,ws = "${workspace}"
                    //-s /var/jenkins_home :指定settings.xml文件的位置, /var/jenkins_home/appconfig/maven/settings.xml 是容器里面的路径
                    sh 'cd ${ws} &&  mvn clean package  -s "/var/jenkins_home/appconfig/maven/settings.xml"  -Dmaven.test.skip=true '
                }
            }
    //2、生成镜像
    stage('生成镜像') {
                    steps {
                        //
                         echo "生成镜像"
                         //检测docker命令是否可以正常运行
                         sh 'docker version'
                         sh 'pwd && ls -alh'
                         sh 'docker build -t java-devops-demo .'
                    }
                }

       //3、部署代码
         stage('部署') {
                         steps {
                             //
                             echo "部署"
                             sh 'docker rm -f java-devops-demo-dev'
                             sh 'docker run -d -p 8888:8080 --name java-devops-demo-dev java-devops-demo'
                         }
                     }


                        //3、构建报告发送
                              stage('报告发送') {
                                              steps {
                                                    emailext body: '项目构建成功', subject: '流水线项目构建情况', to: '1129979425@qq.com'
                                              }
                                              }
    }

}

Jenkins