基于 Gitlab、Jenkins与Jenkins分布式、SonarQube 、Nexus 的 CiCd 全流程打造

前言

在当今数字化飞速发展的时代,软件开发与交付的效率和质量成为了企业竞争的关键要素。为了满足市场对软件快速迭代和高质量交付的需求,越来越多的企业开始探索和实践持续集成与持续交付(CI/CD)的开发模式。而 GitLab、Jenkins、SonarQube 和 Nexus 作为当前软件开发领域中广受欢迎且功能强大的工具,各自在版本控制、自动化构建与部署、代码质量检测以及依赖管理等方面发挥着重要作用。

本博文将深入探讨如何巧妙地整合 GitLab、Jenkins、SonarQube 和 Nexus 这四大工具,打造一个高效、稳定、可靠的 CI/CD 全流程。通过这一流程的构建,开发团队能够实现代码从提交到部署的自动化与规范化,提升软件开发效率,保障代码质量,同时降低人工干预带来的风险,为企业在激烈的市场竞争中赢得先机。接下来,让我们一起深入了解这一强大的 CI/CD 生态系统的搭建与运作。

|---------------|---------------------------|
| 角色 | IP地址/OS |
| Gitlab | 10.0.0.200/Ubuntu22.04LTS |
| Jenkins+Nexus | 10.0.0.202/KylinV10SP3 |
| Jenkins分布式从节点 | 10.0.0.5/KylinV10SP3 |
| SonarQube | 10.0.0.203/KylinV10SP3 |
| web01测试环境 | 10.0.0.7/kylinV10SP3 |
| web02测试环境 | 10.0.0.8/kylinV10SP3 |

一、安装与使用Gitlab

tips: 不熟悉Git分布式版本控制软件使用的可以看我之前发布的一篇有关Git使用的博文: Git 与 GitLab:开启代码协同的实战之旅-CSDN博客https://blog.csdn.net/shjwkzkzk/article/details/148625177?spm=1001.2014.3001.5501

1. 安装Gitlab

gitlab-ce安装包下载_开源镜像站-阿里云

bash 复制代码
# 关闭防火墙
root@git:~# ufw disable
Firewall stopped and disabled on system startup
# Ubuntu的deb国内包仓库
https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu/pool/jammy/main/g/gitlab-ce/
# 安装依赖
apt-get install -y curl openssh-server ca-certificates tzdata perl
# 上传我们的deb包
root@git:~# ll
total 1055524
drwxr-xr-x 3 root root       4096 Feb 17 11:57 git_code
-rw-r--r-- 1 root root 1080842786 Feb 17 04:03 gitlab-ce_16.5.2-ce.0_amd64.deb
# 执行安装命令
root@git:~# dpkg -i gitlab-ce_16.5.2-ce.0_amd64.deb 
出现以下页面表示安装成功:
bash 复制代码
Please configure a URL for your GitLab instance by setting `external_url`
configuration in /etc/gitlab/gitlab.rb file.
Then, you can start your GitLab instance by running the following command:
  sudo gitlab-ctl reconfigure

2. 配置external_url

bash 复制代码
我们在配置文件中添加我们的url  ------->我们的IP的地址对应的URL
root@git:~# sed -n '/^external_url/p' /etc/gitlab/gitlab.rb
external_url 'http://10.0.0.200'
执行以下命令:
root@git:~# gitlab-ctl reconfigure

然后访问:
URL:
http://10.0.0.200

user:
root

Passwd: #存在与我们的文件包里面
root@git:~# sed -n '/^Password/p' /etc/gitlab/initial_root_password
Password: v2cXZszGVo1iekuEvMZGgQ2d1GYew653c/dFTXUcy+g=

3.使用gitlab

a.修改密码

输入我们的用户名和密码进行登入

密码太复杂我们修改一下密码

修改即可

b.修改语言为中文

刷新即可

这里最好不要允许任何人都可以注册

c.添加项目

空的代码仓库,在gitlab创建代码仓库,然后拉取到本地服务器

这里导入空白项目时最好创建一下群组

d.打通系统与gitlab root 账户的SSH
bash 复制代码
root@git:~# ssh-keygen

root@git:~# cat .ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC2iDEj+0P1fdawoyPOTGgvnOil/HiWfCLN3COS0GcNN8795ib6OhRB4FlTWKNgEZdFsl6vEFNOUm8q6Y2/oARyUMFCnXeYnvhg1ysHF0y48s1BC/uK/GOF32gQ+uJSTj2kapzYepUcCR7oOVbbIg5jbm24HGLTd+BhIOjKnX6zwKimWlaSeo6pha9xbpPzbLnG3XaZY8myojJrm1VaNCUbvDuO/2EzX1+uL8GlTPiXOPNyj8bOjClFZ4vcluMnLzDnhAJiv9tW/oktLYh5ro0hxTz+j5/a0Kj1/SM82jJA/oO4glzkn/wyb8il8fwkiPC/QQcifLMMAuPYH2lwcqFsaC++oj8zrxO7/nzX/PFMW40IicvYBbG0y2alik7kMjxx53XAEZFs33dAu1YMJKkVKcFzxZAk94n/+qJOa7T+Dx1e1BSVjMK2WmlpQtrftzrZROpbU0tzFnd4tgFKzh85Tpc/i4xqPEh+DmzvgUPiQLKIYNBzb29VthBuYxPsaDs= root@git

e.使用项目仓库
bash 复制代码
命令行将空的仓库下载到本地
# 这里粗心了,创建了一个和git本地仓库名称一样的项目仓库....
root@git:~# git clone git@10.0.0.200:BestCode/git_code.git
fatal: destination path 'git_code' already exists and is not an empty directory.
root@git:~# ll
total 1055524
drwxr-xr-x 3 root root       4096 Feb 17 11:57 git_code
-rw-r--r-- 1 root root 1080842786 Feb 17 04:03 gitlab-ce_16.5.2-ce.0_amd64.deb
drwx------ 3 root root       4096 Oct 24 10:37 snap
root@git:~# rm -rf git_code/
root@git:~# git clone git@10.0.0.200:BestCode/git_code.git
Cloning into 'git_code'...
The authenticity of host '10.0.0.200 (10.0.0.200)' can't be established.
ED25519 key fingerprint is SHA256:Zk4qeVRp5S3WJiLnUHpyo04qjc9QdCC43c/F2Tdjfpg.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.0.0.200' (ED25519) to the list of known hosts.
warning: You appear to have cloned an empty repository.
root@git:~# cd git_code/
root@git:~/git_code# ll 
total 0
root@git:~/git_code# ll -a
total 12
drwxr-xr-x 3 root root 4096 Feb 17 12:49 .
drwx------ 6 root root 4096 Feb 17 12:49 ..
drwxr-xr-x 7 root root 4096 Feb 17 12:49 .git


### 然后还要配置一下是谁在使用这个仓库,配置一下使用人信息
root@git:~/git_code# git config --global user.name "caofacan"
root@git:~/git_code# git config --global user.email "cfc@can.com"

