文章目录
实践过程和目的大致阐述下:
1.目的。为了通过 jenkins 实现CICD,即自动打包 SpringBoot 项目成 docker 镜像,并启动,这样方便开发人员专注于开发无需手动打包,运维人员可直接一键构建发布。
2.过程。开发人员提交代码到gitlab > 触发jenkins构建 > gitlab自动拉取项目源码 > maven 加载nexus依赖打包 > 打包docker镜像 > 发布。
一、准备阶段
1.1.服务器配置
提示:为了方便,实践均在一台服务器上实现,故如果是基于虚拟机安装linux实现,那配置要调高一点,内存4G起。
以下为我自己配置,仅供参考:
1.2.JDK1.8安装
提示:我这里安装的版本是 1.8.0_202,1.8 以上版本就可以
# 【1】 下载安装wet工具(已安装的可以跳过)
yum install wget
# 【2】 下载jdk,解压
wget https://repo.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz
#创建安装目录,解压到指定目录(目录可以自己指定,下文有用)
mkdir /usr/local/java/
tar -zxvf jdk-8u202-linux-x64.tar.gz -C /usr/local/java/
#嫌弃包占地方可以删除
rm -f jdk-8u202-linux-x64.tar.gz
# 【3】 配置环境变量,我这里采用创建 .sh 文件方式,方便管理,名字自己取。默认会加载该路径下所有.sh 文件。
vi /etc/profile.d/java.sh
# 添加以下内容到文件,保存退出
JAVA_HOME=/usr/local/java/jdk1.8.0_202
CLASSPATH=.:${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
PATH=$PATH:${JAVA_HOME}/bin
# 【4】 创建软连接
ln -s /usr/local/java/jdk1.8.0_202/bin/java /usr/bin/java
# 【5】 刷新配置环境来设置生效,检查版本来确认安装成功
source /etc/profile
java -version
1.3.Gradle安装(非必须)
提示:本文实践没有用到gradle,可以跳过,我这里只是顺手记一记,万一有人需要,我安装的是6.7版本
# 【1】 下载,解压
wget https://downloads.gradle-dn.com/distributions/gradle-6.7-bin.zip
#创建安装目录(可自己指定路径,下文需要)
mkdir /usr/local/gradle/
#解压,未安装则先安装 yum install unzip
unzip -d /usr/local/gradle gradle-6.7-bin.zip
#嫌弃占用可以删除压缩包
rm -f radle-6.7-bin.zip
# 【2】 配置环境变量,创建.sh配置文件
vi /etc/profile.d/gradle.sh
#添加以下内容到配置文件中,保存退出
GRADLE_HOME=/usr/local/gradle/gradle-6.7
PATH=$PATH:${GRADLE_HOME}/bin
# 【3】 设置生效,检查版本以确认安装成功
source /etc/profile
gradle -v
1.4.Maven安装
提示:我这里安装的版本是3.6.3,可自行选择版本
# 【1】 下载,解压
wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
#创建安装目录
mkdir /usr/local/maven
#解压到指定目录(路径可自选,下文有用)
tar -xf apache-maven-3.6.3-bin.tar.gz -C /usr/local/maven/
# 【2】 配置环境变量
vi /etc/profile.d/maven.sh
#添加以下内容到配置文件,保存退出
MAVEM_HOME=/usr/local/maven/apache-maven-3.6.3
PATH=$PATH:${JAVA_HOME}/bin:$MAVEM_HOME/bin
# 【3】设置生效,验证版本确认安装成功
source /etc/profile
mvn -version
1.5.Git安装
提示:我选择源码安装,你也可使用一键安装,只有清楚安装对应目录就可以。我这里安装的是2.25.1版本,自行选择
方式一:源码安装(我选择当前方式)
# 【1】 下载源码包
wget --no-check-certificate https://www.kernel.org/pub/software/scm/git/git-2.25.1.tar.gz
# 【2】 安装依赖包
yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker -y
# 【3】 创建用于安装编译目录
mkdir /usr/local/git/git-2.25.1
# 【4】 解压到当前目录
tar -zxvf git-2.25.1.tar.gz
# 【5】 编译,进入解压目录进行编译安装
cd git-2.25.1
./configure --prefix=/usr/local/git/git-2.25.1 && make install
# 【6】 配置环境变量。创建.sh文件,并追加内容到文件中
echo 'export PATH=$PATH:/usr/local/git/git-2.25.1/bin' > /etc/profile.d/git.sh
# 【7】设置生效,校验版本来确定安装成功
source /etc/profile
git --version
方式二:一键工具安装
# 【1】 一键安装
yum install git
# 【2】 查看命令地址,改地址后续挂载jenkins需要用到
which -a git
1.6.Docker安装
提示:方便起见,我选择安装最新版本 docker-ce 20.10.14版本,有关docker安装及基础原理,或想选择安装版本,可以看我另外一篇博客《Docker入门与实践》,更加详细,这里就简单记录安装及配置脚本
附博客链接:《Docker入门与实践》
# 【1】 卸载老的Docker及依赖(如果之前没有安装,或者系统没有自带则跳过)
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 【2】 安装依赖库
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 【3】 设置稳定版本库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 【4】 安装docker ce 并启动
yum install -y docker-ce
sudo systemctl start docker
# 【5】 设置开机自启动,关闭防火墙,测试安装结果
systemctl start docker
#设置开机启动
systemctl enable docker
#关闭防火墙,并查看防火墙状态以确认关闭
systemctl stop firewalld.service
systemctl status firewalld.service
# 查看运行状态
systemctl status docker
#查看docker版本
docker -v
# 【6】 配置加速,并重新加载生效
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
EOF
#重新加载
sudo systemctl daemon-reload
sudo 3.systemctl restart docker
1.7.Nexus3安装
提示:方便起见,我这里采用docker安装,安装最新版本nexus私服,更多安装细节和原理可以看我另外一篇博客《Maven入门与实践》中的搭建步骤。以下只是简洁搭建脚本,纯干货。
附博客链接:《Maven入门与实践》
# 【1】 查看并拉取nexus镜像
docker search nexus3
docker pull docker.io/sonatype/nexus3
# 【2】 创建数据持久化目录
sudo mkdir -p /home/docker/nexus3/nexus-data
sudo chmod 777 /home/docker/nexus3/nexus-data
# 【3】 启动
docker run \
-d \
--privileged=true \
--name=nexus3 \
--restart=always \
-p 82:8081 \
-v /home/docker/nexus3/nexus-data:/var/nexus-data sonatype/nexus3
#-d 后台运行程序
# privileged=true ,授权容器root权限
#--privileged=true 授予root权限(挂载多级目录必须为true,否则容器访问宿主机权限不足)
#--restart=always 为了虚拟机每次开机他都能自动启动,不用再去 docker start ...
#-p 物理机端口:容器内部端口 端口映射。启动后通过 82 端口访问,这里可以自己指定端口。
#-v centos主机目录:容器目录 ,主要是目录挂载
# 【4】 获取nexus初始化 admin 的密码
docker exec -it nexus3 /bin/bash
cd nexus-data/
#复制密码为: bash单词前,复制登录后提示你重置密码
cat admin.password
# 【5】 登录使用。账号是 admin 密码是上一步获取的,如果一直转圈可能是私服启动比较慢,要等待一会。
# http://ip:82 (我启动映射端口是 82,ip当然是你服务器ip)
1.8.配置全局maven文件setting.xml
提示:该步骤需要上文私服搭建完成后进行,因为要配置私服地址,账号地址
# 【1】 创建本地仓库jar存储地址
sudo mkdir -p /usr/local/maven/repo
sudo chmod 777 /usr/local/maven/repo
# 【2】 进入maven配置文件目录中(该目录为我上文安装的目录)
vi /usr/local/maven/apache-maven-3.6.3/conf/setting.xml
# 添加设置以下配置
提示:按配置顺序加载以下仓库,如果首次较慢可以先把私服放后面后面再改回来,因为首次加载本地仓库没有都是从其它仓库下载的。当然仓库个数自己选择,可以不用底下所有的仓库,我是一股脑配置进去了
<!-- 本地仓库存放地址 -->
<localRepository>/usr/local/maven/repo</localRepository>
<mirrors>
<!-- nexus start -->
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<name>Nexus name</name>
<!-- 复制nexus中的maven-public url -->
<url>http://192.168.36.110:82/repository/maven-public/</url>
</mirror>
<!-- nexus end -->
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>central</id>
<name>Maven Repository Switchboard</name>
<url>http://repo1.maven.org/maven2/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>repo2</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://repo2.maven.org/maven2/</url>
</mirror>
<mirror>
<id>google-maven-central</id>
<name>Google Maven Central</name>
<url>https://maven-central.storage.googleapis.com</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<servers>
<server>
<id>releases</id>
<!-- nexus中的账号密码 -->
<username>admin</username>
<password>1234</password>
</server>
<server>
<id>snapshots</id>
<!-- nexus中的账号密码 -->
<username>admin</username>
<password>1234</password>
</server>
</servers>
<!-- 在settings.xml里把这个group加上设置白名单 -->
<pluginGroups>
<pluginGroups>
<pluginGroup>com.spotify</pluginGroup>
</pluginGroups>
</pluginGroups>
注意:如果以上配置中没有加入group白名单,执行 mvn package docker:build 可能会报以下错误:
[ERROR] No plugin found for prefix 'docker' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (D:\xxxxxxx), nexus (http://repo2.maven.org/maven2/), skynet (http://maven2.mirrors.skynet.be/pub/maven2/)] -> [Help 1]
1.9.GitLab安装
提示:方便起见以下仅为docker安装gitlab相关脚本,如需要更详细了解步骤,已经基本使用,可以看我的博客《Docker安装GitLab与基本操作》
附博客链接:《Docker安装GitLab与基本操作》
# 【1】 下载gitlab镜像(方式二选一)
# 下载最新版本(我这里选择现在最新版本)
docker pull gitlab/gitlab-ce
# 下载指定版本(版本自己选)
docker pull beginor/gitlab-ce:11.0.1-ce.0
# 【2】 创建相对应目录将 GitLab 的配置 (etc) 、 日志 (log) 、数据 (data) 挂载到容器外。
mkdir -p /home/docker/gitlab/{etc,log,data}
# 【3】 启动容器
docker run \
-d \
-p 8443:443 \
-p 83:83 \
-p 8022:22 \
--name gitlab \
--restart always \
-v /home/docker/gitlab/etc:/etc/gitlab \
-v /home/docker/gitlab/log:/var/log/gitlab \
-v /home/docker/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce
# 【4】 修改gitlab配置(目录为我上文安装的目录)
vi /home/docker/gitlab/etc/gitlab.rb
#附:以下修改或添加的内容
# 1.http协议访问地址,不加端口号默端口为 80 (改成部署机器的域名或者IP地址)我这里配置8090
external_url 'http://192.168.36.110:83'
# 2.配置ssh协议访问地址和端口
gitlab_rails['gitlab_ssh_host'] = '192.168.36.110'
# 3.修改端口。docker run 时22端口映射的 8022 端口
gitlab_rails['gitlab_shell_ssh_port'] = 8022
# 【5】 修改gitlab配置(目录为我上文安装的目录)
vi /home/docker/gitlab/data/gitlab-rails/etc/gitlab.yml
#附:以下修改或添加的内容
# 1.将 host 的值改成映射的外部主机 ip 地址和端口,这里会显示在 gitlab 的 clone with http克隆地址
# 2.修改ssh_host
ssh_host: 192.168.36.110
# 3.修改 ssh_port容器启动后映射的端口
ssh_port: 8022
# 【6】 重启
docker restart gitlab
# 【7】 初始化admin账号密码
# 1.进入容器
docker exec -it gitlab /bin/bash
# 2.启动Ruby on Rails控制台,需要等待较长时间
gitlab-rails console
# 3.找到root用户,以下方式或者 user = User.find_by(email: 'admin@example.com')
user = User.where(id: 1).first
# 4.更改密码,这里需要8位密码,少了会保存失败
user.password = '你的密码'
# 5.确认密码
user.password_confirmation = '你的密码'
# 6.保存更改
user.save
# 【8】 登录root 创建一个账号并设置密码登录,创建一个空项目(你也可以直接使用root账号)登录地址为:http://ip:83
# 设置ssh(以下皆本地windows cmd 内操作)
# 1.进入公钥目录(正常都在windows 下的目录:C:\Users\xxx\.ssh,xxx为自己电脑命名)
cd ~/.ssh
# 2.执行以下命令,后面跟的是邮箱,你可以为已经创建的邮箱。如root的(root默认邮箱为admin@example.com)这里用的是我自己创建的(不会创建可以参考上文博客,自己摸索下gitlab管理界面就会了,很简单)
ssh-keygen -t rsa -C "alone@123.com"
# 3.设置文件名,为了区分现在或者未来多个git账号,这里还是要指定下生成的名称防止覆盖,即看到以下提示后,在冒号后输入自己定义的名称,这里我命名为 id_rsa_gitlab_alone。
Enter file in which to save the key (/c/Users/icecr/.ssh/id_rsa):id_rsa_gitlab_alone
# 4.一路回车,创建成功
# 将生成的id_rsa_gitlab_alone.pub 中的内容拷贝到gitlab并添加ssh key(看不懂去看上文博客)
# 5.配置目录下的 config 文件(之前没有设置过就创建一个)这是为了以后本地能配置多个git账号并行使用。添加以下配置
#Host 这里配置 gitlab ip地址,也支持域名
Host 192.168.36.110
#User 配置用户名称。看你要配置哪个账号,要与上文生成的key是同账号。如果是root就root,我这里是上文创建的alone
User alone
#IdentityFile 配置的是生成的秘钥路径
IdentityFile ~/.ssh/id_rsa_gitlab_alone
1.10.Jenkins安装
提示:jenkins放最后安装是有道理的。因为jenkins要使用或者依赖以上安装的各个环境或者插件,所以启动jenkins时挂载目录需要上面安装后才能确定。这里为了方便我采用docker安装,并且安装的是最新版本
# 【1】 下载jenkins镜像
docker pull jenkins/jenkins:lts
# 【2】 创建并授权安装目录
sudo mkdir -p /home/docker/jenkins
sudo chmod 777 /home/docker/jenkins
#docker路径授权
sudo chmod 777 /var/run/docker.sock
# 【3】启动,设置端口映射,配置挂载目录
docker run \
-d \
-p 81:8080 \
-p 50000:50000 \
--name jenkins \
--restart always \
-v /home/docker/jenkins:/var/jenkins_home \
-v /etc/localtime:/etc/localtime \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v /usr/local/maven/apache-maven-3.6.3:/usr/local/maven \
-v /usr/local/maven/repo:/usr/local/maven/repo \
-v /usr/local/java/jdk1.8.0_202:/usr/local/java/jdk \
-v /usr/local/gradle/gradle-6.7:/usr/local/gradle \
-v /usr/local/git/git-2.25.1:/usr/local/git \
jenkins/jenkins:lts
#-p 81:8080 映射容器内端口,启动后可通过81端口访问
#-p 50000:50000 映射端口,jenkins有两个端口需要配置映射
#--restart always 为方便虚拟机重启时候容器自动启动
#-v /home/docker/jenkins:/var/jenkins_home 挂载工作目录,这是jenkins的工作目录
#-v /etc/localtime:/etc/localtime 挂载服务器时间
#-v /var/run/docker.sock:/var/run/docker.sock 挂载容器通信路径
#-v /usr/bin/docker:/usr/bin/docker 挂载docker命令工具
#后续都为 maven,jdk,gradle,git的挂载
# 【4】 进入配置文件,配置加速
cd /home/docker/jenkins/
vi hudson.model.UpdateCenter.xml
# 配置地址如下,可拷贝地址粘贴对应位置即可
<sites>
<site>
<id>default</id>
<url>https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</url>
</site>
</sites>
# 【5】 登录获取初始化密码路径。登录如:http://192.168.36.110:81/
# cat 上一步管理平台上得到的路径,获取初始化的admin登录密码
docker exec -it jenkins /bin/bash
cat /var/jenkins_home/secrets/initialAdminPassword
# 拷贝cat后获取的密码,输入密码登录。
# 【6】执行安装,选择安装推荐插件。等待安装成功
注意:如果上文不进行docker路径授权【chmod 777 /var/run/docker.sock】会报以下错误:
(java.io.IOException) caught when processing request to {}->unix://localhost:80: Permission denied
1.11.Jenkins配置
1.系统设置 > 全局工具配置
2.配置 JDK
3.配置 Git
4.配置 Gradle (本文实践没有使用到,可以跳过)
5.配置 Maven
5.配置 Git 全局ssh凭证
系统管理 > Manage Credentials
> 添加全局凭证
>添加以下内容
提示:这里类型要选择 ssh username with private key,username 自己取无所谓,key需要粘贴上文安装gitlab配置生成的账号的私钥,记住是私钥,而非 public后缀的公钥。拷贝私钥到 key 中粘贴,保存确定
>创建成功,获取到凭证id
提示:创建成功后,记住全局凭证id,下文创建项目配置需要用到
1.12.创建springboot项目
提示:我这里就简单写了一个接口,项目增加 Dockerfile 用来构建镜像,项目目录结构如下图。创建成功编写好代码后提交到你的 gitlab中(不懂得可以查看上文提到的博客《Docker安装GitLab与基本操作》)
部分 pom 配置展示
Dockerfile
FROM docker.io/relateiq/oracle-java8
#VOLUME /tmp
ADD jenkins-boot-test-0.0.1-SNAPSHOT.jar app.jar
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
#RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
pom.xml 增加以下配置,用来使用 mvn docker:build打包构建镜像
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<!-- 镜像名称,我这里使用工程的 artifactId 即我pom中配置的值 <artifactId>jenkins-boot-test</artifactId> -->
<imageName>${project.artifactId}</imageName>
<!-- 项目中 Dockerfile 文件路径 -->
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>nexus</id>
<name>test public</name>
<layout>default</layout>
<!-- 复制nexus中的maven-public url -->
<url>http://192.168.36.110:82/repository/maven-public/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
二、使用Jenkins打包
2.1.创建任务
>新建任务
>选择自由风格,输入任务名称,名称自己取不重要
源码管理 > 配置gitlab项目代码地址
提示:Repository URL 是在gitlab 对应的项目下拷贝的ssh地址。Credentials 下的下拉框选择上文配置的全局凭证git ssh。分支选择你要构建的代码分支,我是自己创建了并提交代码到一个develop分支,所以这里设置开发分支。如果这里配置git会提示奇怪的错误,可能是你上文git配置中挂载的目录没有加 /bin/git,所以没有识别到可执行工具
构建 > 配置maven执行脚本
# 构建选择调用顶层 maven 目标,配置的maven版本(下拉框选择上文配置的maven)
# 目标
clean install -Dmaven.test.skip=true
构建 > 配置构建脚本
提示:这里为什么要进行稍微复杂一些的运行容器,镜像判断呢?这是为了重新构建时候不会报错,会先去停止运行的容器,删除镜像再进行镜像重新打包。后续如果个人需要推送进行到仓库,可以在以下脚本中添加,这里就怎么简单怎么来
#!/bin/sh
#接收外部参数
containerName=jenkins-boot-test
imageName=jenkins-boot-test
echo "$imageName"
#查询容器是否存在,存在则删除
containerId=`docker ps -a | grep -w ${containerName} | awk '{print $1}'`
if [ "$containerId" != "" ] ; then
#停掉容器
docker stop $containerId
#删除容器
docker rm $containerId
echo "成功删除容器"
fi
#查询镜像是否存在,存在则删除
imageId=`docker images | grep -w $containerName | awk '{print $3}'`
if [ "$imageId" != "" ] ; then
#删除镜像
docker rmi -f $imageId
echo "成功删除镜像"
fi
# 构建,这里mvn执行的路径为挂载的路径下/bin下
/usr/local/maven/bin/mvn docker:build
# 启动容器,由于我springboot项目是8083端口
docker run -p 8083:8083 -d --name $containerName $imageName
echo "容器启动成功"
2.2.立即构建
>立即构建
>可查看控制台输出日志
查看日志,构建成功结果打印
2.3.测试验证
>我再进行接口返回结果代码修改,然后提交到 gitlab,测试重新构建后是否有变更
>提交gitlab
提示:截图只截了 push 指令,你要记得先的 commit
>立即构建 >构建成功 >验证
完美!