基于CentOS8,从0开始搭建Jenkins+GitLab+Maven持续集成,自动构建SpringBoot项目案例

一、环境准备

创建三台虚拟机

服务器名操作系统IP说明
GitLabCentOS 8192.168.225.129部署GitLab
JenkinsCentOS 8192.168.225.130部署Jenkins
ServerCentOS 8192.168.225.131部署Maven

二、GitLab服务器环境搭建

①、安装基础依赖

#安装基础依赖
sudo yum install -y curl policycoreutils-python-utils openssh-server

#启动ssh服务&设置为开机启动
sudo systemctl enable sshd
sudo systemctl start sshd

②、安装Postfix

Postfix是一个邮件服务器,GitLab发送邮件需要用到

#安装postfix
sudo yum install -y postfix

#启动postfix并设置为开机启动
sudo systemctl enable postfix
sudo systemctl start postfix

③、开放ssh以及http服务(80端口)

#开放ssh、http服务
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --add-service=http --permanent

#重载防火墙规则
sudo firewall-cmd --reload

④、安装GitLab

添加GitLab社区版Package

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash

安装GitLab社区版

sudo yum install -y gitlab-ce

安装成功后shell窗口会打印出GitLabLogo

image-20211003162910986

⑤、配置GitLab站点Url

GitLab默认的配置文件路径是/etc/gitlab/gitlab.rb,我们需要做的就是将默认Url修改为当前机器的IP即可

external_url 'http://192.168.225.129'

image-20211003163347049

⑥、刷新配置启动GitLab

#重新配置并启动
sudo gitlab-ctl reconfigure

时间会有点长,等待一下即可,当看见如下内容的时候,证明重启成功了

image-20211003170026257

访问http://192.168.225.129/

image-20211003164024194

初始管理员账号为root,密码需要手动查看一下

cat /etc/gitlab/initial_root_password 

将打印出来的密码复制,然后登录

image-20211003164309915

image-20211003164403606

⑦、GitLab常用配置

Ⅰ、邮件配置

配置邮箱可以让GitLab在发生相应事件的时候进行邮件通知,比如:找回密码、添加邮箱等,这里已QQ邮箱为例

image-20211003165215341

gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.example.qq.server"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "xx@qq.com"
gitlab_rails['smtp_password'] = "xx"
# gitlab_rails['smtp_domain'] = "example.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = 'xx@qq.com'
# gitlab_rails['smtp_pool'] = false

配置完毕需要刷新配置重启

sudo gitlab-ctl reconfigure

Ⅱ、禁用创建组权限

GitLab默认所有的注册用户都可以创建组。但对于团队来说,通常只会给Leader相关权限。虽然可以在用户管理界面取消权限,但毕竟不方便。我们可以通过配置GitLab默认禁用创建组权限。还是刚才的配置文件,找到gitlab_default_can_create_group取消注释,并将true改为false

gitlab_rails['gitlab_default_can_create_group'] = false

image-20211003165609979

配置完毕需要刷新配置重启

sudo gitlab-ctl reconfigure

⑧、gitlab-ctl常用命令

命令说明
check-config检查在gitlab中是否有任何配置。在指定版本中删除的rb
deploy-page安装部署页面
diff-config将用户配置与包可用配置进行比较
remove-accounts删除所有用户和组
upgrade升级
service-list查看所有服务
once如果GitLab服务停止了就启动服务,如果已启动就不做任何操作
restart重启GitLab服务
start如果GitLab服务停止了就启动服务,如果已启动就重启服务
stop停止GitLab服务
status查看GitLab服务状态
reconfigurereconfigure重新配置GitLab并启动

⑨、备注

至此GitLab服务创建完毕,可以创建一个自己的账号,用于后续对Maven项目进行构建,然后切换第二台Jenkins机器

三、Jenkins服务器环境搭建

①、JDK8安装

安装验证

sudo yum install -y java-1.8.0-openjdk*
java -version

复制JDK安装路径

#JDK8默认安装路径为/usr/lib/jvm
ls /usr/lib/jvm

image-20211003170824063

修改环境变量配置文件

vim /etc/profile

最后一行追加如下内容

JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.302.b08-0.el8_4.x86_64

PATH=$PATH:$JAVA_HOME/bin 

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar 

export JAVA_HOME CLASSPATH PATH

刷新配置

source /etc/profile

②、Nginx安装

由于Jenkins默认端口号不是80,所以这里部署Nginx是为了方便我们通过IP访问Jenkins,如果无此需求可忽略次操作

#安装
yum install nginx
#开机启动
sudo systemctl enable nginx
#启动
sudo systemctl start nginx
#开放80端口(nginx默认监听80端口)
firewall-cmd --add-port=80/tcp --permanent
#重载防火墙规则
firewall-cmd --reload

