企业级DevOps: GitLab + Jenkins + Tomcat + Pipeline + sonarQube 搭建全流程

基本环境
| 名称 | IP地址 | 安装的软件 | 大小 |
|---|---|---|---|
| 代码托管服务器 | 192.48.75.70 | gitlab-ce-16.9.0 | 8+100G |
| 持续集成服务器 | 192.48.75.71 | Jenkins-2.504-1.1,JDK21,Maven3.6.2,Git | 16+100G |
| 应用测试服务器 | 192.48.75.72 | JDK1.8,Tomcat8.5 | 4+100G |
| 代码检查 | 192.48.75.73 | SonarQube | 4+100G |
[root@localhost ~]# hostnamectl set-hostname gitlab
[root@localhost ~]# hostnamectl set-hostname jenkins
[root@localhost ~]# hostnamectl set-hostname tomcat
[root@localhost ~]# vim /etc/hosts
.......
192.48.75.70 gitlab
192.48.75.71 jenkins
192.48.75.72 tomcat
部署GitLab
-
安装相关依赖
yum -y install policycoreutils openssh-server openssh-clients postfix policycoreutils-python* -
设置 启动ssh服务&设置为开机启动
systemctl enable sshd && sudo systemctl start sshd -
设置postfix开机自启,并启动,postfix支持gitlab发信功能
systemctl enable postfix && systemctl start postfix -
安装软件
[root@gitlab ~]# rpm -ivh --nodeps gitlab-ce-16.9.0-ce.0.el7.x86_64.rpm
这样代表安装成功 -
修改配置
vim /etc/gitlab/gitlab.rb 修改gitlab访问地址和端口,默认为80,我们改为82 external_url 'http://192.48.75.70:82' nginx['listen_port'] = 82 -
启动服务
gitlab-ctl reconfigure

-
启动
gitlab-ctl restart -
访问
ip:82
通过刚刚的初始化来查询密码
这个密码有时间限制, 24h 之后就不可以在用了
Username: root cat /etc/gitlab/initial_root_password
GitLab操作
初始化操作
-
修改密码
用户名: root
密码: Ran000000

-
登录
创建组
-
组的作用


创建项目

创建用户
- 创建用户


- 修改密码

用户名: zhangsan
密码: zhang000
将用户添加到组里面


Gitlab用户在组里面有5种不同权限:
Guest:可以创建issue、发表评论,不能读写版本库
Reporter:可以克隆代码,不能提交,QA、PM 可以赋予这个权限
Developer:可以克隆代码、开发、提交、push,普通开发可以赋予这个权限
Maintainer:可以创建项目、添加tag、保护分支、添加项目成员、编辑项目,核心开发可以赋予这个 权限
Owner:可以设置项目访问权限 - Visibility Level、删除项目、迁移项目、管理组成员,开发组组 长可以赋予这个权限
用zhangsan用户登录
- 登录

-
修改密码
这里默认之前的密码
用户名: zhangsan
密码: Zhang000

-
再次登录即可

上传项目到GitLab
-
开启版本控制


-
提交代码到本地仓库
-
先Add到缓存区

-
再Commit到本地仓库

-
推送到Gitlab项目仓库中




