Jenkins自动化部署

基于Springboot以及Gitee的Jenkins自动化部署

本次教程环境准备:

  • 主要在centOS的Minimal版本下完成,需要下载vmware以及[镜像文件](链接:https://pan.baidu.com/s/13VoGLwBwHQI8EbdaPxfQbg
    提取码:cg8q[)。
  • ssh工具(本文使用finalShell),官网下载地址:http://www.hostbuf.com/t/988.html
  • jdk下载、解压并配置环境变量(本文使用jdk1.8),通过java -version查看版本,官网下载地址:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html
  • maven下载、解压并配置环境变量(本文使用maven3.8.2),通过mvn -version查看版本,官网下载地址:https://maven.apache.org/download.cgi
  • git下载,yum install -y git

Jenkins安装

​ Jenkins安装可通过yum、rpm、docker等方式进行安装,本文采用rpm安装,官网下载地址:https://pkg.jenkins.io/redhat/ ,也可通过我的百度云下载地址进行下载:链接:https://pan.baidu.com/s/1GfA_rZg32saGGdXlUTjw4w 提取码:cg8q。完成下载后会得到一个jenkins-2.174-1.1.noarch.rpm文件。

  • 创建文件夹放入rpm文件在这里插入图片描述

在这里插入图片描述

  • 文件安装,通过rpm -ivh jenkins-2.174-1.1.roarch.rpm命令安装jenkins。

在这里插入图片描述

  • 安装完成之后通过whereis jenkins查看jenkins安装目录。

在这里插入图片描述

  • jenkins需要配置jdk路径,进入/etc/init.d目录下的jenkins文件去通过vim jenkins添加jdk路径。

在这里插入图片描述

在这里插入图片描述

  • 进入jenkins安装目录通过service jenkins start启动jenkins(也可通过/etc/profile修改环境变量后直接通过命令启动)

由于上一步修改了文件,若未重载修改文件时启动会出现提示,需再执行以下systemctl daemon-reload重新加载文件即可

在这里插入图片描述

  • 当出现以上提示则代表jenkins启动成功了,我们可通过ip:端口直接访问(默认端口为8080,需保证当前端口未被占用),本机访问地址为(192.168.159.138:8080)。

在这里插入图片描述

  • 此时我们需要输入管理员密码,即初始化密码,当前密码存在于/var/lib/jenkins/secrets/initialAdminPassword中,输入即可

在这里插入图片描述

  • 输入之后出现以下界面,不清楚自己需求的情况下直接选择安装推荐的插件,社区推荐的插件也挺丰富的。

在这里插入图片描述

  • 设置管理员用户的用户名和密码

在这里插入图片描述

  • 主界面

在这里插入图片描述

对于插件下载失败问题

一是被墙了,二是网络问题,三是jenkins版本过低。

解决一:系统管理->插件管理->高级->升级站点URL改为:

  • http://mirror.esuni.jp/jenkins/updates/update-center.json

  • https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/current/update-center.json(备用)

解决二:升级jenkins版本

在系统管理找到

在这里插入图片描述

可选择自动升级,如果无此按钮可通过下载war文件后到指定目录中替换原有文件

通过系统管理->系统信息中查到需替换文件的路径

在这里插入图片描述

替换完成之后重启jenkins

  • 当前url访问/restart路由,本机为192.168.159.138:8080/restart

在这里插入图片描述

  • 通过whereis jenkins查询jenkins安装目录后,执行命令service jenkins reload

在这里插入图片描述

解决三:手动上传安装插件(不推荐,因为太多了,一个一个安装太慢,但最有效)

官网地址:https://plugins.jenkins.io,在搜索框查询需要的插件名称选择版本进行下载后,在jenkins中系统管理->管理插件->高级->上传插件,完成上传即可

Jenkins自动化部署配置

  • Jenkins->系统管理->全局工具配置来设置jdk、maven、git的路径,可通过jenkins的Install automatically选择安装版本(本文手动安装了jdk、maven、git,无需通过jenkins自动安装)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • Jenkins->插件管理中下载Maven Integration plugin插件

在这里插入图片描述

  • 虽然jdk、maven、git路径配置完成,但是jenkins默认会读取的是/usr/bin目录下的命令,如果不配置的话就会造成java、mvn命令找不到的问题

我们可以通过软连接和硬连接的方式来使jenkins能读取命令(当前采用的是软连接方式,具体软连接和硬连接的区别自行上网查看)

ln -s /usr/local/apache-maven-1.3.8/bin/mvn /usr/bin/mvn

ln -s /usr/jdk1.8.0_261/bin/java /usr/bin/java

创建一个Springboot项目

  • 定义一个简单的springboot项目,定义一个get请求的api以及存放Pipeline语法文件的位置

在这里插入图片描述

  • 以下是Pipeline的语法结构

在这里插入图片描述

  • credentialsId可通过Jenkins设置-> 凭证管理->更新->ID得到

在这里插入图片描述

在这里插入图片描述

  • Jenkinsfile文件通过shell命令执行指定路径下的文件并传递所给的参数,默认jar会存在/var/lib/jenkins/workspace/jenkins-demo/target下,sshpass命令需要通过yum install sshpass进行安装

在这里插入图片描述

  • 上图的stop和start执行sh文件在linux中定义如图,本项目存于/data/app/sh目录下

在这里插入图片描述

新建Item

  • 采用Pipeline声明式语法构建项目

在这里插入图片描述

  • 这里我们不做任何其他配置

在这里插入图片描述

  • 需要自定义Pipeline脚本,可通过流水线语法去完成脚本编辑

在这里插入图片描述

  • 两种方式在定义Pipleline脚本,一是直接在Jenkins上定义Item的流水线语法,二是通过源代码管理仓库获取流水线,即代码中编写流水线脚本并通过指定路径区访问编写的流水线语法(当前示例采用的是Pipeline script from SCM)

在这里插入图片描述

  • 选择SCM源(当前示例采用的是Git控制)

在这里插入图片描述

  • 填写具体信息后点击保存

在这里插入图片描述

  • 当前即为你新建的Item启动项

在这里插入图片描述

  • 部署启动成功在这里插入图片描述

  • 访问API

在这里插入图片描述

可能出现的问题

  • springboot项目的jdk版本和jenkins设置的jdk版本不一样导致出现发行版本不同的问题而无法启动项目,需要统一jdk版本问题

  • 无法找到mvn、java命令->jenkins默认找的是/usr/bin目录下的命令,需要通过软连接方式链接到/usr/bin目录下

  • 权限问题,可能存在jar移动到其他目录而导致的权限问题,最粗暴的方式是chmod 777,直接给该文件或文件夹设置成最高权限,或者指定文件或文件夹某一个权限。

  • 编译太慢,可能是maven仓库问题,特别是第一次部署项目时需要从仓库中拉依赖,在没有镜像设置的情况下极其慢,我们需要设置以下镜像(如阿里云镜像)

  • Host key verification failed.

    运行Jenkins的用户是程序用户jenkins,但是程序用户jenkins是非正常用户

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U1t7jJAL-1630597523895)(C:\Users\win10\Desktop\jenkins\Jenkins自动化部署.assets\image-20210828170934437.png)]

    非正常主要体现在登陆shell异常 如下非正常主要体现在登陆shell异常 如下

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1PW54qFq-1630597523896)(C:\Users\win10\Desktop\jenkins\Jenkins自动化部署.assets\image-20210828171035189.png)]

    解决方法

    (1)改变jenkins用户的登陆shell,使用vim /etc/passwd修改文件

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cDMGHY5a-1630597523897)(C:\Users\win10\Desktop\jenkins\Jenkins自动化部署.assets\image-20210828171237941.png)]

    (2)切换jenkins用户 测试

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JO0Npti8-1630597523899)(C:\Users\win10\Desktop\jenkins\Jenkins自动化部署.assets\image-20210828171353584.png)]

    (3)重新定义jenkins用户的命令提示符,cd返回根目录通过vim .bash_profile执行指令后再尾部添加export PS1='[\u@\h \W]\$ 'source .bash_profile重载文件。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n5olF4gX-1630597523900)(C:\Users\win10\Desktop\jenkins\Jenkins自动化部署.assets\image-20210828171651725.png)]

    (4)再次切换到jenkins用户测试

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uyZXBMwB-1630597523902)(C:\Users\win10\Desktop\jenkins\Jenkins自动化部署.assets\image-20210828172209719.png)]

    (5)jenkins用户对目标主机做免密登陆,其命令包含su jenkinsssh-keygenssh-copy-id -i ~/.ssh/id_rsa.pub root@你的ip

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NmgzgOpU-1630597523904)(C:\Users\win10\Desktop\jenkins\Jenkins自动化部署.assets\image-20210828172345849.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hi0lNJmW-1630597523905)(C:\Users\win10\Desktop\jenkins\Jenkins自动化部署.assets\image-20210828172956001.png)]

  • 无法访问问题

    ​ 大部分原因在于防火墙拦截,端口未开放

    ​ 解决方法:

    ​ 1、 关闭防火墙(不推荐),systemctl stop firewalld

    ​ 2、开放指定端口

    ​ (1)linux 防火墙查询开放的端口号 firewall-cmd --query-port=端口号/tcp

    ​ (2)linux 防火墙开放指定端口号 firewall-cmd --add-port=端口号/tcp --permanent