配置文件说明

1、全局配置文件:/etc/nginx/nginx.conf
2、默认配置文件:/etc/nginx/conf.d/default.conf

新增配置目录

#1、新增配置文件夹
sudo mkdir /etc/nginx/server
#2、修改默认配置(加载该文件夹下的配置)
sudo vim /etc/nginx/nginx.conf
#3、在http属性下的log_format后面追加
include /etc/nginx/server/*.conf;

image-20211003174251942

配置反向代理

#1、新建/修改配置文件
sudo vim /etc/nginx/server/jenkins.conf

#2、配置示例
server {
    listen       80;        #监听80端口
    server_name  192.168.225.130; #监听的域名
    log_format	 main	'$remote_addr - $remote_user [$time_local] $request '
    '"$status" $body_bytes_sent "$http_referer" '
					'"$http_user_agent" "$http_x_forwarded_for" "$gzip_ratio"';
    access_log  /var/log/nginx/jenkins.access.log main;
    error_log  /var/log/nginx/jenkins.error.log error;

    location / {            #转发或处理
        proxy_pass http://192.168.225.130:8080;
    }
    error_page   500 502 503 504  /50x.html;#错误页
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

重载Nginx配置

sudo nginx -s reload

③、Jenkins安装

yum源导入

#添加Yum源
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo

#导入密钥
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key

安装

sudo yum install -y jenkins --nobest

开放端口

#Jenkins站点的默认监听端口是8080
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload

配置Java可选路径,因为Jenkins默认的java可选路径不包含我们部署的jdk路径,所以这里要配置一下,不然Jenkins服务会启动失败

#1、新建/修改配置文件
sudo vim /etc/nginx/server/jenkins.conf

#2、配置示例
server {
    listen       80;        #监听80端口
    server_name  192.168.225.130; #监听的域名
    log_format	 main	'$remote_addr - $remote_user [$time_local] $request '
    '"$status" $body_bytes_sent "$http_referer" '
					'"$http_user_agent" "$http_x_forwarded_for" "$gzip_ratio"';
    access_log  /var/log/nginx/jenkins.access.log main;
    error_log  /var/log/nginx/jenkins.error.log error;

    location / {            #转发或处理
        proxy_pass http://192.168.225.130:8080;
    }
    error_page   500 502 503 504  /50x.html;#错误页
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

启动Jenkins并设置Jenkins开机启动

#重载服务(由于前面修改了Jenkins启动脚本)
sudo systemctl daemon-reload
#启动Jenkins服务
sudo systemctl start jenkins
#将Jenkins服务设置为开机启动
#由于Jenkins不是Native Service,所以需要用chkconfig命令而不是systemctl命令
sudo /sbin/chkconfig jenkins on

Ⅰ、错误排查

直接通过域名访问,反向代理失败

image-20211003174800110

查看日志

#查看错误信息
cat /var/log/nginx/jenkins.error.log
#错误信息示例connect() to 192.168.225.130:8080 failed (13: Permission denied)

需要配置SELinux

  • 方法1:
setsebool -P httpd_can_network_connect 1
  • 方法2:
#关闭SELinux:
sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
#重启:
reboot

④、Jenkins初始化

登录Jenkins

image-20211003175119601

查看密码

cat /var/lib/jenkins/secrets/initialAdminPassword

安装推荐的插件

image-20211003175229153

image-20211003175251065

添加管理员

image-20211003175632979

配置Jenkins URL ,这里的URL指的是默认访问Jenkins的地址。默认是是http://:8080,如果这里通过Nginx配置了域名,那么直接填写配置的域名即可。

image-20211003175808854

点击保存并完成即可进入主页

image-20211003175844425

⑤、Maven安装

下载安装

#进入软件下载目录
cd /home/phz/Downloads

#下载压缩包
wget https://dlcdn.apache.org/maven/maven-3/3.8.2/binaries/apache-maven-3.8.2-bin.tar.gz

#创建软件安装目录
mkdir /usr/maven

#解压到指定目录
sudo tar -zxvf apache-maven-3.8.2-bin.tar.gz -C /usr/maven/

环境变量,编辑/etc/profile,末尾添加如下内容

export M2_HOME=/usr/maven/apache-maven-3.8.2export PATH=$PATH:${M2_HOME}/bin

配置生效

source /etc/profile

修改阿里云镜像仓库,进入Maven配置文件夹,使用Vim编译配置文件

cd /usr/maven/apache-maven-3.8.2/conf/vim settings.xml 

将图示位置的镜像源地址更改为阿里云

<mirror>
    <id>alimaven</id>
    <mirrorOf>central</mirrorOf>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>

<mirror>
    <id>repo1</id>
    <mirrorOf>central</mirrorOf>
    <name>Human Readable Name for this Mirror.</name>
    <url>http://repo1.maven.org/maven2/</url>
</mirror>

<mirror>
    <id>repo2</id>
    <mirrorOf>central</mirrorOf>
    <name>Human Readable Name for this Mirror.</name>
    <url>http://repo2.maven.org/maven2/</url>
</mirror> 

image-20211003182735753

⑥、Git安装

下载

sudo yum install -y git

密钥准备,直接回车

ssh-keygen -t rsa

将公钥添加到GitLab,访问http://192.168.225.129/-/profile/keysGitLab服务器),或者在GitLab主页右上角点击edit profile,然后点击SSH key添加公钥

#查看公钥
cat ~/.ssh/id_rsa.pub

image-20211003183617736

添加Git SSH凭据,后面配置Jenkins构建任务代码仓库时需要用到,访问http://192.168.225.130/credentials/store/system/domain/_/newCredentialsJenkins服务器)

image-20211003184458023

⑦、插件安装

插件名版本说明
Maven Integration3.13使用Maven进行编译等
Publish Over SSH1.20.1用于将编译结果发布到远程服务器

插件安装

image-20211003191327033

Ⅰ、问题处理

在安装完部分插件后,jenkins可能会出现部分功能翻译失败的情况,解决办法如下

  • Manage Jenkins=>Configure System

image-20211003191617439

  • 配置Default Languagezh_US,并勾选下面的单选框,然后点击保存

image-20211003191724985

  • 然后重启Jenkins,方式有两种
#1、命令行重启
sudo service jenkins restart#或
sudo systemctl restart jenkins
#2、访问URL方式重启http://192.168.225.130/restart
  • 重启成功后,再次访问当前页面,将刚刚的更改重新设置为zh_CN,然后保存就可以看到页面恢复正常

⑧、Jenkins环境配置

进入系统管理->全局工具配置中对插件相关工具、

  • JDK

image-20211003192253213

  • Git

image-20211003192324973

  • Maven

image-20211003192501941

最后点击保存即可

⑨、备注

至此Jenkins服务创建完毕,然后切换第三台Maven项目机器

四、Maven应用服务器环境搭建

①、JDK8安装

安装验证

sudo yum install -y java-1.8.0-openjdk*java -version

复制JDK安装路径

#JDK8默认安装路径为/usr/lib/jvmls /usr/lib/jvm

image-20211003170824063

修改环境变量配置文件

vim /etc/profile

最后一行追加如下内容

JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.302.b08-0.el8_4.x86_64

PATH=$PATH:$JAVA_HOME/bin 

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar 

export JAVA_HOME CLASSPATH PATH

刷新配置

source /etc/profile

②、创建部署应用专属账号

#创建账号
sudo useradd app
sudo passwd app

#授予sudo权限且免密码
sudo visudo
#在最后一行加上
app ALL=(ALL) NOPASSWD:ALL

image-20211003181445635

③、开放端口

#开放1000到9999的端口
sudo firewall-cmd --add-port=1000-9999/tcp --permanent
sudo firewall-cmd --reload

④、创建应用部署目录

#创建目录
sudo mkdir -p /webroot

#授权
sudo chown -R app:app /webroot

⑤、配置Jenkins

进入Jenkins服务器:

点击系统管理->系统设置对Publish over SSH进行设置

image-20211003193053281

主要配置项说明:

配置项说明
Name服务器名,随便写,方便记忆即可
Hostname服务器IP,或者可以被正常解析的服务器名/域名
Username用于登录的账号
Remote Dictionary远程目录,绝对路径
Passphrase/Password密码
PortSSH端口

配置完毕后测试是否配置成功,显示success后即可保存

image-20211003193413431

⑥、创建SpringBoot应用

创建工程

image-20211003193826003

image-20211003193901122

新建Java文件夹和Resource文件夹

image-20211003194341556

修改POM文件

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.phz</groupId>
    <artifactId>HelloWorld</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>HelloWorld Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>HelloWorld</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>false</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

创建主启动类

/**
 * @author PengHuAnZhi
 * @ProjectName HelloWorld
 * @Description TODO
 * @time 2021/10/3 19:46
 */
