前言
在当今数字化飞速发展的时代,软件开发与交付的效率和质量成为了企业竞争的关键要素。为了满足市场对软件快速迭代和高质量交付的需求,越来越多的企业开始探索和实践持续集成与持续交付(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安装包下载_开源镜像站-阿里云
# 关闭防火墙
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
出现以下页面表示安装成功:
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
我们在配置文件中添加我们的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.200user:
rootPasswd: #存在与我们的文件包里面
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
root@git:~# ssh-keygenroot@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.使用项目仓库
命令行将空的仓库下载到本地
# 这里粗心了,创建了一个和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.01 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.本地代码已经存在
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.2py5 files changed, 0 insertions(+), 0 deletions(-)create mode 100644 1.pycreate mode 100644 2.pycreate mode 100644 3.pycreate mode 100644 4.pycreate 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.21 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.gitef66792..7d53f65 master -> master
4. Gitlab权限控制
1. 创建普通用户dev赋予对应权限
管理中心------>仪表盘----->新建用户
点击编辑,设置登录密码(dev@123.com)
使用普通账号登录gitlab 默认里面空的
开第二个窗口,因为cookie的原因,浏览器只能存储一个cookie。
将dev账号添加到BestCode组中,dev用户拥有game项目的权限。
模拟开发人员下载代码到本地服务器
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群组里面,所以我们普通用户加入到这个群组之后,就能看到所以的项目了,这里没有细分。
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用户上传代码流程
# 我们模拟一下修改代码
[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 = devemail = 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
# 安装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的插件目录下。
# 上传我们打包好的插件包
[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仓库拉取代码进行构建。
2. Maven Integration Plugin
用于与Maven构建工具集成,帮助执行Maven构建生命周期,自动化Maven项目的构建过程。
3. Pipeline Plugin
使Jenkins支持声明式和脚本化的流水线(Pipeline),可以定义和管理CI/CD工作流。
4. Blue Ocean Plugin
提供一个现代化的Jenkins用户界面,支持直观地查看流水线、作业和结果,帮助用户轻松管理和监控流水线。
5. Slack Notification Plugin
可以将Jenkins构建的状态(成功、失败、稳定等)发送到Slack频道,方便团队实时查看构建结果。
6. Docker Pipeline Plugin
使Jenkins流水线能够轻松与Docker集成,支持在Docker容器中运行构建和测试。
7. JUnit Plugin
用于展示JUnit测试结果,生成测试报告,并将其集成到Jenkins中,便于查看测试的成功率和失败详情。
8. GitHub Plugin
用于将Jenkins与GitHub集成,自动触发构建、同步GitHub代码库等。
9. Parameterized Trigger Plugin
允许Jenkins作业触发其他作业,并支持传递参数,从而实现复杂的作业依赖和多阶段构建流程。
10. Credentials Binding Plugin
让你能够在构建过程中安全地使用密钥、用户名等敏感信息,而不暴露在构建日志中。
这些插件能够帮助你在Jenkins中实现自动化构建、测试、部署、通知等各种功能,极大提升工作流的效率。
Jenkins默认的用户为admin
下翻找到密码
因为是测试环境我修改为了123456
2.体验Jenkins的自动化
a.克隆代码
进入到代码目录,下载game的代码
[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的代码
# 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
出现报错,分析错误,解决报错
现在本地拉一下,把验证过了之后,删除即可
[root@Jenkins /tmp]# git clone git@10.0.0.200:BestCode/game.git
完成后执行构建,绿色表示没有问题
# 查看拉取的代码
[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服务器上面
我们再将拉下来的代码推送到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服务器查看代码目录是否已经存在
[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环境
[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
[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'],
[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勾子
# 保存一下我们的token
6ee0bae8420a9901385f33d4957ca68c
# 保存一下URL:
http://10.0.0.202:8080/project/game_job
跳到我们的gitlab添加钩子
然后构建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.html1 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.gitf089fe6..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
# 安装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
安装插件
[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
## 信息要保留下来
sonar-scanner \-Dsonar.projectKey=html \-Dsonar.sources=. \-Dsonar.host.url=http://10.0.0.203:9000 \-Dsonar.login=73b11ffacb7d24ecabb161c592797a2e0bda3d57
2.客户端扫描代码后上传sonar服务端
# 安装客户端在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=73b11ffacb7d24ecabb161c592797a2e0bda3d57INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 8.098s
INFO: Final Memory: 7M/116M
INFO: ------------------------------------------------------------------------
成功
3.配置jenkins集成soanrqube
# 修改配置文件指向 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的工程
sonar.projectName=${JOB_NAME} # 项目在sonarqube上的显示名称
sonar.projectKey=html # 项目的唯一表示,不能重复
sonar.sources=. # 扫描那个项目的源码
然后Jenkins就可以立即构建了
这里我们走一遍完整的流程
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.git3a515cf..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 类型
声明式
1. 声明式 Pipeline:- 提供了更简洁和结构化的语法。- 示例:pipeline {agent anystages {stage('Build') {steps {echo 'Building...'}}stage('Test') {steps {echo 'Testing...'}}stage('Deploy') {steps {echo 'Deploying...'}}}}
脚本式
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介绍与安装
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仓库源修改为国内的
[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代码上传进去
我们将代码目录上传到仓库中,在此之前,优化一下我们的仓库
[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 code2 files changed, 3 insertions(+), 3 deletions(-)
[root@Jenkins ~/hello-world-war]# git push -u origin master
回到Jenkins接入 Maven
完成之后保存构建即可
进阶一下,我们执行shell自动化拉取部署Java代码,然后构建
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"
[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_3web02直接访问也没有问题
4. 配置nexus私服
部署私服 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私服
[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
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. 部署分布式服务器
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
[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分布式构建的实现,通过添加从节点提升构建效率。整个流程覆盖了代码版本控制、自动化构建、代码质量检测、依赖管理和分布式构建等关键环节,为企业提供了一个高效、可靠的持续集成与持续交付解决方案。