-
部署 Jenkins
-
设置时间同步 与 Windows
yum install -y chrony systemctl start chronyd && systemctl enable chronyd timedatectl set-ntp yes && timedatectl status && export LC_TIME="C"这里建议写一个 shell 脚本
-
安装JDK
Jenkins需要依赖JDK,所以先安装JDK21
注意:目前的 jdk21 如果要用 yum安装,我们没有相关的 秘钥, 网上大部分秘钥都已经不可用, 所以我们用 tar 包安装mkdir -p /usr/local/java tar -zxvf OpenJDK21U-jdk_x64_linux_hotspot_21.0.7_6.tar.gz -C /usr/local/java # 修改文件名称 cd /usr/local/java/ mv jdk-21.0.7+6/ jdk-21# 配置环境变量 vim /etc/profile ....... # 添加到最后一行即可 export JAVA_HOME=/usr/local/java/jdk-21 export PATH=$PATH:$JAVA_HOME/bin export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar # 加载一下环境变量 source /etc/profile # 设置开机自动加载 vim /root/.bashrc source /etc/profile测试java版本是否安装成功
[root@localhost ~]# java -version openjdk version "21.0.15" 2025-04-15 OpenJDK Runtime Environment Temurin-17.0.15+6 (build 17.0.15+6) OpenJDK 64-Bit Server VM Temurin-17.0.15+6 (build 17.0.15+6, mixed mode, sharing) -
获取Jenkins包
https://mirrors.aliyun.com/jenkins/redhat/jenkins-2.504-1.1.noarch.rpm
[root@jenkins ~]# rpm -ivh jenkins-2.504-1.1.noarch.rpm warning: jenkins-2.504-1.1.noarch.rpm: Header V4 RSA/SHA512 Signature, key ID ef5975ca: NOKEY Verifying... ################################# [100%] Preparing... ################################# [100%] Updating / installing... 1:jenkins-2.504-1.1 ################################# [100%] /usr/lib/tmpfiles.d/dbus.conf:13: Line references path below legacy directory /var/run/, updating /var/run/dbus/containers → /run/dbus/containers; please update the tmpfiles.d/ drop-in file accordingly. -
直接启动Jenkins
systemctl start jenkins -
这里直接启动会出现启动不了的情况
修改相关的配置
# 查找 java 的路径 [root@localhost ~]# readlink -f $(which java) /usr/local/java/jdk-21/bin/java # 实际的 JAVA_HOME=/usr/local/java/jdk-21 # 在 jenkins 的服务配置文件里修改 [root@localhost ~]# vim /usr/lib/systemd/system/jenkins.service # 在 Service 模块里面 最后 添加 ........... [Service] ..... Environment=JAVA_HOME=/usr/local/java/jdk-21 -
更新损坏的war包
# 完全删除旧文件 sudo rm -f /usr/share/java/jenkins.war # 从官方镜像下载(使用中国镜像加速) sudo wget -O /usr/share/java/jenkins.war \ https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/latest/jenkins.war # 验证文件可靠性 file /usr/share/java/jenkins.war md5sum /usr/share/java/jenkins.war ls -lh /usr/share/java/jenkins.war -
再次重启就可以了
sudo systemctl daemon-reload sudo systemctl restart jenkins默认端口 8080
访问: ip:8080
-
修改端口
由于这是新版的 Jenkins, 没有的默认的配置文件, 我们直接在 服务文件里面 修改即可
[root@localhost ~]# vim /usr/lib/systemd/system/jenkins.service ........ [Service] ...... ExecStart=/usr/bin/jenkins --httpPort=8090在 ExecStart 最后面添加 --httpPort=8090 即可
sudo systemctl daemon-reload sudo systemctl restart jenkins默认端口 8090
访问: ip:8090
Jenkins操作
初始化操作
-
查看密码

-
直接到终端查看
[root@localhost ~]# cat /var/lib/jenkins/secrets/initialAdminPassword d5303e645a3243e4be8ea84188997a59 -
插件选择


用户创建
用户名: lisi
密码: lisi000



插件管理
-
替换插件地址
cd /var/lib/jenkins/updates sed -i 's|https://updates.jenkins.io/update-center.json|https://repo.huaweicloud.com/jenkins/updates/current/update-center.json|g' default.json -
到网页的地方更新

https://repo.huaweicloud.com/jenkins/updates/current/update-center.json -
重启jenkins
-
安装汉化插件

-
重启

Jenkins 权限管理
安装授权策略插件
-
安装插件 Role-based Authorization Strategy


-
设置策略


创建角色
-
进入创建角色的页面


-
解释角色的不同定位
Global roles: 全局角色
Item roles: 项目角色, 不同的项目被不同的人访问
Agent roles: 节点角色, jenkins 主从的时候需要
-
Global roles

-
Item roles

这里的 tao.* 代表可以访问 tao 前缀的项目名称
创建用户
-
创建 Eric 和 Tom 两个角色




用户名: Eric 密码: Eric000
用户名: Tom 密码: Tom000
虽然这里创建了用户, 但是没有任何权限, 当登录的时候, 是没有任何菜单页面的
分配角色
- 这里只给 Eric 分配了角色, 、Tom也是一样的操作




创建项目测试
- 创建简单的两个项目, 然后进行测试



-
登录不同的用户进行测试
Eric 用户

由于 Eric 是可以访问带 tao 前缀的, 所以都能访问
Tom 用户

这里就能看出来不同了, Tom 只能访问 taoran 的项目
Jenkins凭证管理
凭证初始化
凭据可以用来存储需要密文保护的数据库密码、Gitlab密码信息、Docker私有仓库密码等,以便 Jenkins可以和这些第三方的应用进行交互。
-
安装插件 Credentials Binding


安装完成之后, 会在安全的地方多两个选项
-
添加凭证




