Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。常用的版本控制工具有SVN、GIT,构建工具有Maven、Ant、Gradle。

Jenkins官方网站

实验前必须安装的环境:JDK11+、docker、docker-compose、tomcat9+、maven、Git、vim、wget。

实验过程:在本地IDE开发,提交代码到Gitlab仓库,Jenkins自动监测仓库代码的变化,使用使用docker-compose自动化部署。

Gitlab安装

官网安装文档

配置要求:

内存:最低4G以上,建议6G

内核版本:3.10以上(查看内核版本命令:uname -r)

介绍

GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务。简单来说就是类似GitHub的一个Git开源代码管理平台,只是Gitlab可以自己搭建随意使用,可以用于小团队并且完全不用担心代码泄露。

方式一:docker安装(推荐)

新建文件夹用于存放Gitlab数据

1
mkdir /opt/gitlab/{config,logs,data}

使用docker-compose安装

1
cd /opt/gitlab && vim docker-compose.yml

docker-compose.yml写入以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: '3'
services:
gitlab:
image: 'gitlab/gitlab-ce:latest'
container_name: gitlab
restart: always
environment:
TZ: 'Asia/Shanghai' #设置时区
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['time_zone'] = 'Asia/Shanghai'
external_url 'http://192.168.2.12:980' #要修改成自己的centos7的IP
gitlab_rails['gitlab_shell_ssh_port'] = 2224 #使用ssh远程Gitlab端口
ports:
- '980:980'
- '2224:22'
volumes:
#将相关配置映射到当前目录下的config目录
- '/opt/gitlab/config:/etc/gitlab'
#将日志映射到当前目录下的logs目录
- '/opt/gitlab/logs:/var/log/gitlab'
#将数据映射到当前目录下的data目录
- '/opt/gitlab/data:/var/opt/gitlab'

构建容器

1
docker-compose up -d
  • up:表示运行容器并在前台运行
  • -d:表示运行容器在后台运行

浏览器打开Gitlab

  1. 开放980、2224端口端口(关闭防火墙:systemctl stop firewalld.service)
  2. 运行完docker-compose up -d指令后
  3. 在浏览器打开http://IP:980即可

初次访问Gitlab可能会出现502页面,Gitlab比较消耗资源,需要一点时间加载,等2分钟左右再刷新访问就没问题了,如果还时502,你应该看看是不是虚拟机的内存不够大

方式二:直接安装

官方安装文档:https://gitlab.cn/install/?version=ce

安装依赖

1
2
3
4
5
6
# 安装依赖
sudo yum install -y curl policycoreutils-python openssh-server perl
# 启用 sshd
sudo systemctl enable sshd
# 启动 sshd程序
sudo systemctl start sshd

配置镜像

1
curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash

开始安装

1
sudo EXTERNAL_URL="http://192.168.44.103" yum install -y gitlab-jh

除非您在安装过程中指定了自定义密码,否则将随机生成一个密码并存储在 /etc/gitlab/initial_root_password 文件中(出于安全原因,24 小时后,此文件会被第一次 gitlab-ctl reconfigure 自动删除,因此若使用随机密码登录,建议安装成功初始登录成功之后,立即修改初始密码)。使用此密码和用户名 root 登录。

gitlab常用命令

1
2
3
4
5
6
7
gitlab-ctl start                  # 启动所有 gitlab 组件;
gitlab-ctl stop # 停止所有 gitlab 组件;
gitlab-ctl restart # 重启所有 gitlab 组件;
gitlab-ctl status # 查看服务状态;
gitlab-ctl reconfigure # 启动服务;
vim /etc/gitlab/gitlab.rb # 修改默认的配置文件;
gitlab-ctl tail # 查看日志;

安装Jenkins

如果你是使用官网最新的Jenkins,建议先看一下官方文档

安装最新版的Jenkins是有要求的,博主安装的版本是2.346.3LTS版本,需要JDK版本至少JDK11以上,如果你下载的Jenkins比我安装的还高,可能要求有点改变了。

使用war包方式安装Jenkins

下载Jenkins.war包

1
wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/2.346.3/jenkins.war

将war包复制到tomcat下

暂停tomcat

在复制Jenkins.war包之前,需要将tomcat暂停一下,避免出问题。