关于本项目中的Jenkins文件以及sh文件讲解

Jenkins:

文件定义其实就是Pipeline的语法

什么是Pipeline?

 	Jenkins Pipeline是一组插件,支持在Jenkins上实现和集成持续交付的管道。Pipeline这个单词是水管的意思。我以后可能会翻译成管道或者流水线,我建议大家不要翻译,就写Pipeline。这里持续集成(CI)和持续交付(CD),我们在DevOps基础扫盲篇介绍过,以后多经常用到这两个单词缩写。

	Jenkins为了更好支持CI和CD,通过Groovy语言这么DSL(动态描述语言)来开发Pipeline组件。在Jenkins中有一句话,Pipeline as code,Pipeline是Jenkins中最优雅的存在。之前Jenkins上UI操作动作,都可以在Pipeline中代码实现,主要你对Jenkins和Groovy语言有足够多掌握。

	以后我们经常说CI Pipeline和CD Pipeline,你现在大致可以理解为,要实现CD,先要实现CI。CD Pipeline就是一个代码文件,里面把你项目业务场景都通过Groovy代码和Pipeline语法实现,一个一个业务串联起来,全部实现自动化,从代码仓库到生产环境完成部署的自动化流水线。这个过程就是一个典型的CD Pipeline
	
	官网建议我们把Pipeline代码放在一个名称为Jenkinsfile的文本文件中,并且把这个文件放在你项目代码的根目录,采用版本管理工具管理。Jenkinsfile我后面会具体例子来介绍。当然,我们也可以把Pipeline代码用一个Hello.groovy这样的文件去保存在代码库,这也是没问题的。