Username with password: 用户名密码登录的凭证, 比如拉取gitlab代码
SSH Username with private key: SSH 的免密登录
Secrret file: 需要保密的文本文件,使用时Jenkins会将文件复制到一个临时目录中,再将文件路径设置到一个变量中,等构建结束后,所复制的Secret file就会被删除。
Secret text: 需要保存的一个加密的文本串,如钉钉机器人或Github的api token
Certificate: 通过上传证书文件的方式
Jenkins拉取GitLab代码
-
安装插件 Git

-
测试


如果这里出现了 Git 就说明安装成功
-
在Jenkins服务器上安装 git 工具
[root@jenkins ~]# yum -y install git [root@jenkins ~]# git --version git version 1.8.3.1 -
创建凭证

-
配置项目



-
构建项目

-
检查目录是否成功
[root@localhost ~]# cd /var/lib/jenkins/workspace/tao02 [root@localhost tao02]# ls demo.iml web
Maven安装部署
-
在Jenkins主机执行
[root@jenkins ~]# tar -xzf apache-maven-3.6.2-bin.tar.gz [root@jenkins ~]# mkdir -p /opt/maven [root@jenkins ~]# mv apache-maven-3.6.2/* /opt/maven -
配置环境变量
export MAVEN_HOME=/opt/maven export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin -
加载环境变量
[root@jenkins ~]# source /etc/profile -
检测
[root@jenkins ~]# mvn -v Apache Maven 3.6.2 (40f52333136460af0dc0d7232c0dc0bcf0d9e117; 2019-08-27T23:06:16+08:00) Maven home: /opt/maven Java version: 17.0.15, vendor: Eclipse Adoptium, runtime: /usr/local/java/jdk-17 Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "3.10.0-862.el7.x86_64", arch: "amd64", family: "unix" -
Jenkins配置 maven



-
添加全局属性


JAVA_HOME /usr/local/java/jdk-21
M2_HOME /opt/maven
PATH+EXTRA $M2_HOME/bin
注意: 这里填入的时候, 不能有空格
-
测试

输入构建命令
mvn clean package

- 立即构建