1
{tomcat安装目录}/tomcat9/bin/shutdown.sh

复制文件到tomcat下

1
cp jenkins.war {tomcat路径}/webapps/

打开Jenkins

启动tomcat

1
{tomcat安装目录}/tomcat9/bin/startup.sh

打开Jenkins

http://IP:8080/jenkins

配置Jenkins环境

所需环境:

  1. Gitlab(如果你还没安装Gitlan,你应该先去安装Gitlab)
  2. Git(yum -y install git)
  3. Jenkins需要安装这四个插件:GitLab Plugin、Generic Webhook Trigger、Gitlab Authentication、GitLab Logo(我已打包好放在以下链接)

Jenkins构建Gitlab必装四个插件:https://rookie1679.lanzouy.com/ikJqH0ducmfi

如果你还没安装JDK、Maven、Git你可以参考这篇文章去安装一下

参考这篇文章:https://blog.hikki.site/111f4f09.html

Jenkins配置maven

Manage Jenkins--->Global Tool Configeration

01Manage

02GlobalToolCfongi

maven下的settings.xml文件

03settings

Jenkins配置JDK

04jdk

Jenkins配置Git

05git

Jenkins配置maven

06maven

安装Jenkins插件

Jenkins集成Gitlab需要几个插件,我已经在官方下载并打包好并放在以下,有需要自己取,或者自己去官网下载也是可以的

  1. GitLab Plugin
  2. Generic Webhook Trigger
  3. Gitlab Authentication
  4. GitLab Logo

官网插件下载地址:https://plugins.jenkins.io/

插件下载地址:https://rookie1679.lanzouy.com/ikJqH0ducmfi

Manage Jenkins—>Manage Plugins—>高级—>Deploy Plugin—>上传文件—>Deploy—>勾选安装完重启Jenkins

07安装插件

前言