Pipeline关键字解释

pipeline
	这个单词是小写,可以看作是Pipeline语法中的一个关键字。以后一个groovy文件或者一个Jenkinsfile文件中不光只有Pipeline代码,例如还有其他的工具类方法等。通过pipeline { Pipeline代码},这个关键字就是告诉Jenkins接下来{}中的代码就是pipeline代码,和普通的函数或者方法隔离出来。

node
	关键字node就是用来区分,Jenkins环境中不同的节点环境。例如一个Jenkins环境包括master节点,也就是主节点,还包括N多个从节点,这些从节点在添加到主节点的向导页面中有一个参数,好像是label,就是给这个从节点取一个名称。在Pipeline代码中可以通过node这个关键字告诉Jenkins去用哪一台节点机器去执行代码。

stage
	关键字stage,就是一段代码块,一般个stage包含一个业务场景的自动化,例如build是一个stage, test是第二个stage,deploy是第三个stage。通过stage隔离,让Pipeline代码读写非常直观。到后面你还会学习stages这个关键字,一个stages包含多个stage。

step
	关键字step就是一个简单步骤,一般就是几行代码或者调用外部一个模块类的具体功能。这里step是写在stage的大括号里的。

本项目Jenkins文件讲解

pipeline {		//一
    agent any	//二
    options {	//三
        timeout(time: 2, unit: 'HOURS')		//运行超时时间为两小时
    }
    stages  {	//四
        stage('Package') {	//五		该时期名称定义为Package
            steps {		//六
                sh 'mvn clean install -Dmaven.test.skip=true'	//shell命令执行maven的clean和install操作,中间跳过test
            }
        }
        stage('Deliver for dev') {	//该时期名称定义为Deliver for dev
            steps {
            	//具体steps内部引用参照https://www.jenkins.io/doc/pipeline/steps/
                withCredentials([usernamePassword(credentialsId: 'cheyinbo', passwordVariable: 'password', usernameVariable: 'username')]) {
                	//shell命令执行文件deploy.sh文件并根据顺序传入参数
                     sh "bash scripts/deploy/deploy.sh 192.168.159.138 root root jenkins-demo"
                }
            }
        }
    }
}

一:整个大的代码块,表明该文件是一个Pipeline语法文件,内部语法必须遵从pipeline语法

:agent部分指定整个Pipeline或特定阶段将在Jenkins环境中执行的位置,具体取决于该agent 部分的放置位置。该部分必须在pipeline块内的顶层定义。