到这里说明已经构建成功了
Tomcat
-
安装jdk
yum install java-1.8.0-openjdk* -y -
安装tomcat
tar -xzf apache-tomcat-8.5.47.tar.gz 解压 mkdir -p /opt/tomcat 创建目录 mv /root/apache-tomcat-8.5.47/* /opt/tomcat 移动文件 /opt/tomcat/bin/startup.sh 启动tomcat -
访问

-
配置权限
[root@tomcat ~]# vim /opt/tomcat/conf/tomcat-users.xml <!-- 只保留必要角色 --> <role rolename="manager-script"/> <role rolename="manager-gui"/> <!-- 修正角色分配 --> <user username="tomcat" password="tomcat" roles="manager-script,manager-gui"/>注意: 要把以上内容添加到
标签里面 vim /opt/tomcat/webapps/manager/META-INF/context.xml <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="192\.48\.75\..*|127\.\d+\.\d+\.\d+"/> -
启动tomcat
[root@tomcat bin]# /opt/tomcat/bin/shutdown.sh Using CATALINA_BASE: /opt/tomcat Using CATALINA_HOME: /opt/tomcat Using CATALINA_TMPDIR: /opt/tomcat/temp Using JRE_HOME: /usr Using CLASSPATH: /opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jar [root@tomcat bin]# /opt/tomcat/bin/startup.sh Using CATALINA_BASE: /opt/tomcat Using CATALINA_HOME: /opt/tomcat Using CATALINA_TMPDIR: /opt/tomcat/temp Using JRE_HOME: /usr Using CLASSPATH: /opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jar Tomcat started. -
访问


Jenkins构建项目
Jenkins项目构建类型
- 自由风格软件项目(FreeStyle Project)
- Maven项目(Maven Project)
- 流水线项目(Pipeline Project)
每种类型的构建其实都可以完成一样的构建过程与结果,只是在操作方式、灵活度等方面有所区别,在实际开发中可以根据自己的需求和习惯来选择。(个人推荐使用流水线类型,因为灵活度非常高)
自由风格
拉取代码->编译->打包->部署
创建项目

拉取代码


编译 和 打包

echo "开始编译和打包"
mvn clean package
echo "编译和打包结束"

部署
-
安装 Deploy to container插件

-
部署

添加凭证

添加路径

-
开始构建

-
检测


Maven风格
- 下载插件 Maven Integration

-
创建项目

-
项目配置


-
开始构建

-
检测

这里可以看见改变之后的项目已经被部署好了
Pipeline流水线项目构建
介绍
概念
- Pipeline,简单来说,就是一套运行在 Jenkins 上的工作流框架,将原来独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排和可视化的工作。
好处
- 代码:Pipeline以代码的形式实现,通常被检入源代码控制,使团队能够编辑,审查和迭代其传送流 程。
- 持久:无论是计划内的还是计划外的服务器重启,Pipeline都是可恢复的。
- 可停止:Pipeline可接 收交互式输入,以确定是否继续执行Pipeline。
- 多功能:Pipeline支持现实世界中复杂的持续交付要 求。它支持fork/join、循环执行,并行执行任务的功能。
- 可扩展:Pipeline插件支持其DSL的自定义扩 展 ,以及与其他插件集成的多个选项。
如何创建
- Pipeline 脚本是由 Groovy 语言实现的,但是我们没必要单独去学习 Groovy
- Pipeline 支持两种语法:Declarative(声明式)和 Scripted Pipeline(脚本式)语法
- Pipeline 也有两种创建方法:可以直接在 Jenkins 的 Web UI 界面中输入脚本;也可以通过创建一个 Jenkinsfile 脚本文件放入项目源码库中(一般我们都推荐在 Jenkins 中直接从源代码控制(SCM)中直接载入 Jenkinsfile Pipeline 这种方法)
安装插件
Pipeline

Pipeline语法入门
创建一个流水线项目

声明式脚本[推荐]
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
}
}
脚本式脚本[不推荐]
node {
def mvnHome
stage('Preparation') { // for display purposes
// Get some code from a GitHub repository
git 'https://github.com/jglick/simple-maven-project-with-tests.git'
// Get the Maven tool.
// ** NOTE: This 'M3' Maven tool must be configured
// ** in the global configuration.
mvnHome = tool 'M3'
}
stage('Build') {
// Run the maven build
withEnv(["MVN_HOME=$mvnHome"]) {
if (isUnix()) {
sh '"$MVN_HOME/bin/mvn" -Dmaven.test.failure.ignore clean package'
} else {
bat(/"%MVN_HOME%\bin\mvn" -Dmaven.test.failure.ignore clean package/)
}
}
}
stage('Results') {
junit '**/target/surefire-reports/TEST-*.xml'
archiveArtifacts 'target/*.jar'
}
}
声明式[详细]
分为两个板块:
代理、环境等的一些配置
阶段
pipeline {
agent any
stages { //所有阶段
stage('Hello') { //阶段(步骤)
steps { //操作
echo 'Hello World'
}
}
}
}
入门代码
pipeline {
agent any
stages {
stage('pull code') {
steps {
echo '拉取代码'
}
}
stage('build project') {
steps {
echo '构建项目'
}
}
stage('publish project') {
steps {
echo '发布项目'
}
}
}
}
构建项目

通过流水线脚本拉取代码
这里的脚本, 直接用脚本生成器





将这个脚本 cp 到脚本中

构建

通过流水线脚本构建项目


写入脚本

构建

通过流水线脚本发布项目



cp到脚本中

构建项目

到tomcat 中查看

流水线整合IDEA
这个的好处就是, 把流水线脚本,写在项目下面命名 Jenkinsfile , 这样如果服务器挂掉之后,我们的流水线脚本依然存留

根据上面的步骤上传代码

Jenkins访问 jenkinsfile 文件



检测