# 创建新的文件提交到本地仓库
root@git:~/git_code# touch game.jdk
root@git:~/git_code# ll
total 0
-rw-r--r-- 1 root root 0 Feb 17 12:52 game.jdk
root@git:~/git_code# git add .
root@git:~/git_code# git commit -m "gitlab-game----->V1.0"
[master (root-commit) ef66792] gitlab-game----->V1.0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 game.jdk
 
# 查看远程仓库的名称
 root@git:~/git_code# git remote 
origin
# 查看远程仓库的详细地址
root@git:~/git_code# git remote -v
origin  git@10.0.0.200:BestCode/git_code.git (fetch)
origin  git@10.0.0.200:BestCode/git_code.git (push)
# 将本地仓库的代码提交到远程仓库
root@git:~/git_code# git push -u origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 209 bytes | 209.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To 10.0.0.200:BestCode/git_code.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

# 因为当前处于master分支,所以后面参数是master
root@git:~/git_code# git branch 
* master

刷新我们的项目页面就可以看到了

如果代码已经存在本地我们可以:

1.本地仓库已经初始化

2.本地代码已经存在

bash 复制代码
root@git:~# mkdir code_data
root@git:~# cd code_data/
root@git:~/code_data# git init
Initialized empty Git repository in /root/code_data/.git/
root@git:~/code_data# ll -a
total 12
drwxr-xr-x 3 root root 4096 Feb 17 12:58 .
drwx------ 7 root root 4096 Feb 17 12:58 ..
drwxr-xr-x 7 root root 4096 Feb 17 12:58 .git
root@git:~/code_data# touch {1..5}.py
root@git:~/code_data# ll
total 0
-rw-r--r-- 1 root root 0 Feb 17 12:58 1.py
-rw-r--r-- 1 root root 0 Feb 17 12:58 2.py
-rw-r--r-- 1 root root 0 Feb 17 12:58 3.py
-rw-r--r-- 1 root root 0 Feb 17 12:58 4.py
-rw-r--r-- 1 root root 0 Feb 17 12:58 5.py
root@git:~/code_data# git add .
root@git:~/code_data# git commit -m "git_code-game------>V1.2py"
[master (root-commit) 9932a0a] git_code-game------>V1.2py
 5 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 1.py
 create mode 100644 2.py
 create mode 100644 3.py
 create mode 100644 4.py
 create mode 100644 5.py
 
 ## 这时候如果我们直接push,会出现报错
 root@git:~/code_data# git push -u origin master
To 10.0.0.200:BestCode/git_code.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to '10.0.0.200:BestCode/git_code.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

这个错误表明远程仓库的 master 分支包含了本地仓库没有的更新,所以 Git 拒绝了推送操作。你需要先拉取远程仓库的更新并合并到本地,再推送。
 解决: 
 # 我们将本地仓库的代码提交到远程仓库
 如果直接pull的话,也会报错
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint: 
hint:   git config pull.rebase false  # merge (the default strategy)
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint: 
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
这个报错表明本地和远程的 `master` 分支发生了分叉,Git 无法自动决定如何合并它们,需要你指定合并策略(如合并、变基或仅快速合并)。
root@git:~/code_data# git config pull.rebase false
root@git:~/code_data# git config pull.rebase true
root@git:~/code_data# git pull origin master
From 10.0.0.200:BestCode/git_code
 * branch            master     -> FETCH_HEAD
Successfully rebased and updated refs/heads/master.
root@git:~/code_data# ll
total 4
-rw-r--r-- 1 root root    0 Feb 17 13:06 1.py
-rw-r--r-- 1 root root    0 Feb 17 13:06 2.py
-rw-r--r-- 1 root root    0 Feb 17 13:06 3.py
-rw-r--r-- 1 root root    0 Feb 17 13:06 4.py
-rw-r--r-- 1 root root    0 Feb 17 13:06 5.py
-rw-r--r-- 1 root root    0 Feb 17 13:06 game.jdk
drwxr-xr-x 3 root root 4096 Feb 17 13:02 git_code
root@git:~/code_data# git add .
warning: adding embedded git repository: git_code
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint: 
hint:   git submodule add <url> git_code
hint: 
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint: 
hint:   git rm --cached git_code
hint: 
hint: See "git help submodule" for more information.
root@git:~/code_data# git rm --cached git_code
error: the following file has staged content different from both the
file and the HEAD:
    git_code
(use -f to force removal)
root@git:~/code_data# git add .
root@git:~/code_data# git commit -m "py--->V1.2"
[master 7d53f65] py--->V1.2
 1 file changed, 1 insertion(+)
 create mode 160000 git_code
root@git:~/code_data# git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 454 bytes | 454.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
To 10.0.0.200:BestCode/git_code.git
   ef66792..7d53f65  master -> master

4. Gitlab权限控制

1. 创建普通用户dev赋予对应权限

管理中心------>仪表盘----->新建用户