anynonelabelnodedocker
在任何可用的agent 上执行Pipeline或stage当在pipeline块的顶层使用none时,将不会为整个Pipeline运行分配全局agent ,每个stage部分将需要包含其自己的agent部分agent { node { label ‘labelName’ } },等同于 agent { label ‘labelName’ },但node允许其他选项(如customWorkspace)。使用提供的label标签,在Jenkins环境中可用的代理上执行Pipeline或stage。例如:agent { label ‘my-defined-label’ }定义此参数时,执行Pipeline或stage时会动态供应一个docker节点去接受Docker-based的Pipelines。 docker还可以接受一个args,直接传递给docker run调用。例如:agent { docker ‘maven:3-alpine’ }或docker
agent {
docker {
image 'maven:3-alpine’
label 'my-defined-label’
args ‘-v /tmp:/tmp’
}
}

:options指令允许在Pipeline本身内配置Pipeline专用选项。Pipeline本身提供了许多选项,例如buildDiscarder,但它们也可能由插件提供,例如 timestamps。

可用选项

buildDiscarderpipeline保持构建的最大个数。例如:options { buildDiscarder(logRotator(numToKeepStr: ‘1’)) }

disableConcurrentBuilds

不允许并行执行Pipeline,可用于防止同时访问共享资源等。例如:options { disableConcurrentBuilds() }

skipDefaultCheckout

默认跳过来自源代码控制的代码。例如:options { skipDefaultCheckout() }

skipStagesAfterUnstable

一旦构建状态进入了“Unstable”状态,就跳过此stage。例如:options { skipStagesAfterUnstable() }

timeout

设置Pipeline运行的超时时间。例如:options { timeout(time: 1, unit: ‘HOURS’) }

retry

失败后,重试整个Pipeline的次数。例如:options { retry(3) }

timestamps

预定义由Pipeline生成的所有控制台输出时间。例如:options { timestamps() }

:Stages 是 Pipeline 中最主要的组成部分,Jenkins 将会按照 Stages 中描述的顺序从上往下的执行。Stages 中可以包括任意多个 Stage,而 Stage 与 Stages 又能互相嵌套,除此以外还有 parallel 指令可以让内部的 Stage 并行运行。实际上可以把 Stage 当作最小单元,Stages 指定的是顺序运行,而 parallel 指定的是并行运行。

:steps 是 Pipeline 中最核心的部分,每个 Stage 都需要指定 Steps。Steps 内部可以执行一系列的操作,任意操作执行出错都会返回错误。

jenkins-demo.sh文件讲解

APP_NAME=jenkins-demo
USER_DIR=/data/app/java	
APP_JAR=${APP_NAME}.jar
JAR_FILE=$USER_DIR/${APP_NAME}.jar
PID_FILE=$USER_DIR/${APP_NAME}.pid

        #--logging.config=$USER_DIR/logback.xml \

//开始进程的语法
start() {
	//1>/dev/null:表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,不显示任何信息。
	//2>&1:表示标准错误输出重定向等同于标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。
    nohup java -Xmx512M  -jar $JAR_FILE > /dev/null 2>&1 & 	//后台运行jar包
    
    //$!表示获取做个一个生成进程的pid, 本语句译为将当前执行进程的pid存入到指定目录下的指定文件名称.pid文件里并输出当前生成的进程pid
    echo $! > $USER_DIR/$APP_NAME.pid & 
    
    //输出当前jar的路径
    echo $JAR_FILE 
    
    //休眠1秒
    sleep 1	
    
    //输出当前应用执行完毕的标识
    echo "Start $APP_NAME done."
    
    //结束
    exit 0
}

//结束进程方法
stop() {
	//获取生成pid文件中的pid
    PID=`cat ${PID_FILE}`
    //结束指定pid的进程
    kill $PID
    
    //循环
    for i in {1..30}
    do
    	//查询当前pid进程是否还存在
        process=`ps aux | grep ${PID} | grep -v grep`
        if [[ $process ]]; then
        	//输出等待指定应用的进程结束的标识
            echo "Wait process ${APP_NAME} exit..."
            //休眠1秒
            sleep 1
        else
        	//输出指定应用的进程已结束的标识
            echo "Process ${APP_NAME} exited."
            //删除之前保存的pid文件
            rm -rf $PID_FILE
            //结束
            exit 0
        fi
    done
    
    echo 'Force kill'
    
    //若进程依旧未被结束,在执行一次结束进程的命令
    kill -KILL $PID
    //删除之前生成的pid文件
    rm -rf $PID_FILE
}

case $1 in
start)
	start
;;
stop)
	stop
;;
esac
    	//输出指定应用的进程已结束的标识
        echo "Process ${APP_NAME} exited."
        //删除之前保存的pid文件
        rm -rf $PID_FILE
        //结束
        exit 0
    fi
done

echo 'Force kill'

//若进程依旧未被结束,在执行一次结束进程的命令
kill -KILL $PID
//删除之前生成的pid文件
rm -rf $PID_FILE

}

case $1 in
start)
start
;;
stop)
stop
;;
esac



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值