sonarQube
代码审查工具: https://www.sonarqube.org
基本环境
| 软件 | 版本 |
|---|---|
| MySQL | 5.6 |
| jdk | 8 |
| sonarQube | 7.8 |
安装数据库
安装必要依赖
sudo dnf install -y libaio wget tar ncurses-compat-libs
注意:MySQL 5.6 需要较旧的
libtinfo.so.5库,需通过ncurses-compat-libs提供兼容支持
下载 MySQL 5.6 二进制包
wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.6.51-linux-glibc2.12-x86_64.tar.gz
解压并移动到安装目录
sudo tar -zxvf mysql-5.6.51-linux-glibc2.12-x86_64.tar.gz -C /usr/local/
sudo mv /usr/local/mysql-5.6.51-linux-glibc2.12-x86_64 /usr/local/mysql
创建 MySQL 系统用户和组
sudo groupadd mysql
sudo useradd -r -g mysql -s /bin/false mysql
初始化数据库
sudo mkdir -p /usr/local/mysql/data
sudo chown -R mysql:mysql /usr/local/mysql
# 使用旧版初始化脚本
sudo /usr/local/mysql/scripts/mysql_install_db \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data
创建配置文件
编辑 /etc/my.cnf:
[mysqld]
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
port = 3306
socket = /tmp/mysql.sock
user = mysql
[client]
socket = /tmp/mysql.sock
配置 systemd 服务
创建文件 /etc/systemd/system/mysqld.service:
[Unit]
Description=MySQL Server
After=network.target
[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
启动 MySQL 服务
sudo systemctl daemon-reload
sudo systemctl start mysqld
sudo systemctl enable mysqld
设置 root 密码
# 首次登录(默认无密码)
/usr/local/mysql/bin/mysql -u root
-- 在 MySQL 中执行
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('你的新密码');
FLUSH PRIVILEGES;
配置环境变量(可选)
echo 'export PATH=/usr/local/mysql/bin:$PATH' | sudo tee /etc/profile.d/mysql.sh
source /etc/profile.d/mysql.sh
创建数据库
mysql> create database sonar;
Query OK, 1 row affected (0.00 sec)
mysql>
mysql>
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sonar |
| test |
+--------------------+
5 rows in set (0.00 sec)
安装jdk8
yum install java-1.8.0-openjdk* -y
安装sonarQube
下载软件包
https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-7.8.zip
解压软件包
unzip sonarqube-7.8.zip
创建目录并移动软件包
mkdir -p /opt/sonar
mv sonarqube-7.8/* /opt/sonar
修改配置文件
[root@sonarQube ~]# vim /opt/sonar/conf/sonar.properties
sonar.jdbc.username=root
sonar.jdbc.password=54877846Rt@.
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
创建用户
useradd sonar
赋予权限
chown -R sonar. /opt/sonar
修改内核数据
# 编辑系统配置文件
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
# 重新加载配置
sysctl -p
启动服务
su - sonar -c "/opt/sonar/bin/linux-x86-64/sonar.sh start"
su - sonar -c "/opt/sonar/bin/linux-x86-64/sonar.sh status"
检测

默认账户: admin
默认密码: admin


生成秘钥

4748ffa7fe71347a255f45d3f8e924f63736ed33
SonaQube 关闭审查结果上传到SCM功能

jenkins 整合 sonarQube
安装插件

Jenkins安装sonar-sanner
jenkins 主机上安装
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.2.0.1873-linux.zip
# 解压安装
unzip sonar-scanner-cli-4.2.0.1873-linux.zip -d /opt
mv /opt/sonar-scanner-4.2.0.1873-linux /opt/sonar-scanner
# 设置环境变量
echo 'export PATH=$PATH:/opt/sonar-scanner/bin' | sudo tee -a /etc/profile
source /etc/profile
# 验证安装
sonar-scanner -v
配置全局选项

添加凭证

系统配置

在项目添加SonaQube代码审查(非流水线项目)
配置构建


# must be unique in a given SonarQube instance
sonar.projectKey=demo01
# this is the name and version displayed in the SonarQube UI. Was mandatory
prior to SonarQube 6.1.
sonar.projectName=web_demo
sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# This property is optional if sonar.modules is set.
sonar.sources=.
sonar.exclusions=**/test/**,**/target/**
sonar.java.source=21
sonar.java.target=21
# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8
检测

在项目添加SonaQube代码审查(流水线项目)
项目根目录下,创建sonar-project.properties文件

# must be unique in a given SonarQube instance
sonar.projectKey=demo01
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=web_demo
sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# This property is optional if sonar.modules is set.
sonar.sources=.
sonar.exclusions=**/test/**,**/target/**
sonar.java.source=21
sonar.java.target=21
# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8
这里修改之后, 不要忘记更新代码到 Gitlab 仓库
修改Jenkinsfile,加入SonarQube代码审查阶段

pipeline {
agent any
stages {
stage('pull code') {
steps {
checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '28d46438-c565-449e-8099-f2e7cccca9de', url: 'http://192.48.75.70:82/tom.com/helloword.git']])
}
}
stage('code checking') {
steps {
script {
//引入 sonarQubeSanner工具
scannerHome = tool 'sonarqube'
}
//引入 SonarQube 服务环境
withSonarQubeEnv('sonar-scanner') {
sh "${scannerHome}/bin/sonar-scanner"
}
}
}
stage('build project') {
steps {
sh 'mvn clean package'
}
}
stage('publish project') {
steps {
deploy adapters: [tomcat9(credentialsId: 'bddeda71-2b0c-4e2c-850e-a082b962c2b8', path: '', url: 'http://192.48.75.72:8080/')], contextPath: null, war: 'target/*.war'
}
}
}
}
这里修改之后, 不要忘记更新代码到 Gitlab 仓库
构建任务



企业级DevOps: GitLab + Jenkins + Tomcat + Pipeline + sonarQube

浙公网安备 33010602011771号