还在手动发包?手把手教你 Jenkins 自动化部署SpringBoot 置顶!
大家好,我是一航!
程序员每天的工作,几乎都是围绕着开发
、打包
、发布
、测试
这些点循环往复,但这些过程中,有很大一部分重复性的苦力活,不仅消耗了我们大量的时间,但有不得不做;纯手工去集成、部署,既苦力,还容易出错;此时就需要通过自动化,来解放双手。
在做自动化集成、部署前,先引入两个概念CI/CD,其核心分为三点:
-
持续集成(Continuous integration)
频繁地(一天多次)将代码集成到主干。 每次集成都通过自动化的构建(包括编译、发布、自动化测试)来验证,从而尽快地发现集成错误。
-
持续交付(Continuous delivery)
频繁地将软件的新版本,交付给质量团队或者用户,以供评审。如果评审通过,代码就进入生产阶段。
-
持续部署(Continuous deployment)
持续部署是持续交付的下一步,指的是代码通过评审以后,自动部署到生产环境。
Jenkins就是专门为CI/CD而生的一款Java开源软件,因功能强大
、跨平台
、插件丰富
、扩展性强
、分布式
等特点,深受大家的喜爱;
但是,好用归好用,可他对新手来说稍微有一点点不太友好,环境部署总是会遇到一些莫名其妙的问题,哪怕是我部署过这么多次了,但每一次重新部署的时候,总会遇到各种各样不同的问题;交流群里面经常有铁子在交流Jenkins,这里就索性带从0开始,带大家完整部署一套 Jenkins 自动化环境。
本次的目标,就是将我们从集成、部署的苦力活中解放出来,专心写代码就好了
文章尽可能的细化到每个细节,稍微有点点长,建议收藏,以便日后查看;
准备
本文所有的部署都是在CentOS 7上完成,软件安装都采用的是Docker,如果你想跟着这个教程搭建,需要准备一下环境:
-
2台CentOS 7 的电脑 / 虚拟机
没有物理机的,可以使用虚拟机的方式来搭建,本文就是采用的虚拟机来配置;
CentOS 7 虚拟机搭建教程:https://blog.lupf.cn/articles/2020/04/04/1586001434581.html
以下两台测试机器的IP和功能点
- 192.168.1.253 安装Jenkins、GitLab
- 192.168.1.237 运行打包后的项目
-
Docker 安装
服务编排采用的
docker-compose
安装教程:https://blog.lupf.cn/articles/2019/11/23/1574503815568.html
-
JDK安装
全版本JDK下载:https://blog.lupf.cn/category/jdkdl
-
Maven安装
下载地址:https://maven.apache.org/download.cgi
wget http://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz tar -zxvf apache-maven-3.8.6-bin.tar.gz mv apache-maven-3.8.6 /usr/local/
-
SSH工具
用于远程Linux服务器,虚拟机,直接操作起来比较的麻烦;
之前给大家推荐过多款SSH;【5款SSH工具】、【】
软件安装
由于是工具类的软件,为了减少对机器的侵入, Jenkins 和代码仓库 GitLab的安装都是采用的Docker的方式,所以请提前安装好Docker
Jenkins
安装
-
准备挂载目录
用于持久化数据
mkdir -p /var/jenkins/data chmod 777 /var/jenkins/data cd /var/jenkins/data
-
查看Docker的组ID
**重要!**这个步骤很重要,因为后续Jenkins使用的是宿主机的 Docker ,所以在启动的时候,就需要做好Docker的映射以及权限组ID的配置;
cat /etc/group | grep docker
每台电脑都会有所差异,下面是我两台虚拟机对应的ID;
记住你装Jenkins那一台的ID,在下个步骤配置docker-compose时,需要在
group_add
中配置上对应的ID;这里务必要配置正确,否则后面在Jenkins容器中使用Docker命令时,会报权限不足的错误。
-
准备docker-compose-jenkins.yml配置文件
vim docker-compose-jenkins.yml
添加以下配置
version: '2' services: jenkins: container_name: 'jenkins' image: 'jenkins/jenkins' restart: always environment: TZ: 'Asia/Shanghai' ports: - '8880:8080' - '50000:50000' group_add: - 994 volumes: - /var/run/docker.sock:/var/run/docker.sock - /usr/bin/docker:/usr/bin/docker - /var/jenkins/data:/var/jenkins_home - /usr/local/apache-maven-3.8.6:/usr/local/apache-maven-3.8.6
参数说明
-
ports
映射的端口 -
restart
自启动 -
group_add
Docker的组ID,就是前一个步骤获取出来的ID -
volumes
挂在目录/usr/bin/docker:/usr/bin/docker
,将宿主机的Docker挂在给Jenkins,方便后续在Jenkins中使用宿主机Docker,就不需要在Jenkins容器中再安装一个Docker了;/var/jenkins/data:/var/jenkins_home
将Jenkins的工作目录/var/jenkins_home
挂在到宿主机的/var/jenkins/data
的目录下;/usr/local/apache-maven-3.8.6:/usr/local/apache-maven-3.8.6
挂在的Maven,可以根据个人使用的调整;
-
-
启动
# 启动 docker-compose -f docker-compose-jenkins.yml up -d # 查看容器 docker ps | grep jenkins
初始化
容器启动,大约等1分钟之后,就可以来初始化Jenkins了
-
访问jenkins
直接在浏览器访问
http://你jenkins机器的ip:8880
,我本地地址:http://192.168.1.253:8880
-
查看初始密码
默认密码是保存在
/var/jenkins_home/secrets/initialAdminPassword
获取命令如下:
docker exec -it jenkins cat /var/jenkins_home/secrets/initialAdminPassword
命令的意思是在名称为
jenkins
的Docker容器中执行cat /var/jenkins_home/secrets/initialAdminPassword
;也可以在本地挂在的目录下去查找;
安装推荐插件
安装插件
在初始化的时候,默认给我们安装了一些插件,后续还需要用到一些插件,这里提前安装一下;
安装入口:系统管理-->插件管理-->可选插件
注意!所有插件在重启之后才会生效
-
汉化插件
-
Maven插件
本文演示的下项目是通过Maven管理,搜索
Maven Integration
安装Maven相关插件 -
Git 插件
-
GitLab插件
-
SSH 插件
用于将文件上传到远端服务器
-
webhook
全局配置
主要是配置一些基础的环境,比如Maven、Git、JDK等工具,便于后续构建的时候,能够直接使用这些全局的基础配置
-
Maven配置
这里的Maven是容器启动时,映射的宿主机的包,如果你是下载的其他的版本或者映射的其他路径,请根据实际情况调整;
Maven优化
可以通过配置 MAVEN_OPTS 避免编译复杂项目时出现内存泄漏等问题
-
JDK配置
Docker安装的Jenkins容器自带了JDK,所以这里只需要拿到容器内的JDK路径,配置上即可;获取当时如下:
# 进去容器 docker exec -it jenkins /bin/bash # 输出JDK的环境变量 echo $JAVA_HOME
-
SSH Server配置
这里配置的是远端服务器的信息(也就是代码运行的服务器信息);
Gitlab
GitLab 是一个用于仓库管理系统的开源项目,使用 Git 作为代码管理工具,并在此基础上搭建起来的Web服务。
介于很多人在实际工作的时候,都是使用GitLab来搭建的私有代码仓库,这里就使用GitLab来演示;当然你使用Github
、Gitee
也是可以的,不过由于本地Jenkins没有公网IP,后续配置webhook的时候,如果使用Github、Gitee的话,就需要做内网穿透,又会增加一些麻烦,所以这里索性就直接安装一个本地GitLab,方便后续的使用,反正Docker安装起来也比较的容易。
安装
-
搜索中文版的gitlab-ce-zh
docker search gitlab-ce-zh
这里是用的是
twang2218/gitlab-ce-zh
镜像 -
准备持久化目录
mkdir -p /var/gitlab
-
准备docker-compose
version: '2' services: gitlab: container_name: 'gitlab-ce-zh' image: 'twang2218/gitlab-ce-zh' restart: unless-stopped hostname: 'gitlab' environment: TZ: 'Asia/Shanghai' GITLAB_OMNIBUS_CONFIG: | external_url 'http://192.168.1.253:880' ports: - '880:880' - '8443:443' - '2212:22' volumes: - /var/gitlab/etc:/etc/gitlab - /var/gitlab/log:/var/log/gitlab - /var/gitlab/data:/var/opt/gitlab
其中
external_url
中的IP为你本地机器的IP;其中的端口和容器映射的端口要保持一致,否则将无法访问。 -
启动
docker-compose -f docker-compose-gitlab.yml up -d docker ps | grep gitlab
状态变成
healthy
,说明服务已经正常。
初始化
-
访问
访问上一步的
external_url
(本机:http://192.168.1.253:880) -
设置管理员密码
设置完之后,就使用
root
和你新设置的密码,登录即可进入gitlab的主页
配置Jenkins、GitLab关联
由于后续Jenkins需要自动在Gitlab中获取最新的代码,因此,需要提前配置身份认证令牌。
GitLab令牌
-
创建
hYw-Qy6KxGFsdzGA96Ux
每次创建的都会不一样;而且,这个令牌只会显示一次,之后就不会再显示了,所以请保存好;否则就只能重新生成了;
Jenkins配置GitLab的凭据
将前面步骤生成的GitLab令牌配置成Jenkins的全局凭据,以方便后续的使用。
-
选择管理凭据
-
点击Jenkins
-
点击全局凭据
-
点击添加凭据
-
输入Token
选择
GitLab API token
,然后输入前一步在GitLab中创建好的token -
创建成功
点击
Create
按钮即可创建凭据
Jenkins配置GitLab的基础信息
构建Maven项目
准备项目
-
测试源码
-
本地GitLab创建一个项目
源码创建了一个
jenkins
分支,推送到本地Gitlab仓库
准备脚本
此脚本的作用就是将Jenkins传到运行服务器的Jar包给跑起来;
单模块的项目脚本写起来会比较的简单;当我在群里面说在写Jenkins教程的时候,有群友专门@我,说要求把多模块的写一下,然后这里的脚本就变长了;因为多模块的情况稍微复杂一些,比如:一个项目有10个模块,本次提交,仅仅修改了1个模块,其他9个模块没做任何改动,就不需要发布那9个,仅仅更新有修改的哪一个包就好了;
下面只是一个最基础的脚本,个人可以根据实际的使用过程,再进行调整;
#!/bin/sh
# JDK的环境变量
export JAVA_HOME=/usr/local/jdk-11.0.14
export PATH=$JAVA_HOME/bin:$PATH
# 基础路径,由参数传入
# 多模块的时候,需要在路径中使用*统配一下多模块
# 比如/opt/ehang-spring-boot是多模块,下面由module1和module2
# 那么执行shell的时候使用:sh restart.sh /opt/ehang-spring-boot/\* 注意这里的*需要转义一下
JAR_BATH=$1
echo "基础路径:"$JAR_BATH
JAR_PATH=${JAR_BATH}/target/*.jar
# 获取所有的JAR 开始遍历
for JAR_FILE in $JAR_PATH
do
if [ -f $JAR_FILE ]
then
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo "JAR路径:"$JAR_FILE
JAR_FILE_MD5=${JAR_FILE}.md5
# 用于标记是否需要重启的标识
RESTART=false
# 判断MD5文件是否存在,存在就校验MD5值
if [ -f $JAR_FILE_MD5 ]; then
# 校验MD5
md5sum --status -c $JAR_FILE_MD5
# = 0表示校验成功 =1 表示校验失败
if [ $? = 1 ];then
echo "MD5校验失败,安装包已经更新!"
RESTART=true
else
echo "安装包没有更新!"
fi
else
echo "没有MD5值,说明是第一次启动"
RESTART=true
fi
# 获取进程号
PROCESS_ID=`ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}'`
# 如果不需要重启,但是进程号没有,说明当前jar没有启动,同样也需要启动一下
if [ $RESTART == false ] && [ ${#PROCESS_ID} == 0 ] ;then
echo "没有发现进程,说明服务未启动,需要启动服务"
RESTART=true
fi
# 如果是需要启动
if [ $RESTART == true ]; then
# kill掉原有的进程
ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}' | xargs kill -9
#如果出现Jenins Job执行完之后,进程被jenkins杀死,可尝试放开此配置项
#BUILD_ID=dontKillMe
#启动Jar
nohup java -jar $JAR_FILE > ${JAR_FILE}.log 2>&1 &
# =0 启动成功 =1 启动失败
if [ $? == 0 ];then
echo "restart success!!! process id:" `ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}'`
else
echo "启动失败!"
fi
# 将最新的MD5值写入到缓存文件
echo `md5sum $JAR_FILE` > $JAR_FILE_MD5
fi
echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo ""
fi
done
脚本细节,注释已经写的很清楚了;简单说一下脚本的流程:
-
执行脚本传入单模块/多模块的路径
注意:多模块的时候,需要使用*通配一下各个模块,执行命令的时候,需要通过
\*
转义一下;详情见下图 -
遍历目录中
target
目录下的所有jar包 -
校验MD5,MD5没有或者对不上,说明更新了,否则对应包没有更新
-
当不需要更新时,校验进程是否存在,如果进程不存在,同样需要启动
-
启动jar
-
将最新的MD5值缓存起来
以下仅仅是后续测试截图,此处可以跳过,继续下一步
Jenkins创建Maven任务
-
创建Maven任务
Maven任务配置
设置gitlab凭据
选择前面步骤配置的凭据
设置GitLab项目地址
首次配置,这里需要先添加Git仓库的凭据信息,步骤如下:
配置构建命令
clean package -DskipTests=true
注意这里本身就是使用的Maven构建,所以命令不需要在前面加上mvn
构建完后上传文件
上传脚本
在上传Jar包之前,我们需要将项目的启动/重启脚本传到服务器,方便后续jar上传完之后,就能直接执行了
- Transfer Set Source files:表示要传输的文件/文件规则
- Remove prefix:要去掉文件的前缀,比如以上配置,默认文件路径是:script/jenkins/abc.sh,在这里配置script/jenkins/就只会将abc.sh拷贝到远端目录,否则,script/jenkins/abc.sh 完整的拷贝过去。
- Remote directory:拷贝的远端路径,如果不配置,就是有SSH Server中配置的路径,我ssh server配置的远端路径为
/opt/jenkins/package
- Exec command:拷贝完之后,执行的脚本
上传Jar包
由于项目是多模块的,打包之后,每个模块都会打出一个jar包,分别放在各个模块的target目录下;我们需要作的就是将所有模块的Jar都拷贝到服务器并启动;
上传成功之后,会在/opt/jenkins/package
目录下看到所有的包信息:
拷贝完之后,将执行shell
脚本,单模块和多模块执行的命令仅仅为参数上的区别:
-
单模块
以
spring-boot-001-hello-world/target/spring-boot-001-hello-world-0.0.1-SNAPSHOT.jar
为单模块的包进行测试,执行的重启脚本为:sh /opt/jenkins/package/jenkins_restart.sh /opt/jenkins/package/spring-boot-001-hello-world
其中参数
/opt/jenkins/package/spring-boot-001-hello-world
为单模块的根目录 -
多模块
多模块仅仅只是路径不同而已
sh /opt/jenkins/package/jenkins_restart.sh /opt/jenkins/package/\*
其中
/opt/jenkins/package/\*
用于指明/opt/jenkins/package路径下的所有子模块Jar包都重启;其中\*
表示通配。
注意:由于这里执行了shell脚本,所以配置的时候,一定要在高级选项中将Exec in pty
勾选上,否则shell命令执行不会终止,直到超时结束,如下日志:
....
SSH: Connecting with configuration [centos_server] ...
SSH: Disconnecting configuration [centos_server] ...
ERROR: Exception when publishing, exception message [Exec timed out or was interrupted after 120,000 ms]
Build step 'Send files or execute commands over SSH' changed build result to UNSTABLE
Finished: UNSTABLE
开启控制台的输出日志
初次配置的时候,容易出现异常情况,为了方便排查问题,可以勾上下图左侧的选项,输出远端服务器执行日志;下图右侧中的日志就是远端执行shell脚本的输出;不勾选将不会有这些日志。
手动构建
选择项目,点击“立即构建”即可开始,执行完如果是绿色,说明构建成功,红色表示失败。
自动构建
Jenkins任务开启监听
前面的手动构建已经完成了,我们最终的目的是希望能够做到代码一提交,就自动构建并发布。
Jenkins中开启Gitlab监听,并设置一个token(可以不设置)
配置好之后,得到了以下的信息:
-
token
97a6a4c1601cebe83241a08a67fd3755
token是为了安全性,也可以不设置,根据个人的需要来定
GitLab配置钩子
找到项目之后,按着上图的步骤,将jenkins的地址、token以及触发条件配置好后,点击添加按钮;
手动触发事件
成功添加之后,可以通过测试(Test)按钮,可以手动测试一下事件触发,如果出现10的提醒,说明触发成功;
然后前往Jenkins查看,即可发现自动多了一条构建任务,触发条件是:Started by GitLab push by Administator
;
自动触发事件
上面通过手动触发的方式,已经能够正常构建了,下面就来通过git提交一段代码,看能否自动触发
动图中可以看到,当代码成功push
2秒之后,Jenkins就已经自动开始构建任务了
执行完之后,查看Jenkins的日志与Linux的服务进程,服务已经正常启动。
使用Docker部署
上面演示了Maven + SSH 的构建与部署,以直接运行Jar的方式,部署到服务器;当服务容器化之后,以Docker的方式将更方便管理,下面就来说一下,如何将项目构建成Docker镜像,来部署服务;
阿里云镜像仓库
有Docker镜像,就需要有仓库管理,本地局域网使用,可以通过Harbor搭建私有仓库,不过要想能在公网下使用,就必须有公网IP;
其实也可以不用那么麻烦,阿里云为我们提供了免费的镜像仓库,Jenkins服务器可以将打好的镜像直接推送到阿里云的仓库,业务服务器直接在阿里云仓库拉取镜像,运行起来即可;
-
地址
-
创建命名空间
免费3个
-
创建仓库
-
Docker登录阿里云仓库
上一步,创建完仓库之后,根据引导,在服务器登录阿里云的Docker仓库
docker login --username=你的用户名 registry.cn-guangzhou.aliyuncs.com
Jenkins共享的Docker,也需要进入容器类登录一下,由于容器内用户不一样,所以在宿主机上登录的,容器内无法使用
# 进入容器 docker exec -it jenkins /bin/bash # 容器内登录 docker login --username=你的用户名 registry.cn-guangzhou.aliyuncs.com
准备脚本
在Maven构建完之后,就需要构建对应的 Docker 镜像,并将镜像推送到远端服务器,因此这里需要提前准备好一些脚本,以方便构建时使用,过程如下:
- Jenkins本地构建Docker镜像
- 将镜像推送的阿里云仓库
- 推送下载脚本、启动脚本到运行服务器
- 执行下载、启动脚本
脚本详情如下:
Dockerfile
用来构建镜像时用的
FROM openjdk:8
# 同步时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 将当前目录下的jar拷贝到容器类
ADD ./*.jar /app.jar
# 监听端口
EXPOSE 8081
# 启动
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom" \
,"-XX:+UnlockExperimentalVMOptions","-XX:+UseCGroupMemoryLimitForHeap" \
,"-jar", "/app.jar" ]
构建脚本
Jenkins任务使用!
docker-image-build.sh
,
构建镜像时执行的shell脚本;
# 考虑到多模块的情况 这里创建一个临时目录,来汇总配置
rm -rf ./tmp
mkdir ./tmp
# 将脚本 jar包拷贝的临时目录中
cp ./spring-boot-001-hello-world/docker/* ./tmp
cp ./spring-boot-001-hello-world/target/*.jar ./tmp
cd ./tmp
# 构建镜像
docker build -t registry.cn-guangzhou.aliyuncs.com/ehang_jenkins/ehang-sping-boot-hello-world:latest .
# 将镜像推送到阿里云
docker push registry.cn-guangzhou.aliyuncs.com/ehang_jenkins/ehang-sping-boot-hello-world:latest
# 删除临时文件
cd ..
rm -rf ./tmp
镜像下载脚本
运行服务器使用;
docker-image-pull.sh
;用于运行服务器下载最新的镜像脚本
# 更新最新的镜像
docker pull registry.cn-guangzhou.aliyuncs.com/ehang_jenkins/ehang-sping-boot-hello-world:latest
docker-compose配置
运行服务器使用;
docker-compose.yaml
模块的服务编配配置,用于启动/重启Docker容器
version: '2'
services:
ehang-hello-world:
container_name: ehang-hello-world
image: registry.cn-guangzhou.aliyuncs.com/ehang_jenkins/ehang-sping-boot-hello-world:latest
restart: always
volumes:
- /opt/ehang:/opt/ehang
ports:
- "8081:8081"
environment:
- --spring.profiles.active=dev
多模块构建脚本
Jenkins任务使用!
用于遍历构建所有的子模块
#!/bin/sh
BUILD_SHELL_PATH=./*/docker/docker-image-build.sh
# 获取所有的JAR 开始遍历
for BUILD_SHELL in $BUILD_SHELL_PATH
do
if [ -f $BUILD_SHELL ]
then
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo "构建脚本:"$BUILD_SHELL
sh $BUILD_SHELL
echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo ""
fi
done
启动/重启脚本
运行服务器使用;
jenkins_restart_docker.sh
用于所有模块打包并随送到Docker仓库之后,启动/重启Docker容器的脚本;
#!/bin/sh
# 基础路径,由参数传入
# 多模块的时候,需要在路径中使用*统配一下多模块
# 比如/opt/ehang-spring-boot是多模块,下面由module1和module2
# 那么执行shell的时候使用:sh restart.sh /opt/ehang-spring-boot/\* 注意这里的*需要转义一下
BASE_PATH=$1
echo "基础路径:"$BASE_PATH
DOCKER_COMPOSE_FILES=${BASE_PATH}/docker/docker-compose.yaml
DOCKER_PULL_SHELL=${BASE_PATH}/docker/docker-image-pull.sh
# 获取最新的镜像
for PULL_SHELL in $DOCKER_PULL_SHELL
do
if [ -f $PULL_SHELL ]
then
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo "更新最新的镜像:"$PULL_SHELL
sh $PULL_SHELL
echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo ""
fi
done
# 启动镜像
for DOCKER_COMPOSE_FILE in $DOCKER_COMPOSE_FILES
do
if [ -f $DOCKER_COMPOSE_FILE ]
then
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo "docker compose 配置路径:"$DOCKER_COMPOSE_FILE
docker-compose -f $DOCKER_COMPOSE_FILE up -d
echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo ""
fi
done
所有的脚本,功能都很单一,逻辑也比较的简单,看看注释,很容易就看明白了;
Maven任务配置
使用Docker部署的步骤和前面使用SSH上传的步骤差不多,唯一的区别就在Maven打包完之后,脚本执行的差异,所以关于创建Maven任务
,设置GitLab凭据
、设置GitLab地址
以及配置构建命令
这些一样的配置,这里就不再重复了,忘了的可以翻回去看看;
这里详细说一下不同的地方!
构建后的操作
构建Docker镜像
Jenkins 执行本地构建所有子模块Docker镜像的脚本jenkins_docker_build.sh
上传基础脚本
上传启动/重启模块的脚本,这里的配置使用通配符上传了所有脚本,但服务器用到的只有jenkins_restart_docker.sh
;
上传所有模块Docker相关的脚本
这里上传的主要是各个子模块服务编排的配置
以及下载最新镜像的脚本
;
上传成功之后,开始执行jenkins_restart_docker.sh
,后面的参数需要根据项目结构来定,单模块,直接传项目的根路径;多模块需要使用\*
通配所有子模块
手动构建、自动触发
手动构建、自动触发和前面配置的方式一样,这里就不再重复了;
由于资源有限,下面使用了两个子模块进行构建测试;成功之后,服务端的Docker出现以下两个容器,说明服务已经正常了。
异常情况
-
Docker命令权限不否
dial unix /var/run/docker.sock: connect: permission denied
解决方案:Jenkins启动时,
group_add
未配置或者配置有误,配置正确后即可正常; -
denied: requested access to the resource is denied
上传/下载镜像时,错误
解决方案:需要进入 Jenkins 容器,登录一下Docker仓库;
Pipeline流水线
前面了Maven任务操作下来,可以将其看成一个框架,基于那个框架,去填入个性化的东西;这种构建方式,几乎能满足我们大部分的需求场景了;Pipeline流水线提供的就一种更加灵活的构建方式;
什么是Pipeline?
pipeline,即流水线,是jenkins2.X的新特性,是jenkins官方推荐使用的持续集成方案。与传统的自由风格项目不同,它是通过 jenkins DSL
编写代码来实现。相比于之前用户只能通过Web界面进行配置的方式来定义Jenkins任务,现在通过使用 jenkins DSL
和 Groovy
语言编写程序,用户可以定义流水线并执行各种任务。
简单测试
Pipeline 是Jinkins 一块比较大的功能点,涉及的内容很多,由于时间关系,这里就先不深入了,后续再针对 Pipeline 再进行详细的讲解。
下面就简单演示一下,通过Pipeline 编译打包构建Docker镜像的过程;
-
创建Pipeline任务
-
配置脚本
pipeline { agent any stages { stage('下载源码'){ options { timeout(time: 60, unit: 'SECONDS') } steps { git branch: 'jenkins', credentialsId: '6b7f5874-52b0-4859-ab83-14b20d68db50', url: 'http://192.168.1.253:880/root/ehang-spring-boot.git' } } stage('Maven编译'){ steps { sh ''' /usr/local/apache-maven-3.8.6/bin/mvn clean package -DskipTests=true ''' } } stage("构建/上传镜像"){ steps { sh ''' sh ./script/jenkins/jenkins_docker_build.sh ''' } } } }
- git branch 表示代码分支的名称
- credentialsId GitLab凭据ID,在 系统管理-->凭据中添加或者查看
-
测试
总结
虽然花了这么长的篇幅来写这个教程,但也只是讲解了一些最基本,最常用的功能;Jenkins的功能实在太强了,原本计划本文会将Pipeline以及自动化测试相关一并整理了,但一路写下来,发现基础的内容就占了如此大的篇幅,决定剩下的部分就留到下一篇文章再来写吧!
希望本文能够让你的日常工作变的更加“丝滑”;
我是一航!码字不易!求个三连!
标题:还在手动发包?手把手教你 Jenkins 自动化部署SpringBoot
作者:码霸霸
地址:https://lupf.cn/articles/2022/08/23/1661270044684.html