@SpringBootApplication
public class HelloWorldApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloWorldApplication.class, args);
    }
}

创建Controller

/**
 * @author PengHuAnZhi
 * @ProjectName HelloWorld
 * @Description TODO
 * @time 2021/10/3 19:47
 */
@Controller
public class HelloController {
    @RequestMapping("/")
    @ResponseBody
    String helloWorld() {
        return "Hello World";
    }
}

启动项目测试

image-20211003195007999

⑦、GitLab创建项目

image-20211003195624477

初始化本地项目

image-20211003200240178

将本地代码提交到本地仓库

image-20211003200406268

然后点击push

image-20211003200504193

点击Define Remote

image-20211003200517217

将远程仓库地址填入

image-20211003200601969

最后点击push,查看远程仓库master分支

image-20211003200706090

五、Jenkins任务创建

①、新建任务

主页点击新建任务

image-20211003200828672

②、配置源码管理

image-20211003201728915

③、构建环境配置

image-20211003202003530

配置项说明:

配置项说明
NameappserverSSH Server名称,根据之前配置选择即可
Source filestarget/*.jar需要传输的文件,支持通配符,编译文件默认都在项目根目录下的target目录中
Remove prefixtarget移除匹配到的文件路径的前缀,如果留空,会在远程服务器上创建对应的目录
Remote directoryhelloworld/远程服务器上的项目目录,该目录会被创建在Publish over SSH配置的远程根目录中(/webroot)
Exec command见下面文件传输到远程服务器后执行的命令

命令示例:

APP_NAME=HelloWorld.jar
cd /webroot/helloworld
mkdir -p logs

#找到包含AppName的进程
PROCESS=`ps -ef|grep $APP_NAME|grep -v grep  |awk '{ print $2}'`
#循环停用进程直到成功
while :
do
  kill -9 $PROCESS > /dev/null 2>&1
  if [ $? -ne 0 ];then
   break
  else
   continue
fi
done
echo 'Stop Successed'

#启动应用
nohup  /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.302.b08-0.el8_4.x86_64/bin/java -jar $APP_NAME >>logs/start.log 2>>logs/startError.log &

#sleep等待15秒后,判断包含AppName的线程是否存在
sleep 15
if test $(pgrep -f $APP_NAME|wc -l) -eq 0
then
   echo "Start Failed"
else
   echo "Start Successed"
fi

最后保存,点击左边导航栏立即构建

image-20211003202338022

你也可以通过控制台实时查看构建日志

image-20211003202639869

image-20211003202653985

构建成功后当前任务会变成绿色小勾

image-20211003202741952

访问Maven应用服务器,成功

image-20211004093337852

④、配置触发器

触发器的触发条件有很多,这里只配置了一个,即想要每次提交都让Jenkins帮我们自动构建,在配置这个触发器之前,我们还需要添加两个插件,一个是GitLab,另一个是Gitlab Hook

image-20211004100120698

安装完成后,重新进入构建触发器页面,可以看到如图所示的选项

image-20211004100351940

http://192.168.225.130/project/HelloWorld链接复制下来,然后保存,然后进入Gitlab,使用管理员账号root登录,进入Setting找到Network,然后展开Outbound requests选项,将Allow requests to the local network from web hooks and services勾选上,然后保存更改

image-20211004101439578

然后回到项目的Setting

image-20211004101548731

将刚刚复制的URL粘贴到图示位置

image-20211004101620702

最后Add webhook即可

image-20211004101703178

image-20211004101717220

最后回到Jenkins的全局配置,往下拉,找到Enable authentication for '/project' end-point并取消勾选,保存

image-20211004101849062

最后我们测试一下提交代码

image-20211004102306687

image-20211004102318510

image-20211004102333942

六、备注

①、构建成功,但是目标文件夹中没有项目生成

一定要确定这段脚本中的APP_NAME一定要正确

APP_NAME=HelloWorld.jar
cd /webroot/helloworld
mkdir -p logs

#找到包含AppName的进程
PROCESS=`ps -ef|grep $APP_NAME|grep -v grep  |awk '{ print $2}'`
#循环停用进程直到成功
while :
do
  kill -9 $PROCESS > /dev/null 2>&1
  if [ $? -ne 0 ];then
   break
  else
   continue
fi
done
echo 'Stop Successed'

#启动应用
nohup  /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.302.b08-0.el8_4.x86_64/bin/java -jar $APP_NAME >>logs/start.log 2>>logs/startError.log &

#sleep等待15秒后,判断包含AppName的线程是否存在
sleep 15
if test $(pgrep -f $APP_NAME|wc -l) -eq 0
then
   echo "Start Failed"
else
   echo "Start Successed"
fi

image-20211004094214382

还有启动应用的时候jdk路径一定也要对应上

image-20211004094405073

②、 Exception when publishing, exception message [Permission denied]

这个问题就是手动在目标项目根目录/webroot下面手动新建了一个HelloWorld文件夹,而这个文件夹还是用的root用户创建,导致使用Jenkins配置的用户没有操作权限导致的,解决方案就是把这个文件夹删了,项目部署的时候会自动帮我们创建,不用担心这个


版权声明:本文为qq_43509535原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。