我一开始在给容器命名的时候,是使用了下划线,在构建完的时候,我在浏览器打不开我的项目,访问总是返回400,查了一下,是nginx不支持下划线的,会自动将下划线改为-,就一直访问失败,所以我后面将_改为-,如果你看到_,你应该将它改为``-`。

创建Git仓库

如果你有需要选择其他模板可以选择模板创建,比如spring boot。

01创建Git仓库

初始化idea开发环境

新建项目

02创建本地项目

测试项目

测试项目是否正常运行,浏览器打开http://localhost:8080/hi项目正常运行

03本地开发已完成

推送代码至Git仓库

  1. 勾选需要推送的代码
  2. 提交备注是必填项
  3. 然后点击提交并推送(推送到Gitlab)

04推送代码

打开Git仓库刷新查看是否推送成功

如下图可以看到代码已经推送成功了

05提交代码到git仓库成功

Jenkins添加Gitlab用户凭证

在Jenkins添加Gitlab的用户凭证,为了后面在Jenkins绑定Gitlab仓库进行其他操作做准备。

添加的用户名和密码为Gitlab的用户和密码。

05新建用户凭证

初始化Jenkins任务

新建Item--->输入任务名称--->构建一个maven项目--->确定--->Git--->填写Repository URL(Git仓库地址)--->Credentials(选择用户,没有就新建一个)--->构建触发器--->Build when a change is pushed to GitLab. GitLab webhook--->高级--->Secret token--->Generate--->复制token到Gitlab Secret 令牌--->去除SSL验证--->Add webhook--->Build--->填写Goals and options--->Run only if build succeeds--->保存

1
clean package -Dmaven.test.skip=true

重点:去掉SSL验证,除非你有SSL证书,否则不要勾选

06新建Jenkins任务

源码管理中,选择Git,添加如下信息,如果在Credentials没有用户可以选择,你应该去Jenkins凭据管理添加一个Gitlab用户和密码,再过来选择用户。

构建Jenkins任务

当构建结束后,看到绿色的小勾,说明已经构建成功了。如果执行失败,打开控制台输出可以看到错误内容了。

07开始构建

构建Docker镜像

构建两个容器,一个nginx容器负责反向代理,web-server-auto负责运行我们开发代码的war包,通过容器化,减少依赖对系统环境的影响,而且容器化更方便管理,可以提高效率。

  • /home/docker/nginx:nginx映射目录

  • /home/auto:用于存放Dockerfile、项目jar包、docker-compose.yml

初始化工作目录

1
mkdir /home/auto && cd /home/auto

复制auto-0.0.1-SNAPSHOT.war包到工作目录

刚刚我们已经在Jenkins完成简单的构建了,在构建完成时,会在/root/.jenkins/workspace/auto/target下生成auto-0.0.1-SNAPSHOT.war包,我们需要将war包构建成Docker镜像。

1
cp /root/.jenkins/workspace/auto/target/auto-0.0.1-SNAPSHOT.war /home/auto/

Dockerfile与docker-compose

Dockerfile编写

1
vim Dockerfile

将以下内容写入Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 拉取镜像
FROM openjdk:11
# 作者信息
MAINTAINER wtl
#开放端口
EXPOSE 8080
#挂载目录
VOLUME /home/auto
#执行shell指令
RUN mkdir -p /home/auto
#执行工作目录
WORKDIR /home/auto
#复制宿主机文件到镜像中
COPY auto-0.0.1-SNAPSHOT.war /home/auto/auto-0.0.1-SNAPSHOT.war
#开始认证服务
ENTRYPOINT ["java","-jar","auto-0.0.1-SNAPSHOT.war"]

编写docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
version: "3.1"
services:
nginx_auto: #服务名称,自定义
image: nginx:latest #镜像版本
restart: always
container_name: nginx-auto
privileged: true #解决nginx的文件调用的权限问题
environment:
- TZ=Asia/Shanghai
ports: #暴露端口
- "801:80"
- "4444:443"
volumes:
- /home/docker/nginx/nginx.conf:/etc/nginx/nginx.conf
- /home/docker/nginx/log:/var/log/nginx
links:
- web-server-auto # 将容器nginx_auto连接到web-server-auto

web-server-auto:
restart: always
environment:
- TZ=Asia/Shanghai # 设置时区
build:
context: /home/auto # 构建文件的路径
dockerfile: Dockerfile #构建文件Dockerfile
container_name: web-server-auto #容器名字,可自定义
ports: # 暴露端口 宿主机端口:docker容器端口
- 7889:8080

09创建docker

添加执行权限

/home/auto/文件夹下的所有文件都给予执行权限,因为该文件夹下存储着Dockerfile和docker-compose.yml、jar包,这些文件需要执行权限。

1
chmod +x -R /home/auto/
  • -R :对目前目录下的所有档案与子目录进行相同的权限变更(即以递回的方式逐个变更)

添加脚本

添加执行脚本

Jenkins实时监测Gitlab中auto仓库的代码变动,一旦有代码更新,Jenkins就会实时构建,在构建时,我们可以添加一些脚本来达到我们想要的目的,比如我们添加如下脚本,表示再构建时删除旧的容器的镜像,重新生成新的容器和镜像。

auto--->配置--->Post Steps--->Run only if build succeeds--->Add post-build step--->Excute shell--->在输入框中输入以下shell脚本--->保存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/sh
WORKSPACE_DIR='/root/.jenkins/workspace/auto/'
DEVOPS_DIR='/home/auto'

echo "删除之前的容器"
docker ps -a | grep web-server-auto | awk '{print $1}' | xargs docker rm -f
docker ps -a | grep nginx-auto | awk '{print $1}' | xargs docker rm -f

echo "删除上一个版本的jar包"
sudo rm -rf ${DEVOPS_DIR}/auto-0.0.1-SNAPSHOT.war
echo "复制打包最新版的jar包"
cp ${WORKSPACE_DIR}/target/auto-0.0.1-SNAPSHOT.war ${DEVOPS_DIR}
echo "赋予jar包权限"
chmod 777 -R /home/auto
echo "启动容器"
cd /home/auto/
docker-compose up -d

08添加Jenkins执行脚本

测试结果

在添加完脚本后,我们来测试一下刚刚添加的脚本是否执行成功。

在Gitlab打开Git仓库,设置—>Webhooks—>测试—>Push events

10提交测试

测试结果出错

出错了,打开控制台看看我的错误是什么。

auto--->构建记录--->控制台输出--->查看错误

11打开控制台查看错误

12运行出错

解决错误

大概意思说删除的容器指令出错,返回错误。

1
2
docker ps -a | grep web-server-auto | awk '{print $1}' | xargs docker rm -f
docker ps -a | grep nginx-auto | awk '{print $1}' | xargs docker rm -f

我们在Jenkins任务中添加了shell指令,以上是部分的指令。

我们一开始是不存在web-server-auto、nginx-auto容器的,直接查找该容器并删除,但是容器不存在的,系统就说指令不正确了,那我们就把指令稍微改一改,在指令后面添加一下确定的容器名字应该就没问题了。

1
2
docker ps -a | grep web-server-auto | awk '{print $1}' | xargs docker rm -f web-server-auto
docker ps -a | grep nginx-auto | awk '{print $1}' | xargs docker rm -f nginx-auto

等第一次启动完,再把指令改为原来的指令就不会出错了。

13解决错误

重新构建

10提交测试

构建成功

重新构建后应该是成功了。

成功后在浏览器打开http://192.168.2.12:801/hi,其中的IP地址改为你的IP地址,这时,浏览器显示出来了,但是我们还没完全成功,这只是初步显示出来了,还不够完善

14运行成功

完善Jenkins任务

完善shell脚本

原来的脚本中,只是可以新建容器和镜像,可能会出现一些奇怪的问题,我们应该在每次构建时删除旧的容器和镜像,重新构建新的镜像和容器,减少环境对构建的影响。

将以下脚本内容复制到Jenkins任务中

auto--->Post Steps--->Excute shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/sh
WORKSPACE_DIR='/root/.jenkins/workspace/auto/'
DEVOPS_DIR='/home/auto/'

echo "删除之前的容器"
docker ps -a | grep web-server-auto | awk '{print $1}' | xargs docker rm -f
docker ps -a | grep nginx-auto | awk '{print $1}' | xargs docker rm -f

echo "删除上一个版本的jar包"
sudo rm -rf ${DEVOPS_DIR}/auto-0.0.1-SNAPSHOT.war
echo "复制打包最新版的jar包"
cp ${WORKSPACE_DIR}/target/auto-0.0.1-SNAPSHOT.war ${DEVOPS_DIR}
echo "赋予jar包权限"
chmod 777 -R /home/auto
echo "删除镜像"
docker rmi -f auto_web-server-auto
echo "启动容器"
cd /home/auto/
docker-compose up -d

15完善shell脚本

推送代码构建

在本地idea开发,推送代码到Gitlab,Jenkins检测到Gitlab仓库的更新,实时构建,构建完即可在浏览器打开预览内容。http://IP:801/hi

16实时更新内容

此次学会了自动构建maven项目的构建,其实还是很方便的,以后开发的还是直接push,然后打开浏览器一看,减少自己操作的时间。

其他

重启、关闭、重载jenkins

重启jenkins

在jenkins后面加上restart

1
http://localhost:8080/jenkins/restart

关闭jenkins

在jenkins后面加上exit

1
http://localhost:8080/jenkins/exit

重载jenkins

在jenkins后面加上reload

1
http://localhost:8080/jenkins/reload

可能遇到的错误

maven拒绝http请求

1
2
3
ERROR: Failed to parse POMs
org.apache.maven.project.ProjectBuildingException: Some problems were encountered while processing the POMs:
[FATAL] Non-resolvable parent POM for com.example:devops:0.0.1-SNAPSHOT: org.springframework.boot:spring-boot-starter-parent:pom:2.7.4 failed to transfer from http://0.0.0.0/ during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of maven-default-http-blocker has elapsed or updates are forced. Original error: Could not transfer artifact org.springframework.boot:spring-boot-starter-parent:pom:2.7.4 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [alimaven (http://maven.aliyun.com/nexus/content/groups/public/, default, releases)] and 'parent.relativePath' points at no local POM @ line 5, column 13

解决办法

不提示http请求不安全,换一个镜像站即可解决问题

02修改settings

返回400-Rad Request

返回400

解决方法

nginx是不支持下划线的_,但是我在容器中使用了下划线,同时nginx也使用到了这个容器,就报错了,将所有的下划线都改为-即可。

报错内容

02无法打开共享对象

解决办法

如图,这真的是个大坑,搞了好久,去除这个转发X11就解决了

01不要打勾