点击编辑,设置登录密码(dev@123.com

使用普通账号登录gitlab 默认里面空的

开第二个窗口,因为cookie的原因,浏览器只能存储一个cookie。

将dev账号添加到BestCode组中,dev用户拥有game项目的权限。

模拟开发人员下载代码到本地服务器

bash 复制代码
dev开发使用的服务器10.0.0.7
1.开发需要再自己的linux系统中生成秘钥对
[root@dev:~]#ssh-keygen
2.将公钥复制到gitlab的 dev账号中
[root@web01 ~]# cat .ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4ng0mdQxOaU0dq24KjIGC/rcwgWjMIGPgDsdGSyKS3f8FxqLL2y67/FUT1tMd1TGX5V6OcCEnIQC91P0wbOmPpqxWpGuBhdA+7sMxBJaIyVNJgwbO2jFnPc4S9i8zeUusqIdfjRmMNOtr5xu0u8tot6YuIpOA3KNxmpasIWPuSS2V46ab49uRMv92j9SNAFd0uCRzd+wQGztqOwzoi4N1qdzuuw/P8FTOSD3Ws9K0YNXzWGHT/JwIL7LdDWnd8XvskmkueS65OjLWYUSUYhL4qTSJ7f9qY0cUZ6HjM1Dh8xXfFGyA7pgrBayfGkyhS+lqMRruR7HgW4hyapzi7JX4oSrZICAb/VsHfXFY3Zd2ug57JNYDGyQg3Fq7yXWvrlmgZOi54Cvz6dXA+0H3I+mnXtM2X9kWOL7aFGaVuLe1gRQLAg8pBWw7MZ8BekIFjRAhmghrg3eJK4z330P5u4xAs5c15GWp+Gm6lX4Lxpl+qjVOR1rKusMZCsDF0nZ9f8s= root@web01

因为我们只有一个群组项目都在BestCode群组里面,所以我们普通用户加入到这个群组之后,就能看到所以的项目了,这里没有细分。

bash 复制代码
3.下载游戏代码到本地
[root@web01 ~]# git clone git@10.0.0.200:BestCode/game.git
Cloning into 'game'...
The authenticity of host '10.0.0.200 (10.0.0.200)' can't be established.
ECDSA key fingerprint is SHA256:KmllkN7Me0V380RXxrpFR0hd+H6hNqtUgXGBl9Smykc.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.0.0.200' (ECDSA) to the list of known hosts.
remote: Enumerating objects: 102, done.
remote: Counting objects: 100% (102/102), done.
remote: Compressing objects: 100% (99/99), done.
remote: Total 102 (delta 3), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (102/102), 14.86 MiB | 9.71 MiB/s, done.
Resolving deltas: 100% (3/3), done.
[root@web01 ~]# ll
total 4
drwxr-xr-x 7 root root  152 Feb 17 21:40 game
-rw-r--r-- 1 root root 2281 Feb 15 15:20 os_check.sh
[root@web01 ~]# ll game/
total 7764
-rw-r--r-- 1 root root   28032 Feb 17 21:40 bgm.mp3
drwxr-xr-x 2 root root      23 Feb 17 21:40 css
-rw-r--r-- 1 root root 7890373 Feb 17 21:40 game.zip
drwxr-xr-x 2 root root      23 Feb 17 21:40 images
-rw-r--r-- 1 root root    8956 Feb 17 21:40 index.html
drwxr-xr-x 2 root root     213 Feb 17 21:40 js
-rw-r--r-- 1 root root    6153 Feb 17 21:40 README.md
drwxr-xr-x 2 root root    4096 Feb 17 21:40 roms
-rw-r--r-- 1 root root     811 Feb 17 21:40 shuoming.html

需要游戏实例代码可通过主页email联系我。

2. dev用户上传代码流程
bash 复制代码
# 我们模拟一下修改代码
[root@web01 ~/game]# vim index.html
                "经典": [
                    ['魂斗罗V1.0第一次修改', 'roms/Contra1(U)30.nes'],
                    ['超级玛丽', 'roms/(W) Super Mario Bros. [!].nes'],
                    ......                
[root@web01 ~/game]# git add .
[root@web01 ~/game]# git commit -m "index.html---->第一次修改"
# 配置使用人信息
[root@web01 ~/game]# git config --global user.name "dev"
[root@web01 ~/game]# git config --global user.email "dev@123.com"
[root@web01 ~/game]# cat ../.gitconfig 
[user]
        name = dev
        email = dev@123.com
# 提交到远程仓库
默认不允许提交到master主干分支,需要先创建子分支,然后提交子分支,在发起代码合并请求master 
[root@web01 ~/game]# git branch ops
[root@web01 ~/game]# git push -u origin ops

dev新建一下合并请求

root处理合并请求

二、 Jenkins集成Gitlab

Jenkins 是一个开源的自动化服务器,用于实现持续集成和持续交付,帮助开发团队自动化构建、测试和部署软件,提高开发效率和软件质量。

1. 安装Jenkins

点我下载Jenkins软件包owo

bash 复制代码
# 安装JDK运行环境
[root@Jenkins ~]# yum -y install java
# 上传Jenkins的RPM包
[root@Jenkins ~]# ll
total 91220
-rw-r--r-- 1 root root 93405530 Sep 27 17:20 jenkins-2.405-1.1.noarch.rpm
# 安装Jenkins
[root@Jenkins ~]# rpm -ivh jenkins-2.405-1.1.noarch.rpm 
# 配置Jenkins
[root@Jenkins ~]# grep -n root /etc/sysconfig/jenkins 
31:JENKINS_USER="root"
[root@Jenkins ~]# grep -n root /usr/lib/systemd/system/jenkins.service
34:User=root
35:Group=root
# 启动Jenkins服务
[root@Jenkins ~]# systemctl daemon-reload
[root@Jenkins ~]# systemctl start jenkins.service 
浏览器访问: 10.0.0.202:8080

因为Jenkins要依赖于多又强大的插件来完成工作的,这里我网络不是很好所以我需要导入准备好的插件到Jenkins的插件目录下。

bash 复制代码
# 上传我们打包好的插件包
[root@Jenkins ~]# tar xf jenkins_plu.tar.gz -C /var/lib/jenkins/plugins/
# 重启Jenkins服务
[root@Jenkins ~]# systemctl restart jenkins.service 
# 进入Jenkins修改密码,因为插件中我们有中文插件

大致所需的插件如下(需要插件包一样可以联我email):

Jenkins有很多插件,以下是一些最常用的插件,它们能够极大地增强Jenkins的功能:

  1. Git Plugin

用于与Git版本控制系统集成,支持从Git仓库拉取代码进行构建。

  1. Maven Integration Plugin

用于与Maven构建工具集成,帮助执行Maven构建生命周期,自动化Maven项目的构建过程。

  1. Pipeline Plugin

使Jenkins支持声明式和脚本化的流水线(Pipeline),可以定义和管理CI/CD工作流。

  1. Blue Ocean Plugin

提供一个现代化的Jenkins用户界面,支持直观地查看流水线、作业和结果,帮助用户轻松管理和监控流水线。

  1. Slack Notification Plugin

可以将Jenkins构建的状态(成功、失败、稳定等)发送到Slack频道,方便团队实时查看构建结果。

  1. Docker Pipeline Plugin

使Jenkins流水线能够轻松与Docker集成,支持在Docker容器中运行构建和测试。

  1. JUnit Plugin

用于展示JUnit测试结果,生成测试报告,并将其集成到Jenkins中,便于查看测试的成功率和失败详情。

  1. GitHub Plugin

用于将Jenkins与GitHub集成,自动触发构建、同步GitHub代码库等。

  1. Parameterized Trigger Plugin

允许Jenkins作业触发其他作业,并支持传递参数,从而实现复杂的作业依赖和多阶段构建流程。

  1. Credentials Binding Plugin

让你能够在构建过程中安全地使用密钥、用户名等敏感信息,而不暴露在构建日志中。

这些插件能够帮助你在Jenkins中实现自动化构建、测试、部署、通知等各种功能,极大提升工作流的效率。

Jenkins默认的用户为admin

下翻找到密码

因为是测试环境我修改为了123456

2.体验Jenkins的自动化

a.克隆代码

进入到代码目录,下载game的代码

bash 复制代码
[root@web01 /code]# git clone git@10.0.0.200:BestCode/game.git
[root@web01 /code]# mv game/* .
[root@web01 /code]# ll
total 7764
-rw-r--r-- 1 root root   28032 Feb 18 19:29 bgm.mp3
drwxr-xr-x 2 root root      23 Feb 18 19:29 css
drwxr-xr-x 3 root root      18 Feb 18 19:29 game
-rw-r--r-- 1 root root 7890373 Feb 18 19:29 game.zip
drwxr-xr-x 2 root root      23 Feb 18 19:29 images
-rw-r--r-- 1 root root    8976 Feb 18 19:29 index.html
drwxr-xr-x 2 root root     213 Feb 18 19:29 js
-rw-r--r-- 1 root root    6153 Feb 18 19:29 README.md
drwxr-xr-x 2 root root    4096 Feb 18 19:29 roms
-rw-r--r-- 1 root root     811 Feb 18 19:29 shuoming.html
b.新建一个Jenkins任务
c.查看Jenkins的执行命令的默认路径

d.Jenkins拉取gitlab的代码
bash 复制代码
# 1.Jenkins生成密钥对
[root@Jenkins ~]# ssh-keygen 
+---[RSA 3072]----+
|.oo. ..    + E   |
|.o. =+.o. ooo    |
|. +o+=o.o.o o    |
| = =+.+o . o .   |
|. . +*o S . +    |
|   ..o o . + o   |
|    =   . o o    |
|     o    .+     |
|        .o..o    |
+----[SHA256]-----+
[root@Jenkins ~]# cat .ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7M3Q/3QYGwSbb3lxDcgmaLaTk9aRF7zEFG3g5ImuLJnKED7/e2LfPAr0hGd8a2WrQWQQEhP5u4qGfMdPVduekXdhj0rbUQMS8V+jJ/o7mOYEiBZ4IAd2xlKoDhIM3Lj7pof8vrNEIwLqblfVQqDefPKdAVnHnSTdSDFv5DFE32xpb6LcpNKpZS8zGefhTKPwcOEmQ85Br5tqWAfSpj4Huwm8c/kv7rOOVKq/FJE+ly0n774Fga9Z8Q0AmYkHr7/6jZ+SDAFg3ha/grfePhVDrv7z9B5VubZgHSzIUI7G3AhQ/6IWInIUxNcz4WhODTKfZQoYqprDZ/mxsjeay7frwG0Kzh95CwkMcPXeZOg4tx/E8LO9EPYlcNFizA1kbjh4XEDtVw81QL4ObnPohoMW32EtI+Rh71EI3R2wgIhj/c8QhIA9gfTWhqMcLFBqAQ7dubOePgfsb7A8NAf9OvYB/BvuyRExs6rYDERVgu4hS3Elmefz67iHShFx1HTSTYcc= root@Jenkins

将公钥复制到gitlab的root账号中

e.配置Jenkins拉取game

出现报错,分析错误,解决报错

bash 复制代码
现在本地拉一下,把验证过了之后,删除即可
[root@Jenkins /tmp]# git clone git@10.0.0.200:BestCode/game.git

完成后执行构建,绿色表示没有问题

bash 复制代码
# 查看拉取的代码
[root@Jenkins ~]# cd /var/lib/jenkins/workspace/
[root@Jenkins /var/lib/jenkins/workspace]# ll
total 0
drwxr-xr-x 7 root root 152 Feb 18 19:45 game_job
[root@Jenkins /var/lib/jenkins/workspace]# ll game_job/
total 7764
-rw-r--r-- 1 root root   28032 Feb 18 19:45 bgm.mp3
drwxr-xr-x 2 root root      23 Feb 18 19:45 css
-rw-r--r-- 1 root root 7890373 Feb 18 19:45 game.zip
drwxr-xr-x 2 root root      23 Feb 18 19:45 images
-rw-r--r-- 1 root root    8976 Feb 18 19:45 index.html
drwxr-xr-x 2 root root     213 Feb 18 19:45 js
-rw-r--r-- 1 root root    6153 Feb 18 19:45 README.md
drwxr-xr-x 2 root root    4096 Feb 18 19:45 roms
-rw-r--r-- 1 root root     811 Feb 18 19:45 shuoming.html
f.自动推送到web服务器上面
bash 复制代码
我们再将拉下来的代码推送到web服务器上面
# 在此之前先做个免密钥
[root@Jenkins /var/lib/jenkins/workspace]# ssh-copy-id 10.0.0.7

# 再将我们web服务器的代码目录清空
[root@web01 /code]# ll
total 7764
-rw-r--r-- 1 root root   28032 Feb 18 19:29 bgm.mp3
drwxr-xr-x 2 root root      23 Feb 18 19:29 css
drwxr-xr-x 3 root root      18 Feb 18 19:29 game
-rw-r--r-- 1 root root 7890373 Feb 18 19:29 game.zip
drwxr-xr-x 2 root root      23 Feb 18 19:29 images
-rw-r--r-- 1 root root    8976 Feb 18 19:29 index.html
drwxr-xr-x 2 root root     213 Feb 18 19:29 js
-rw-r--r-- 1 root root    6153 Feb 18 19:29 README.md
drwxr-xr-x 2 root root    4096 Feb 18 19:29 roms
-rw-r--r-- 1 root root     811 Feb 18 19:29 shuoming.html
[root@web01 /code]# rm -rf *
[root@web01 /code]# ll
total 0

保存后构建,然后直接去web服务器查看代码目录是否已经存在

bash 复制代码
[root@web01 /code]# ll
total 7764
-rw-r--r-- 1 root root   28032 Feb 18 19:50 bgm.mp3
drwxr-xr-x 2 root root      23 Feb 18 19:50 css
-rw-r--r-- 1 root root 7890373 Feb 18 19:50 game.zip
drwxr-xr-x 2 root root      23 Feb 18 19:50 images
-rw-r--r-- 1 root root    8976 Feb 18 19:50 index.html
drwxr-xr-x 2 root root     213 Feb 18 19:50 js
-rw-r--r-- 1 root root    6153 Feb 18 19:50 README.md
drwxr-xr-x 2 root root    4096 Feb 18 19:50 roms
-rw-r--r-- 1 root root     811 Feb 18 19:50 shuoming.html

web01测试环境准备NGINX环境

bash 复制代码
[root@web01 /etc/nginx/conf.d]# cat default.conf 
server {
        listen 80;
        server_name _;
        location / {
                root /code;
                index index.html;
        }
}
[root@web01 /etc/nginx/conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web01 /etc/nginx/conf.d]# systemctl restart nginx
[root@web01 /etc/nginx/conf.d]# curl localhost
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.26.1</center>
</body>
</html>

访问一下我们的web服务器

浏览器打开: 10.0.0.7

g.更新代码后,使用Jenkins更新web
bash 复制代码
[root@web01 /code]# vim index.html
= new JSNES({
            'ui': $('#emulator').JSNESUI({
                "经典": [
                    ['魂斗罗V1.0第一次修改', 'roms/Contra1(U)30.nes'],
                    ['超级玛丽'V1.0第一次修改, 'roms/(W) Super Mario Bros. [!].nes'],
                    
bash 复制代码
[root@web01 /code]# git remote add origin git@10.0.0.200:BestCode/game.git
[root@web01 /code]# git remote -v
origin  git@10.0.0.200:BestCode/game.git (fetch)
origin  git@10.0.0.200:BestCode/game.git (push)
[root@web01 /code]# git commit -am "web01第二次修改魂斗罗"
[master 26f6c97] web01第二次修改魂斗罗
 1 file changed, 1 insertion(+), 1 deletion(-)
[root@web01 /code]# git push -u origin testing
Enumerating objects: 100, done.
Counting objects: 100% (100/100), done.
Compressing objects: 100% (98/98), done.
Writing objects: 100% (100/100), 14.86 MiB | 8.94 MiB/s, done.
Total 100 (delta 3), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (3/3), done.
remote: 
remote: To create a merge request for testing, visit:
remote:   http://10.0.0.200/BestCode/game/-/merge_requests/new?merge_request%5Bsource_branch%5D=testing
remote: 
To 10.0.0.200:BestCode/game.git
 * [new branch]      testing -> testing
Branch 'testing' set up to track remote branch 'testing' from 'origin'.

访问gitlab页面合并一下代码

切换到root用户处理一下请求

4.配置自动触发webhook勾子

bash 复制代码
# 保存一下我们的token
6ee0bae8420a9901385f33d4957ca68c
# 保存一下URL:
http://10.0.0.202:8080/project/game_job

跳到我们的gitlab添加钩子

bash 复制代码
然后构建Jenkins测试钩子
root@git:~/game# git pull
root@git:~/game# vim index.html 
'ui': $('#emulator').JSNESUI({
                "经典": [
                    ['魂斗罗V1.2第二次修改', 'roms/Contra1(U)30.nes'],
                    ['超级玛丽V1.0第一次修改', 'roms/(W) Super Mario Bros. [!].nes'],
                    ['坦克V1.0master第一次修改', 'roms/(Ch) Missile Tank.nes'],
root@git:~/game# git commit -am "master第一次修改index.html"
[master 3a515cf] master第一次修改index.html
 1 file changed, 1 insertion(+), 1 deletion(-)
root@git:~/game# git push -u origin master 
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 326 bytes | 326.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
To 10.0.0.200:BestCode/game.git
   f089fe6..3a515cf  master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
然后等着钩子触发,web服务器直接就push到了最新的代码。
[root@web01 /code]# grep 'master' index.html 
                    ['坦克V1.0master第一次修改', 'roms/(Ch) Missile Tank.nes'],
                  

Jenkins没有问题

三、SonarQube代码扫描工具

jenkins将代码拉取到jenkins本地,先将代码推送到sonar服务器上代码扫描检测,检测代码的漏洞 逻辑 坏味道。

1.安装sonarqube

bash 复制代码
# 安装Java
[root@SonarQube ~]# yum -y install java
# 安装数据库
[root@SonarQube ~]# wget dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
[root@SonarQube ~]# rpm -ivh mysql-community-release-el6-5.noarch.rpm
#禁止gpgcheck
[root@SonarQube ~]# vim /etc/yum.repos.d/mysql-community.repo
...
# Enable to use MySQL 5.6
[mysql56-community]
name=MySQL 5.6 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.6-community/el/6/$basearch/
enabled=1
gpgcheck=0
gpgkey=file:/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
[root@SonarQube ~]# yum -y install mariadb-server
[root@SonarQube ~]# service mysqld start
[root@SonarQube ~]# mysqladmin -uroot password caofacan123
Warning: Using a password on the command line interface can be insecure.
[root@SonarQube ~]# mysql -uroot -pcaofacan123 -e "CREATE DATABASE sonar DEFAULT CHARACTER SET utf8;"
Warning: Using a password on the command line interface can be insecure.
[root@SonarQube ~]# mysql -uroot -pcaofacan123 -e "show databases;"
Warning: Using a password on the command line interface can be insecure.
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sonar              |
+--------------------+
# 安装sonarqube
[root@SonarQube ~]# unzip sonarqube-7.0.zip -d /usr/local/
[root@SonarQube ~]# cd /usr/local/
[root@SonarQube /usr/local]# ln -s sonarqube-7.0/ sonarqube
[root@SonarQube /usr/local/sonarqube]# pwd
/usr/local/sonarqube
# 修改配置文件
[root@SonarQube /usr/local/sonarqube]# sed -n '16p;17p;26p' conf/sonar.properties 
sonar.jdbc.username=root
sonar.jdbc.password=caofacan123
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
26行取消注释即可

# 创建普通用户sonar
sonarqube服务必须由普通用户运行。
[root@SonarQube /usr/local/sonarqube]# useradd sonar
[root@SonarQube /usr/local/sonarqube]# chown -R sonar.sonar /usr/local/sonarqube-7.0/
# 使用sonar用户运行服务
[root@SonarQube ~]# su - sonar -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start"
Starting SonarQube...
Started SonarQube.

# 浏览器访问:10.0.0.203:9000

安装插件

bash 复制代码
[root@SonarQube ~]# cd /usr/local/sonarqube/extensions/
[root@SonarQube /usr/local/sonarqube/extensions]# ll
total 4
drwxr-xr-x 2 sonar sonar    6 Feb 18 21:10 downloads
drwxr-xr-x 3 sonar sonar   20 Feb  2  2018 jdbc-driver
drwxr-xr-x 2 sonar sonar 4096 Feb 18 21:10 plugins
[root@SonarQube /usr/local/sonarqube/extensions]# cd plugins/
[root@SonarQube /usr/local/sonarqube/extensions/plugins]# rm -rf *
[root@SonarQube /usr/local/sonarqube/extensions/plugins]# tar xf /root/sonar_plugins.tar.gz -C .
[root@SonarQube /usr/local/sonarqube/extensions/plugins]# mv plugins/* .
[root@SonarQube /usr/local/sonarqube/extensions/plugins]# su - sonar -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh restart"

登录sonarqube:用户名和密码都是admin

登录之后

令牌与标识都为html

bash 复制代码
## 信息要保留下来
sonar-scanner \
  -Dsonar.projectKey=html \
  -Dsonar.sources=. \
  -Dsonar.host.url=http://10.0.0.203:9000 \
  -Dsonar.login=73b11ffacb7d24ecabb161c592797a2e0bda3d57

2.客户端扫描代码后上传sonar服务端

bash 复制代码
# 安装客户端在Jenkins
[root@Jenkins ~]# unzip sonar-scanner-cli-4.2.0.1873-linux.zip -d /usr/local/
[root@Jenkins ~]# mv /usr/local/sonar-scanner-4.2.0.1873-linux/ /usr/local/sonar-scanner
[root@Jenkins ~]# ll /usr/local/
total 0
drwxr-xr-x 2 root root 18 Dec  2 16:00 bin
drwxr-xr-x 2 root root  6 Mar  6  2021 etc
drwxr-xr-x 2 root root  6 Mar  6  2021 games
drwxr-xr-x 2 root root  6 Mar  6  2021 include
drwxr-xr-x 2 root root  6 Mar  6  2021 lib
drwxr-xr-x 3 root root 17 Dec  2 23:59 lib64
drwxr-xr-x 2 root root  6 Mar  6  2021 libexec
drwxr-xr-x 2 root root  6 Mar  6  2021 sbin
drwxr-xr-x 5 root root 49 Dec  2 23:59 share
drwxr-xr-x 6 root root 51 Oct  1  2019 sonar-scanner
drwxr-xr-x 2 root root  6 Mar  6  2021 src
[root@Jenkins ~]# export PATH="$PATH:/usr/local/sonar-scanner"
[root@Jenkins ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin:/usr/localsonar-scanner/bin
# 写入到环境变量
[root@Jenkins ~]# tail -1 /etc/profile
export PATH="$PATH:/usr/local/sonar-scanner/bin"

# 执行代码扫描
[root@Jenkins ~/game]# pwd
/root/game
在代码目录执行
[root@Jenkins ~/game]# sonar-scanner \
  -Dsonar.projectKey=html \
  -Dsonar.sources=. \
  -Dsonar.host.url=http://10.0.0.203:9000 \
  -Dsonar.login=73b11ffacb7d24ecabb161c592797a2e0bda3d57
  
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 8.098s
INFO: Final Memory: 7M/116M
INFO: ------------------------------------------------------------------------
成功

3.配置jenkins集成soanrqube

bash 复制代码
# 修改配置文件指向 203的9000端口,默认是指向自己再添加一行login信息
[root@Jenkins /usr/local/sonar-scanner/conf]# pwd
/usr/local/sonar-scanner/conf
[root@Jenkins /usr/local/sonar-scanner/conf]# grep -E 'sonar.host.url|sonar.login' /usr/local/sonar-scanner/conf/sonar-scanner.properties 
sonar.host.url=http://10.0.0.203:9000
sonar.login=73b11ffacb7d24ecabb161c592797a2e0bda3d57
之前的执行脚本的login编号

下滑找到,添加Jenkins信息

回到我们的Jenkins的工程

bash 复制代码
sonar.projectName=${JOB_NAME} # 项目在sonarqube上的显示名称
sonar.projectKey=html # 项目的唯一表示,不能重复
sonar.sources=. # 扫描那个项目的源码

然后Jenkins就可以立即构建了

这里我们走一遍完整的流程

bash 复制代码
root@git:~/game# vim index.html 
root@git:~/game# git commit -am "master第二次修改"
[master 5872f80] master第二次修改
 1 file changed, 1 insertion(+), 1 deletion(-)
root@git:~/game# git push -u origin master 
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 303 bytes | 303.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
To 10.0.0.200:BestCode/game.git
   3a515cf..5872f80  master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

# 然后我们的Jenkins就会自动触发

web服务器正常

代码也会自动扫描

root@Jenkins \~\]# date +%F-%H-%M 2025-02-19-14-48

四、Jenkins的pipeline

1. Jenkins Pipeline 简介

Jenkins Pipeline 是一种用于自动化构建、测试和部署的工具,基于声明性或脚本式的语法,帮助开发团队实现持续集成和持续交付 (CI/CD)。基于Java的动态编程groovy语言。

核心概念

  • Pipeline:一系列自动化流程的定义,从代码构建、测试到部署。

  • Jenkinsfile:用来定义 Pipeline 的文件,通常存放在项目的根目录下,支持两种格式:声明式和脚本式。

2. Pipeline 类型

声明式

bash 复制代码
1. 声明式 Pipeline:
   - 提供了更简洁和结构化的语法。
   - 示例:
     pipeline {
         agent any
         stages {
             stage('Build') {
                 steps {
                     echo 'Building...'
                 }
             }
             stage('Test') {
                 steps {
                     echo 'Testing...'
                 }
             }
             stage('Deploy') {
                 steps {
                     echo 'Deploying...'
                 }
             }
         }
     }

脚本式

bash 复制代码
2. 脚本式 Pipeline:
   - 更灵活,但语法较为复杂,适合需要自定义逻辑的场景。
   - 示例:
     node {
         stage('Build') {
             echo 'Building...'
         }
         stage('Test') {
             echo 'Testing...'
         }
         stage('Deploy') {
             echo 'Deploying...'
         }
     }

主要组成部分

  • Agent:指定在哪个节点上执行 Pipeline(如 `any` 表示在任意可用的节点上执行)。

  • Stages:定义多个阶段,通常用于分隔不同的工作流程,如构建、测试、部署等。

  • Steps:每个阶段中的具体操作,可以是执行 shell 命令、构建工具或脚本等。

优势

  • 自动化:通过流水线自动化整个开发、构建、测试和部署过程。

  • 可追踪性:每个阶段都有详细日志,方便追踪和排查问题。

  • 版本控制:通过 `Jenkinsfile` 可以将流水线定义与代码一同管理,支持版本控制。

总结

Jenkins Pipeline 是一种强大的工具,通过自动化的流程实现高效的持续集成与持续交付,帮助团队更快地交付高质量的代码。

3. 使用Jenkins-pipline项目

保存然后构建,构建完成之后鼠标落在绿色的方块上可以看到具体的日志

点击旁边的Blue Ocean可以看到具体的识图

我们换一种方式重新定义

然后我们去gitlab上面直接创建一个Jenkinsfile的文件

然后提交更改

我们可以看到存在了Jenkinsfile,然后我们再把仓库的URL复制到Jenkins里面

完成之后保存即可

然后构建

4. 体验Jenkins流水线语法转换

当然Jenkins也给我们流水线的项目提供了语法参考与转换

五、Java项目发布流程

apache-maven安装包下载_开源镜像站-阿里云

1.Maven介绍与安装

bash 复制代码
Maven是一个项目管理和综合工具。Maven提供给开发人员构建一个完整的生命周期框架。
开发团队可以自动完成该项目的基础设施建设,Maven使用标准的目录结构和默认构建生命周期。
Apache的开源项目主要服务于JAVA平台的构建、依赖管理、项目管理。
Project Object Model,项目对象模型。通过xml格式保存的pom.xml文件。该文件用于管理:源代码、配置文
件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。该文件是由开
发维护,我们运维人员可以不用去关心。

# 安装Maven
[root@Jenkins ~]# tar xf apache-maven-3.3.9-bin.tar.gz 
[root@Jenkins ~]# mv apache-maven-3.3.9 /usr/local/
[root@Jenkins ~]# ln -s /usr/local/apache-maven-3.3.9/ /usr/local/maven
[root@Jenkins ~]# ll /usr/local/
total 0
drwxr-xr-x 6 root root 99 Feb 19 16:59 apache-maven-3.3.9
。。。。
lrwxrwxrwx 1 root root 30 Feb 19 17:00 maven -> /usr/local/apache-maven-3.3.9/
[root@Jenkins ~]# tail -1 /etc/profile
export PATH="$PATH:/usr/local/sonar-scanner/bin:/usr/local/apache-maven-3.3.9/bin/"
[root@Jenkins ~]# source /etc/profile
[root@Jenkins ~]# mvn -v
which: no javac in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/sonar-scanner/bin:/root/bin:/usr/local/apache-maven-3.3.9/bin/:/usr/local/sonar-scanner/bin:/usr/local/apache-maven-3.3.9/bin/)
Warning: JAVA_HOME environment variable is not set.
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)
Maven home: /usr/local/apache-maven-3.3.9
Java version: 11.0.25, vendor: BiSheng
Java home: /usr/lib/jvm/java-11-openjdk-11.0.25.9-3.p01.ky10.x86_64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.19.90-52.22.v2207.ky10.x86_64", arch: "amd64", family: "unix"

# 上传一个简单的java项目包hello‐world.tar.gz进行解压
[root@Jenkins ~]# tar xf hello-world.tar.gz 
[root@Jenkins ~]# cd hello-world-war/
[root@Jenkins ~/hello-world-war]# ll
total 8
drwxr-xr-x 2 root root  29 May 23  2014 dist
-rw-r--r-- 1 root root 931 May 14  2024 pom.xml
-rw-r--r-- 1 root root 213 May 23  2014 README.md
drwxr-xr-x 3 root root  18 May 23  2014 src
[root@Jenkins ~/hello-world-war]# mvn package
....
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:01 min
[INFO] Finished at: 2025-02-19T17:05:50+08:00
[INFO] Final Memory: 14M/83M
[INFO] ------------------------------------------------------------------------

进入目录执行打包命令
validate(验证): 验证项目正确,并且所有必要信息可用。
compile(编译): 编译项目源码
test(测试): 使用合适的单元测试框架测试编译后的源码。
package(打包): 源码编译之后,使用合适的格式(例如JAR格式)对编译后的源码进行打包。
integration‐test(集成测试): 如果有需要,把包处理并部署到可以运行集成测试的环境中去。
verify(验证): 进行各种测试来验证包是否有效并且符合质量标准。
install(安装): 把包安装到本地仓库,使该包可以作为其他本地项目的依赖。
deploy(部署): 在集成或发布环境中完成,将最终软件包复制到远程存储库,以与其他开发人员和项目共享。
mvn clean (清除) : 清除上次编译的结果
mvn package ‐Dmaven.test.skip=true 跳过测试用例


# web02部署tomcat
[root@web02 ~]# netstat -nltup|grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      3416/java           
# 将war包拷贝tomcat的站点目录下
[root@jenkins:hello-world-war]#scp target/hello-world-war-1.0.0.war 10.0.0.8:/soft/tomcat/webapps/ROOT/

# 解压war包 启动tomcat访问
[root@web02:ROOT]#unzip hello-world-war-1.0.0.war
[root@web02:ROOT]#/usr/local/tomcat/bin/startup.sh

# 浏览器打开访问: 10.0.0.8:8080

2.将默认的maven仓库源修改为国内的

bash 复制代码
[root@Jenkins /usr/local/maven/conf]# pwd
/usr/local/maven/conf
[root@Jenkins /usr/local/maven/conf]# grep -n -C 5 aliyun settings.xml 
148-     | Specifies a repository mirror site to use instead of a given repository. The repository that
149-     | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
150-     | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
151-     |
152-    <mirror>
153:      <id>nexus-aliyun</id>
154-      <mirrorOf>*</mirrorOf>
155:      <name>Nexus aliyun</name>
156:      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
157-    </mirror>
158-     -->
159-  </mirrors>
160-
161-  <!-- profiles

我们再次执行一下mvn package查看仓库是否来源阿里云
[root@Jenkins ~/hello-world-war]# pwd
/root/hello-world-war
[root@Jenkins ~/hello-world-war]# mvn clean
[root@Jenkins ~/hello-world-war]# mvn package

注意:如果公司部分java代码 不需要配置nexus私服,只需要将maven配置文件仓库指向阿里云仓库
如果公司是重java项目,则需要搭建私有的仓库nexus

3.集成到jenkins

我们的gitlab也创建一个新的Java仓库,把我们的hello-world代码上传进去

我们将代码目录上传到仓库中,在此之前,优化一下我们的仓库

bash 复制代码
[root@Jenkins ~/hello-world-war]# ll -a
total 16
drwxr-xr-x  6 root root  105 Feb 19 17:17 .
dr-xr-x--- 13 root root 4096 Feb 19 17:15 ..
drwxr-xr-x  2 root root   29 May 23  2014 dist
drwxr-xr-x  8 root root  166 Oct 15  2019 .git
-rw-r--r--  1 root root   42 May 23  2014 .gitignore
-rw-r--r--  1 root root  931 May 14  2024 pom.xml
-rw-r--r--  1 root root  213 May 23  2014 README.md
drwxr-xr-x  3 root root   18 May 23  2014 src
drwxr-xr-x  4 root root   90 Feb 19 17:17 target
[root@Jenkins ~/hello-world-war]# mvn clean
[root@Jenkins ~/hello-world-war]# git remote add origin git@10.0.0.200:BestCode/java.git
fatal: remote origin already exists.
[root@Jenkins ~/hello-world-war]# git remote remove origin 
[root@Jenkins ~/hello-world-war]# git remote add origin git@10.0.0.200:BestCode/java.git
[root@Jenkins ~/hello-world-war]# git config --global user.name "caofacan"
[root@Jenkins ~/hello-world-war]# git config --global user.email "cao@cfc.com"
[root@Jenkins ~/hello-world-war]# git add .
[root@Jenkins ~/hello-world-war]# git commit -m "first java code"
[master 7657698] first java code
 2 files changed, 3 insertions(+), 3 deletions(-)
[root@Jenkins ~/hello-world-war]# git push -u origin master 

回到Jenkins接入 Maven

完成之后保存构建即可

进阶一下,我们执行shell自动化拉取部署Java代码,然后构建

bash 复制代码
scp target/*.war 10.0.0.8:/soft/tomcat/webapps/
ssh 10.0.0.8 "cd /soft/tomcat/webapps/ && mkdir java_${BUILD_ID}"
ssh 10.0.0.8 "cd /soft/tomcat/webapps/ && unzip *.war -d java_${BUILD_ID} && rm -rf *.war"
ssh 10.0.0.8 "cd /soft/tomcat/webapps/ && rm -rf ROOT && ln -s 	java_${BUILD_ID} ROOT" 
ssh 10.0.0.8 "/soft/tomcat/bin/shutdown.sh && sleep 1 && /soft/tomcat/bin/startup.sh"
bash 复制代码
[root@web02 /soft/tomcat/webapps]# ll
total 4
drwxr-x--- 16 root root 4096 Feb 19 17:08 docs
drwxr-x---  7 root root   99 Feb 19 17:08 examples
drwxr-x---  6 root root   79 Feb 19 17:08 host-manager
drwxr-xr-x  2 root root    6 Feb 19 17:45 java_2
drwxr-xr-x  4 root root   54 Feb 19 17:49 java_3
drwxr-x---  6 root root  114 Feb 19 17:08 manager
lrwxrwxrwx  1 root root    6 Feb 19 17:49 ROOT -> java_3

web02直接访问也没有问题

4. 配置nexus私服

bash 复制代码
部署私服 xenus 下载https://www.sonatype.com/download‐oss‐sonatype
配置仓库两个选项
1、项目下的pom.xml配置、只生效当前的项目
2、在maven配置全局所有项目生效
3.上传JDK和nexus的包
[root@nexus ~]# ll
total 286068
-rw-r--r-- 1 root root 170023183 Sep 27 17:19 jdk-8u181-linux-x64.rpm
-rw-r--r-- 1 root root 122904706 Sep 27 17:19 nexus-3.13.0-01-unix.tar.gz
[root@nexus ~]# rpm -ivh jdk-8u181-linux-x64.rpm 
[root@nexus ~]# tar xf nexus-3.13.0-01-unix.tar.gz
[root@nexus ~]# mv nexus-3.13.0-01 /usr/local/nexus
[root@nexus ~]# /usr/local/nexus/bin/nexus start
WARNING: ************************************************************
WARNING: Detected execution as "root" user.  This is NOT recommended!
WARNING: ************************************************************
Starting nexus

# 浏览器访问$IP:8081端口

用户名/密码: admin/admin123

配置nexus仓库指向阿里云

修改jenkins编译指向nexus私服

bash 复制代码
[root@jenkins:~]#cd /usr/local/maven/conf/
[root@jenkins:conf]#mv settings.xml settings.xml.bak
上传配置文件

修改配置文件信息:
[root@jenkins:conf]#vim settings.xml
132     -->
133      <server>
134      <id>my-nexus-releases</id>
135      <username>admin</username>
136      <password>admin123</password>
137      </server>
138      <server>
139      <id>my-nexus-snapshot</id>
140      <username>admin</username>
141      <password>admin123</password>
142      </server>
143   </servers>
144 
...

155    |-->
156   <mirrors>
157   <mirror>
158   <id>nexus</id>
159   <mirrorOf>*</mirrorOf>
160   <url>http://10.0.0.204:8081/repository/maven-public/</url>
161 </mirror>
162     <!-- mirror
....
261     -->
262 <profile>
263   <id>nexus</id>
264   <repositories>
265     <repository>
266       <id>central</id>
267       <url>http://10.0.0.204:8081/repository/maven-public/</url>
268       <releases><enabled>true</enabled></releases>
269       <snapshots><enabled>true</enabled></snapshots>
270     </repository>
271   </repositories>
272  <pluginRepositories>
273     <pluginRepository>
274       <id>central</id>
275       <url>http://10.0.0.204:8081/repository/maven-public/</url>
276       <releases><enabled>true</enabled></releases>
277       <snapshots><enabled>true</enabled></snapshots>
278     </pluginRepository>
279   </pluginRepositories>
280 </profile>
281   </profiles>
282 

...
290   -->
291 <activeProfiles>
292 <activeProfile>nexus</activeProfile>
293 </activeProfiles>
294 </settings>

再次mvn package

bash 复制代码
Downloaded: http://10.0.0.204:8081/repository/maven-public/commons-io/commons-io/2.6/commons-io-2.6.jar (0 B at 0.0 KB/sec)
[INFO] Packaging webapp
[INFO] Assembling webapp [hello-world-war] in [/root/hello-world-war/target/hello-world-war-1.0.0]
[INFO] Processing war project
[INFO] Copying webapp resources [/root/hello-world-war/src/main/webapp]
[INFO] Building war: /root/hello-world-war/target/hello-world-war-1.0.0.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:49 min
[INFO] Finished at: 2025-02-19T20:14:01+08:00
[INFO] Final Memory: 13M/101M
[INFO] ------------------------------------------------------------------------

就是先从私服下载,没有再去阿里云仓库。

还是那句话 ------> 注意:如果公司部分java代码 不需要配置nexus私服,只需要将maven配置文件仓库指向阿里云仓库 如果公司是重java项目,则需要搭建私有的仓库nexus.

六、配置Jenkins分布式(拓展)

如果项目需要定期集成,同时每次集成都需要较长时间。如果都运行在master服务器上,会消耗过多资源,导致其他项

目搁置无法集成,这时就需要在建立多台设备,并配置作为slave机器来为master提供负载服务。

1. 部署分布式服务器

bash 复制代码
1.找一台或者目前已有的服务器配置为slave端
[root@lb01 ~]# rpm -ivh jdk-17_linux-x64_bin.rpm 
2. 配置Jenkins与从节点免密钥
[root@Jenkins ~]# ssh-copy-id 10.0.0.5
既然是从节点,那么配置就要和主节点相同
[root@jenkins:~]#scp -r /usr/local/sonar-scanner 10.0.0.5:/usr/local/
[root@jenkins:~]#scp -r /usr/local/maven/ 10.0.0.5:/usr/local/
3.jenkins服务端添加从节点lb01
PS: 把lb01的公钥上传至gitlab 拥有下载代码的权限
点击系统管理->节点管理->新建节点
[root@lb01 ~]# ssh-keygen 
[root@lb01 ~]# cat .ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCukeQGhURJgDbIp189+pWRukYoLY34YtxFJ9ffjOcj79DrXSqvc2eudlfESVidnAcxi1+09+kZwiWgWBHGzMvAcWpf6BZQnPulWfdqJHUZvCL1OBKEiFenN+Dt9F/89dIvLJBjHyXzw63F8tzrZ3NjUEMhMIe3hRjrY+l9ZpX6xE+GfWY1G+1tZx+2LU9E7WJmdd+eOBXHO/zBPjx7EN3jLZbcx8X2pIUA60Czj0VD8sLWEWMFfeCaD55X+45/yDA47PNCwyuyihM+Bdr5vpG647RB8UwcyDzgfoGAFGnQ8yCKjCOjYCnxPe1eS/O5nGEJ4dqmVdAFLz2uDRj/cDczggvqoOPvlOQ700thsZIxkXRDU1J3Dq0SU5j7ZUqwvuiwr8+dwDKip/M8puB0BFVUVF/cN2p3/k/owx0d1omHU59JJGBmaPIT+uNGwA1fiE5NBsSpH+QUg0y8g0KIl8zXw/qiz61/mQ5kd/3qHXqsYXipgxOYt1CsgbxOKQPg2iM= root@lb01
bash 复制代码
[root@lb01 ~]# umount /tmp 
[root@lb01 ~]# systemctl mask tmp.mount 
Created symlink /etc/systemd/system/tmp.mount → /dev/null.


Jenkins的主节点也最好做一个
[root@Jenkins ~]# umount /tmp 
umount: /tmp: target is busy.
[root@Jenkins ~]# umount -fl /tmp 
[root@Jenkins ~]# systemctl mask tmp.mount 
Created symlink /etc/systemd/system/tmp.mount → /dev/null.
[root@Jenkins ~]# systemctl restart jenkins.service

2. jenkins添加从节点lb01

注意,这里最好取消机器的tmp的挂载,Jenkins默认将tmp作为机器的储存。(kylin系统的老毛病,如果是其他系统默认不会挂载/tmp)

3. 配置工具的家目录位置

保存后发现

4. 测试

多点几个项目同时执行

七、总结

本文详细介绍了如何构建一个完整的CI/CD流程,整合GitLab、Jenkins、SonarQube和Nexus四大工具。首先在Ubuntu系统上安装配置GitLab作为代码仓库,并演示了代码提交与权限控制流程。接着安装Jenkins实现自动化构建与部署,通过Webhook实现代码提交自动触发。然后部署SonarQube进行代码质量检测,并集成到Jenkins流程中。针对Java项目,介绍了Maven构建工具的使用,以及Nexus私服的配置方法。最后拓展了Jenkins分布式构建的实现,通过添加从节点提升构建效率。整个流程覆盖了代码版本控制、自动化构建、代码质量检测、依赖管理和分布式构建等关键环节,为企业提供了一个高效、可靠的持续集成与持续交付解决方案。

相关推荐
Sally璐璐几秒前
OpenVPN:深度解析开源 VPN 解决方案
运维·开源
阿巴~阿巴~27 分钟前
理解Linux文件系统:从物理存储到统一接口
linux·运维·服务器
tan77º1 小时前
【Linux网络编程】应用层自定义协议与序列化
linux·运维·服务器·网络·c++·tcp/ip
wanhengidc1 小时前
在徐州网络中服务器租用与托管的优势
运维·服务器·网络
Guheyunyi2 小时前
电气安全监测系统:筑牢电气安全防线
大数据·运维·网络·人工智能·安全·架构
音程3 小时前
(已解决) 如何使用密钥连接远程服务器jupyter notebook从而在本地浏览器上打开
运维·服务器·python·jupyter
妫以明4 小时前
Ubuntu——多媒体应用推荐与安装(音频、视频、图片)
linux·运维·ubuntu·vlc
不做菜鸟的网工5 小时前
开源IPPBX-Asterisk部署
运维
Dusk_橙子5 小时前
在Linux中,如何使用grep awk sed find?
linux·运维·chrome
星辰大海14125 小时前
AI Linux 运维笔记
运维·笔记