banner
云野阁

云野阁

闲云野鹤,八方逍遥

Jenkins知識梳理

🔜什麼是Jenkins?🔚

Jenkins 是一款基於 Java 開發的開源 CI&CD 軟體,用於自動化各種任務,包括構建、測試和部署軟體。Jenkins 提供多種安裝方式,提供超過 1000 個插件來滿足任何項目的需要。

Jenkins 的特徵:

  • 開源的 Java 語言開發持續集成工具,支持持續集成,持續部署。
  • 易於安裝部署配置:可通過 yum 安裝,或下載 war 包以及通過 docker 容器等快速實現安裝部署,可方便 web 界面配置管理。
  • 消息通知及測試報告:集成 RSS/E-mail 通過 RSS 發布構建結果或當構建完成時通過 e-mail 通知,生成 JUnit/TestNG 測試報告。
  • 分佈式構建:支持制 Jenkins 能夠讓多台計算機一起構建 / 測試。
  • 文件識別:Jenkins 能夠跟蹤哪次構建生成哪些 jar, 哪次構建使用哪個版本的 jar 等。
  • 豐富的插件支持:支持擴展插件,你可以開發適合自己團隊使用的工具,如 git,svn,maven,docker 等。

本文通過 GitLab+Jenkins+Tomcat,構建 CI/CD 流程。

主機規劃#

主機名ip所需軟體用途
121192.168.1.121GitLab-12.4.2代碼托管
124192.168.1.124Jenkins、JDK-21、Maven-3.9.9、
Git、SonarQube
Jenkins 持續集成
125192.168.1.125JDK-1.8、Tomcat-8.5發布測試

伺服器操作系統為 centos7.9

部署步驟#

部署 GitLab#

安裝 GitLab#

安裝依賴

yum -y install policycoreutils-python policycoreutils postfix

下載並安裝 gitlab

#下載gitlab安裝包
curl -O  http://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-12.4.2-ce.0.el7.x86_64.rpm
#安裝gitlab
rpm -i gitlab-ce-12.4.2-ce.0.el7.x86_64.rpm

修改 gitlab 默認訪問端口

vi /etc/gitlab/gitlab.rb

#將默認端口80修改為82
external_url "http://192.168.1.121:82"
nginx['listen_port'] = 82

重載配置,啟動 gitlab

gitlab-ctl reconfigure
gitlab-ctl restart

配置防火牆策略

firewall-cmd --add-port=82/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-all

在瀏覽器中輸入http://192.168.1.121:82/, 修改 root 用戶密碼,並用 root 用戶登錄 gitlab

管理 GitLab#

(1)創建組

使用管理員 root 創建組,一個組裡面可以有多個項目分支,可以將開發添加到組裡面進行設置權限,不同的組就是公司不同的開發項目或者服務模塊,不同的組添加不同的開發即可實現對開發設置權限的管理。

(2)創建項目

(3)創建用戶

在管理中心 - 概覽 - 用戶中,創建一個新用戶test1,並設置密碼,將用戶加入剛創建的項目中。

Gitlab 用戶在組裡面有 5 種不同權限:

  • Guest:可以創建 issue、發表評論,不能讀寫版本庫
  • Reporter:可以克隆代碼,不能提交,QA、PM 可以賦予這個權限
  • Developer:可以克隆代碼、開發、提交、push, 普通開發可以賦予這個權限
  • Maintainer:可以創建項目、添加 tag、保護分支、添加項目成員、編輯項目,核心開發可以賦予這個權限
  • Owner:可以設置項目訪問權限 Visibility Level、刪除項目、遷移項目、管理組成員,卉發組組長可以賦予這個權限

上傳項目代碼#

使用 idea 創建 java 項目,並上傳至 gitlab 倉庫

本文中使用的 java 項目代碼,源自 b 站 up 主,'' 涣沷 a 靑惷 '',原文鏈接為: https://www.yuque.com/huanfqc/jenkins/jenkins。

java 代碼地址為: https://share.feijipan.com/s/qdEO7czl

將項目導入 idea 中,並配置 gitlab 相關設置,推送代碼,具體步驟參考上面提到的原文鏈接。

部署 Jenkins#

安裝 jenkins-2.19 * 版本時,無法正常安裝中文插件。本文使用的 jdk 為 jdk-21、jenkins 為 2.492.3,且均為 rpm 方式安裝

(1)安裝 jdk

yum install -y wget && wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.rpm
rpm -ivh jdk-21_linux-x64_bin.rpm
#查看版本
java -version

(2)安裝 Jenkins

#下載jenkins
curl -O https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.492.3-1.1.noarch.rpm
#安裝
rpm -ivh jenkins-2.492.3-1.1.noarch.rpm

(3)修改 jenkins 的配置文件

vi /etc/sysconfig/jenkins
#修改默認用戶為root
JENKINS_USER="root"
#修改默認端口為8888
JENKINS_PORT=8888

(4)配置防火牆策略,並啟動 jenkins

firewall-cmd --add-port=8888/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-all
#啟動jenkins
systemctl daemon-reload
systemctl start jenkins
systemctl enable jenkins

(5)查看 jenkins 的 admin 初始化密碼

cat /var/lib/jenkins/secrets/initialAdminPassword

(6)在瀏覽器中輸入http://192.168.1.124:8888 / 訪問,輸入 admin 初始化密碼。

(7)點擊選擇插件來安裝,選擇,跳過安裝插件,為之後重新配置下載插件的國內源做準備。

1

(8)按引導完成 jenkins 的安裝。

配置國內插件源#

(1)選擇左側邊欄中的 Jenkins -Manage Jenkins-Manage Plugins,選擇 Available,等待插件相關文件的加載。

(2)進入插件的目錄,將地址修改為國內源

cd /var/lib/jenkins/updates && ll
sed -i 's|http://updates.jenkins-ci.org/download|https://mirrors.tuna.tsinghua.edu.cn/jenkins|g' default.json
sed -i 's|http://www.google.com|https://www.baidu.com|g' default.json

(3)訪問 jenkins,選擇左側邊欄中的 Jenkins -Manage Jenkins-Manage Plugins,選擇 Advanced,把 Update Site 改為https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json(或者https://mirrors.huaweicloud.com/jenkins/updates/update-center.json),保存,在瀏覽器中輸入http://192.168.1.124:8888/restart,點擊並重啟 jenkins。

設置中文#

安裝中文插件,選擇左側邊欄中的 Jenkins -Manage Jenkins-Manage Plugins,選擇 Advanced,搜索chinese,勾選插件,並點擊下載並重啟。

管理用戶權限#

安裝Role-based Authorization Strategy插件,管理用戶權限。安裝完成後,(新版 jenkins)選擇 Manage Jenkins-Security,授權策略選擇 Role-Based Strategy。選擇 Manage Jenkins-Manage and Assign Roles,進行角色的創建和分配管理。

憑證管理#

(1)安裝Credentials Binding插件,進行憑證管理。

憑證類型:

  • Username with password:用戶名和密碼
  • SSH Username with private key:使用 ssH 用戶和密鑰
  • Secret file:需要保密的文本文件,使用時 Jenkins 會將文件複製到一個臨時目錄中,再將文件路徑設置到一個變量中,等構建結束後,所複製的 Secret file 就會被刪除。
  • Secret text:需要保存的一個加密的文本串,如釘釘機器人或 Github 的 api token
  • Certificate:通過上傳證書文件的方式

常用的憑證類型有:Username with password (用戶密碼) 和 SSH Username with private key (SSH 密鑰)

(2)安裝git插件,並在伺服器上下載 git。

yum -y install git
密碼憑證#

(1)創建 jenkins 項目和密碼憑證。選擇 Manage Jenkins-Credentials,點擊全局-Add Credentials,添加 gitlab 用戶 test1 的用戶名和密碼,創建憑證。

2

(2)創建一個新任務test01,點擊配置,設置源碼管理為 Git,填寫 gitlab 的項目倉庫地址(http 開頭),選擇 test1 的憑證,保存即可。

(3)進入 test01,點擊 Build Now,等待任務構建完成後,點擊控制台輸出查看詳細信息。

3

4

SSH 密鑰憑證#

(1)在 jenkins 伺服器中創建 SSH 密鑰。

ssh-keygen -t rsa
#查看公鑰內容
cat ~/.ssh/id_rsa.pub
# 測試 SSH 連接
ssh -T [email protected]
# 查看是否有gitlab主機,確保有該主機,否則使用ssh憑證時會報錯
cat ~/.ssh/known_hosts

(2)使用管理員賬戶登錄 Gitlab,選擇設置-SSH密鑰,填入 SSH 公鑰內容,並保存。

(3)在伺服器中使用命令cat ~/.ssh/id_rsa,查看私鑰內容。在 jenkins 中創建 SSH 密鑰憑證,輸入用戶名 root 和 SSH 私鑰內容,保存即可。

5

(4)創建一個新任務test02,點擊配置,設置源碼管理為 Git,填寫 gitlab 的項目倉庫地址(git 開頭),選擇 SSH 憑證,保存即可。

(5)進入 test02,點擊 Build Now,等待任務構建完成後,點擊控制台輸出查看詳細信息。

6

安裝 Maven#

(1)下載安裝 Maven

curl -O https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.tar.gz
#創建存儲目錄
mkdir -p /opt/maven
tar -vxzf apache-maven-3.9.9-bin.tar.gz -C /opt/maven/
#配置環境變量,使環境生效
echo "
export MAVEN_HOME=/opt/maven/apache-maven-3.9.9
export PATH=\$PATH:\$MAVEN_HOME/bin" >> /etc/profile
source /etc/profile
#查看maven版本
mvn -v

(2)配置 jenkins 與 maven 關聯

在 Manage Jenkins-Tools 中配置JDK安裝Maven安裝,配置其對應安裝路徑。

8

在 Manage Jenkins-System - 全局屬性中,新增 3 個Environment variables

7

(3)修改 Maven 的本地倉庫位置

#創建本地倉庫
mkdir -p /data/jenkins/repo
#修改Maven的配置文件
vi /opt/maven/apache-maven-3.9.9/conf/settings.xml
#將<localRepository>/path/to/local/repo</localRepository>修改為
  <localRepository>/data/jenkins/repo</localRepository>
  
#在<id>maven-default-http-blocker</id>所在的鏡像後添加阿里雲鏡像源
#    <mirror>
#      <id>maven-default-http-blocker</id>
#      <mirrorOf>external:http:*</mirrorOf>
#      <name>Pseudo repository to mirror external repositories initially using HTTP.</name>
#      <url>http://0.0.0.0/</url>
#      <blocked>true</blocked>
#    </mirror>
    <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
      <mirrorOf>central</mirrorOf>
    </mirror>

(4)測試 Maven 配置

在 jenkins 中選擇任務test02,選擇配置 - Environment-Build Steps,選擇 Execute shell 中輸入命令mvn clean package, 保存後,點擊 Build Now,等待任務構建完成後,點擊控制台輸出查看詳細信息。

9

10

此時伺服器上的 test02 任務目錄中會新增一個target目錄。

[root@124 workspace]# ls
test01 test01@tmp test02 test02@tmp
[root@124 workspace]# cd test01
[root@124 test01]# ls
pom.xml src
[root@124 test01]# cd ..
[root@124 workspace]# ls
test01 test01@tmp test02 test02@tmp
[root@124 workspace]# cd test02
[root@124 test02]# ls
pom.xml src target
[root@124 test02]# pwd
/var/lib/jenkins/workspace/test02
[root@124 test02]#

安裝 Tomcat#

下載 jdk-1.8 和 tomcat-9

yum install -y java-1.8.0-openjdk*
curl -O https://mirrors.huaweicloud.com/apache/tomcat/tomcat-9/v9.0.104/bin/apache-tomcat-9.0.104.tar.gz
#創建存儲目錄
mkdir -p /opt/tomcat/
#解壓
tar -zxvf apache-tomcat-9.0.104.tar.gz -C /opt/tomcat/
#啟動tomcat
/opt/tomcat/apache-tomcat-9.0.104/bin/startup.sh

配置防火牆策略

firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-all

在瀏覽器中訪問http://192.168.1.125:8080/

11

配置 tomcat 的用戶角色

vi  /opt/tomcat/apache-tomcat-9.0.104/conf/tomcat-users.xml

<!--在tomcat-users標籤下添加以下內容 -->

<role rolename="tomcat"/>
<role rolename="role1"/>
<role rolename="manager-script"/>
<role rolename="manager-gui"/>
<role rolename="manager-status"/>
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<user username="tomcat" password="tomcat" roles="manager-gui,manager-script,tomcat,admin-gui,admin-script"/>

配置 tomcat 的遠程訪問地址範圍

vi /opt/tomcat/apache-tomcat-9.0.104/webapps/manager/META-INF/context.xml
<!-- 將以下內容註釋-->
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />

重啟 tomcat,輸入用戶名和密碼進行訪問。

#停止運行
/opt/tomcat/apache-tomcat-9.0.104/bin/shutdown.sh
#啟動
/opt/tomcat/apache-tomcat-9.0.104/bin/startup.sh

Jenkins 構建項目#

Jenkins 中自動構建項目的類型有很多,常用的有以下三種:

  • 自由風格軟體項目 (FreeStyle Project)
  • Maven 項目 (Maven Project)
  • 流水線項目 (Pipeline Project)

本文構建項目時使用的 war 包,源自 b 站 up 主,'' 涣沷 a 靑惷 '',原文鏈接為: https://www.yuque.com/huanfqc/jenkins/jenkins。

war 包項目代碼地址為:https://share.feijipan.com/s/BWEO9Jad,war 包構建具體過程見原文。

Jenkins 構建自由風格項目#

(1)安裝 Deploy to container 插件

(2)新建項目 freestyle_demo,配置並拉取 gitlab 中 test_war 代碼,該過程除包含步驟《部署 Jenkins》的過程外,還需進行構建後操作,具體如下圖。

12

(3)配置保存後,點擊 Build Now,等待任務構建完成後,訪問 tomcat,可以看到/websocketChat-1.0-SNAPSHOT虛擬目錄已出現。

13

Jenkins 構建 Maven 項目#

(1)安裝Maven Integration插件

(2)新建項目 maven-demo,配置並拉取 gitlab 中 test_war 代碼,該過程除包含步驟《Jenkins 構建自由風格項目的過程外,還需要在 Build 時進行修改,具體如下圖。

14

構建時出現報錯可將之前配置的阿里雲鏡像地址改為 https

(3)配置保存後,點擊 Build Now,等待任務構建完成後,訪問 tomcat,可以看到/websocketChat-1.0-SNAPSHOT虛擬目錄已出現。

Jenkins 構建 Pipeline 流水線項目#

Pipeline, 簡單來說,就是一套運行在 Jenkins 上的工作流框架,將原來獨立運行於單個或者多個節點的任務連接起來,實現單個任務難以完成的複雜流程編排和可視化的工作。

如何創建 Jenkins Pipeline 呢?

  • Pipeline 腳本是由 Groovy 語言實現的。

  • Pipeline 支持兩種語法:Declarative (聲明式) 和 Scripted Pipeline (腳本式) 語法。

  • Pipeline 也有兩種創建方法:可以直接在 Jenkins 的 Web Ul 界面中輸入腳本;也可以通過創建一個 Jenkinsfile 腳本文件放入項目源碼庫中(一般我們都推薦在 Jenkins 中直接從源代碼控制 (SCM) 中直接載入 Jenkinsfile Pipeline 這種方法)。

在 Jenkins 的 Web Ul 中創建 Pipeline 腳本發布項目#

(1)安裝 Pipeline 插件

(2)新建任務 Pipeline-demo,使用聲明式語法,在 Jenkins 的 Web Ul 裡創建 Pipeline 腳本;實現從代碼拉取、編譯構建、到發布項目。

在 Pipeline-demo 的配置界面,選擇構建觸發器 - 流水線,選擇一個腳本模板 Hello Word。

15

點擊流水線語法,在片段生成器中選擇checkout:Check out from version control,按引導填寫項目地址和憑證,生成流水線腳本,將拉取代碼腳本粘貼到修改後的模板中。

在片段生成器中選擇sh:Shell Script,填寫編譯命令,生成流水線腳本,將腳本粘貼到修改後的模板中。

在片段生成器中選擇deploy:Deploy war/ear to a container,按引導填寫,生成流水線腳本,將腳本粘貼到修改後的模板中。

pipeline {
    agent any

    stages {
        stage('拉取代碼') {
            steps {
                checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'fbf87557-40b6-468a-91c5-2cfa1b2e33e8', url: 'http://192.168.1.121:82/test/test_war_demo.git']])
            }
        }
        stage('編譯構建') {
            steps {
                sh 'mvn clean package'
            }
        }
        stage('發布項目') {
            steps {
                deploy adapters: [tomcat9(credentialsId: '4d9b76aa-078c-462b-81f1-33fe1d9c971c', path: '', url: 'http://192.168.1.125:8080/')], contextPath: null, war: 'target/*.war'
            }
        }
    }
}

(3)配置保存後,點擊 Build Now,等待任務構建完成後,訪問 tomcat,可以看到/websocketChat-1.0-SNAPSHOT虛擬目錄已出現。

使用 Jenkinsfile 腳本發布項目#

(1)在 idea 中的項目目錄下,選擇 New-File,創建 Jenkinsfile 文件,將 Pipeline 腳本內容粘貼進去,隨代碼一起發布到項目倉庫中。

16

17

(2)在任務 Pipeline-demo 的配置界面,選擇構建觸發器 - 流水線,定義內容選擇Pipeline script from SCM-GIt,填寫項目地址和憑證,腳本路徑填寫Jenkinsfile

18

(3)配置保存後,點擊 Build Now,等待任務構建完成後,訪問 tomcat,可以看到/websocketChat-1.0-SNAPSHOT虛擬目錄已出現。

常用構建觸發器#

Jenkins 內置 4 種構建觸發器:

  • 觸發遠程構建

  • 其他工程構建後觸發 (Build after other projects are build)

  • 定時構建 (Build periodically)

    定時字符串從左往右分別為:分 時 日 月 周

    定時表達式的例子:

    每 30 分鐘構建一次:H 代表形參

    H/30 * * * *

    每 2 個小時構建一次:

    H H/2 * * *

    每天的 8 點,12 點,22 點,一天構建 3 次:(多個時間點中間用逗號隔開)

    0 8,12,22 * * *

  • 轮询 SCM (Poll SCM)

轮询 SCM, 是指定时扫描本地代码仓库的代码是否有变更,如果代码有变更就触发项目构建。

(1)觸發遠程構建

在任務 Pipeline-demo 的配置界面,選擇構建觸發器-觸發遠程構建 (例如,使用腳本),自定義身份驗證令牌為test,保存配置。在瀏覽器中訪問:

jenkins 地址 /job/Pipeline-demo/build?token=TOKEN_NAME

http://192.168.1.124:8888/job/Pipeline-demo/build?token=test ,返回查看任務狀態已經開始構建。

(2)其他工程構建後觸發 (Build after other projects are build)

當需要多個任務先後執行時可用。比如若希望執行freestyle_demo任務後,再執行Pipeline-demo,在任務 Pipeline-demo 的配置界面,選擇構建觸發器-Build after other projects are built,中輸入freestyle_demo,選擇只有構建穩定時觸發,保存配置。freestyle_demo 任務構建完成後,freestyle_demo 開始進行構建。

(3)定時構建 (Build periodically)

在任務 Pipeline-demo 的配置界面,選擇構建觸發器-Build periodically,設置*/1 * * * *(一分钟一次),保存配置,freestyle_demo 任務會每分鐘構建一次。

(4)輪詢 SCM (Poll SCM)

輪詢 SCM 也要設置時間周期,不過與定時構建不同的是,如果在時間周期內代碼倉庫未發生變化,任務構建就不會進行。比如:在任務 Pipeline-demo 的配置界面,選擇構建觸發器-Poll SCM,設置*/1 * * * *(一分钟一次),保存配置。如果在之後的一分鐘內代碼變更,Pipeline-demo 任務會進行構建,反之,直到代碼變更後的一分鐘周期內進行構建。

Git hook 構建觸發器(常用)#

當 GitLab 出現代碼變更時,會提交構建請求到 Jenkins,Jenkins 收到請求後,觸發構建。

(1)安裝 GitLab 插件和 GitLab Hook 插件(新版本自帶 GitLab Hook 插件)

(2)在 Jenkins 的任務 Pipeline-demo 的配置界面,選擇構建觸發器-Build when a change is pushed to GitLab. GitLab webhook URL: http://192.168.1.124:8888/project/Pipeline-demo,會出現以下表格中的選項,默認選擇即可。

事件類型觸發條件
Push Events代碼推送到分支或標籤,包括新分支創建。
Push on Branch Delete分支被刪除時。
Opened Merge Request創建新的合併請求時觸發。
New Commits in MR向已存在的 MR 推送新提交時觸發(更新 MR)。
Accepted (Merged) MR合併請求被合併到目標分支(如main)時觸發。
Closed MR合併請求被關閉(未合併)時觸發。

(3)在 Jenkins 中選擇 Manage Jenkins-System-GitLab 中,取消勾選Enable authentication for '/project' end-point,保存設置。

(4)在 GitLab 的管理員賬戶中選擇管理中心 - 設置 - 網絡 - 外發請求中勾選Allow requests to the local network from web hooks and services ,保存配置。

(5)在 GitLab 的項目倉庫中選擇設置 - 集成,輸入 webhook URL,選擇默認配置,保存。在生成的 Webhook 右側,選擇 Test-Push events,顯示Hook executed successfully: HTTP 200,即為成功。

參數化構建#

(1)在源碼中創建分支 v1,並修改 Jenkinsfile 腳本中的分支名稱,提交代碼到 gitlab。

修改前: checkout scmGit (branches: [[name: '*/master']]

修改後:checkout scmGit (branches: [[name: '*/${branch}']]

(2)在 Jenkins 的任務 Pipeline-demo 的配置界面,選擇This project is parameterized-String Parameter,具體設置如下圖。

19

(3)保存設置,在任務 Pipeline-demo 界面選擇Build with Parameters,輸入分支的名稱,點擊 Build,進行構建。

配置郵件伺服器#

(1)安裝 Email Extension TemplateVersion 插件

(2)選擇 Manage Jenkins-Credentials,點擊全局-Add Credentials,創建郵件伺服器的密碼憑證,賬戶為郵箱地址,密碼為獲取的郵箱授權碼。

(3)選擇System,在Jenkins Location``-系統管理員郵件地址出輸入註冊郵箱,在Extended E-mail Notification處,輸入註冊郵箱和端口,點擊高級,選擇密碼憑證,勾選Use SSL,在Default user e-mail suffix中郵箱後綴,Default Content Type選擇HTML (text/html)Default Recipients輸入註冊郵箱,在郵件通知部分輸入 SMTP 伺服器和用戶默認郵件後綴,點擊高級完善信息,勾選通過發送測試郵件測試配置測試郵件伺服器。

(4)構建郵件伺服器模板

在項目根目錄下創建 email.html 模板

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次構建日誌</title>

</head>

<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
      offset="0">
<table width="95%" cellpadding="0" cellspacing="0"
       style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
    <tr>
        <td>(本郵件是程序自動下發的,請勿回覆!)</td>

    </tr>

    <tr>
        <td><h2>
                <font color="#0000FF">構建結果 - ${BUILD_STATUS}</font>

            </h2></td>

    </tr>

    <tr>
        <td><br />
            <b><font color="#0B610B">構建信息</font></b>

            <hr size="2" width="100%" align="center" /></td>

    </tr>

    <tr>
        <td>
            <ul>
                <li>項目名稱&nbsp;&nbsp;${PROJECT_NAME}</li>

                <li>構建編號&nbsp;&nbsp;第${BUILD_NUMBER}次構建</li>

                <li>觸發原因:&nbsp;${CAUSE}</li>

                <li>構建日誌:&nbsp;<a href="${BUILD_URL}console">${BUILD_URL}console</a></li>

                <li>構建&nbsp;&nbsp;Url&nbsp;&nbsp;<a href="${BUILD_URL}">${BUILD_URL}</a></li>

                <li>工作目錄&nbsp;&nbsp;<a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>

                <li>項目&nbsp;&nbsp;Url&nbsp;&nbsp;<a href="${PROJECT_URL}">${PROJECT_URL}</a></li>

            </ul>

        </td>

    </tr>

    <tr>
        <td><b><font color="#0B610B">Changes Since Last
                    Successful Build:</font></b>

            <hr size="2" width="100%" align="center" /></td>

    </tr>

    <tr>
        <td>
            <ul>
                <li>歷史變更記錄 : <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a></li>

            </ul> ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br />%c<br />",showPaths=true,changesFormat="<pre>[%a]<br />%m</pre>",pathFormat="&nbsp;&nbsp;&nbsp;&nbsp;%p"}
        </td>

    </tr>

    <tr>
        <td><b>Failed Test Results</b>

            <hr size="2" width="100%" align="center" /></td>

    </tr>

    <tr>
        <td><pre
                    style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">$FAILED_TESTS</pre>

            <br /></td>

    </tr>

    <tr>
        <td><b><font color="#0B610B">構建日誌 (最後 100行):</font></b>

            <hr size="2" width="100%" align="center" /></td>

    </tr>

    <tr>
        <td><textarea cols="80" rows="30" readonly="readonly"
                      style="font-family: Courier New">${BUILD_LOG, maxLines=100}</textarea>

        </td>

    </tr>

</table>

</body>

</html>

(5)修改 Jenkinsfile 文件,添加與 stages 同級的 post 部分,添加構建後發送郵件

pipeline {
    agent any

    stages {
        stage('拉取代碼') {
            steps {
                checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'fbf87557-40b6-468a-91c5-2cfa1b2e33e8', url: 'http://192.168.1.121:82/test/test_war_demo.git']])
            }
        }
        stage('編譯構建') {
            steps {
                sh 'mvn clean package'
            }
        }
        stage('發布項目') {
            steps {
                deploy adapters: [tomcat9(credentialsId: '4d9b76aa-078c-462b-81f1-33fe1d9c971c', path: '', url: 'http://192.168.1.125:8080/')], contextPath: null, war: 'target/*.war'
            }
        }
    }
    post {
        always {
            emailext(
                subject: '構建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}!',
                body: '${FILE,path="email.html"}',
                to: '郵箱地址1,郵箱地址2'
            )
        }
    }
}

安裝 SonarQube#

Jenkins 集成 SonarQube 進行代碼審查。

SonarQube7.9 開始不再支持 mysql,SonarQube7.8 安裝支持 mysql >=5.6 && <8.0

(1)安裝 SonarQube 前需要安裝 mysql 數據庫

#配置mysql5.7的yum源
vi /etc/yum.repos.d/mysql-community.repo

[mysql-connectors-community]
name=MySQL Connectors Community
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-connectors-community-el7-$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

[mysql-tools-community]
name=MySQL Tools Community
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-tools-community-el7-$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

[mysql-5.7-community]
name=MySQL 5.7 Community Server
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-5.7-community-el7-$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql-2022


#安裝mysql
yum -y install mysql-server
# 查看版本
mysql -V
systemctl start mysqld
systemctl enable mysqld
# 查看MySQL的初始密碼
grep "password" /var/log/mysqld.log
# MySQL的安全性配置
mysql_secure_installation
#按引導配置完後,登錄並創建數據庫
mysql -uroot -p
create database sonar;
#查看數據庫
show databases;

(2)安裝 SonarQube

#配置系統相關參數
echo "vm.max_map_count=524288
fs.file-max=131072" >> /etc/sysctl.conf
sysctl -p

#下載依賴工具
yum install -y unzip
wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-7.8.zip
mkdir -p /opt/sonar
unzip -q sonarqube-7.8.zip -d /opt/sonar
#創建用戶
useradd sonar
passwd sonar
#修改sonarqube文件權限
chown -R sonar:sonar /opt/sonar/sonarqube-7.8

(3)修改conf目錄下的sonar.properties配置文件

sonar.jdbc.username=root
sonar.jdbc.password=數據庫密碼
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false

(4)修改conf目錄下wrapper.conf的 jdk-1.8 的路徑

wrapper.java.command=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.412.b08-1.el7_9.x86_64/bin/java

(5)進入bin/linux-x86-64/目錄,使用 sonar 用戶啟動 sonarqube

su sonar
./sonar.sh start
#查看啟動日誌
tail ../../logs/sonar.log

使用默認賬戶登錄,賬號密碼都是 admin

(6)登錄 sonarqube 後,選擇 Administration - Security- Global Permissions,為 admin 勾選 Administer SystemAdministerExecute AnalysisCreate 權限。單擊右上角頭像下拉框,選擇 My Account - Security,隨意填寫 token 名稱,完成 Token 的創建。

配置 Jenkins 與 sonarqube 集成#

(1)在 Jenkins 上安裝SonarQube Scanner插件,安裝完成後,選擇Manage Jenkins -Tools-SonarQube Scanner 安裝,點擊新增SonarQube Scanner ,輸入名稱,版本選擇SonarQube Scanner 4.2.0.1873,點擊保存。

SonarQube 7.8 對應 Sonar-Scanner 4.2

SonarQube 8.9 LTS 對應 Sonar-Scanner 4.6

(2)在 Jenkins 中配置 SonarQube 的 token 憑證。選擇類型為Secret text,輸入 token,點擊創建。

(3)在 Jenkins 中選擇 System-SonarQube installations,點擊Add SonarQube,輸入 SonarQube 的地址、選擇創建的 token 憑證,保存集成 SonarQube。

非流水線任務添加 SonarQube 代碼審查#

在 freestyle_demo 任務中選擇配置 - Build Steps,點擊增加構建步驟,選擇Execute SonarQube Scanner,選擇 JDK,輸入分析內容,保存配置後,點擊 Build Now,等待任務構建完成。在 SonarQube 裡查看代碼分析結果。

sonar.projectKey=websocketChat
sonar.projectName=websocketChat
sonar.projectVersion=1.0
sonar.sources=.
sonar.java.binaries=./target/classes
sonar.exclusions=**/test/**,**/target/**
sonar.java.source=1.8
sonar.java.target=1.8
sonar.sourceEncoding=UTF-8

20

21

流水線任務添加 SonarQube 代碼審查#

(1)在項目根目錄下,創建 sonar-project.properties,寫入以下內容。

sonar.projectKey=Pipeline-demo
sonar.projectName=Pipeline-demo
sonar.projectVersion=1.0
sonar.sources=.
sonar.java.binaries=./target/classes
sonar.exclusions=**/test/**,**/target/**
sonar.java.source=1.8
sonar.java.target=1.8
sonar.sourceEncoding=UTF-8

(2)在 Jenkinsfile 的 stages 前,引入在 Jenkins 中安裝的 SonarQube Scanner 作為預置環境變量,之後在拉取代碼步驟後,添加審查代碼的步驟。

pipeline {
    agent any
     environment {
         //引入在Jenkins中安裝的SonarQube Scanner
        scannerHome = tool 'sonar-scanner-jenkins'
            }
    stages {
        stage('拉取代碼') {
            steps {
                checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'fbf87557-40b6-468a-91c5-2cfa1b2e33e8', url: 'http://192.168.1.121:82/test/test_war_demo.git']])
            }
        }
        stage('審查代碼') {
            steps { 
                    //引入在Jenkins中配置的SonarQube伺服器設置
                withSonarQubeEnv('SonarQube-jenkins') {
                    sh '${scannerHome}/bin/sonar-scanner'
                    }
            }
        }
        stage('編譯構建') {
            steps {
                sh 'mvn clean package'
            }
        }
        stage('發布項目') {
            steps {
                deploy adapters: [tomcat9(credentialsId: '4d9b76aa-078c-462b-81f1-33fe1d9c971c', path: '', url: 'http://192.168.1.125:8080/')], contextPath: null, war: 'target/*.war'
            }
        }
    }
    post {
        always {
            emailext(
                subject: '構建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}!',
                body: '${FILE,path="email.html"}',
                to: '郵箱地址'
            )
        }
    }
}

(3)代碼完成變更後,在流水線任務執行完成,在 SonarQube 裡查看代碼分析結果。

22

應用案例#

該應用案例參考來源於 b 站 up 主,'' 涣沷 a 靑惷 '',原文鏈接為: https://www.yuque.com/huanfqc/jenkins/jenkins。

使用 Jenkins+GitLab+Docker+SonarQube,在 192.168.1.125 上部署若依的 springboot 前後端分離項目。

環境準備#

設置 Jenkins 伺服器免密登錄 192.168.1.125

ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]

安裝 docker#

bash <(curl -sSL https://linuxmirrors.cn/docker.sh)
#修改鏡像源和默認配置文件路徑
vi /etc/docker/daemon.json
{
  "data-root": "/data/dockerData",
  "registry-mirrors": [
        "https://docker.1ms.run",
        "https://docker.xuanyuan.me"
    ]
}
#啟動docker
systemctl start docker
systemctl enable docker

獲取並修改源碼配置#

(1)拉取若依項目源碼到本地,並將 ruoyi-ui 目錄與 RuoYi-Vue 項目放置在同一級

git clone https://gitee.com/y_project/RuoYi-Vue.git

23

(2)修改ruoyi-ui目錄中的vue.config.js文件,將localhost修改為部署主機的 ip,即 192.168.1.125。

#修改前
const baseUrl = 'http://localhost:8080' // 後端接口
#修改後
const baseUrl = 'http://192.168.1.125:8080' // 後端接口

(3)修改RuoYi-Vue\ruoyi-admin\src\main\resources\application.yml文件,將 redis 配置的 ip 改為 192.168.1.125。

  # redis 配置
  redis:
    # 地址
    host: 192.168.1.125

(4)修改RuoYi-Vue\ruoyi-admin\src\main\resources\application-druid.yml文件,將 mysql 的鏈接地址改為 192.168.1.125。

 # 主庫數據源
            master:
                url: jdbc:mysql://192.168.1.125:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
              

(5)在 ruoyi-ui 目錄下,創建 sonar-project.properties,寫入以下內容,添加 SonarQube 代碼審查

sonar.projectKey=ruoyi-ui
sonar.projectName=ruoyi-ui
sonar.projectVersion=1.0
sonar.sources=.
sonar.sourceEncoding=UTF-8

(6)在 ruoyi-ui 目錄下創建前端項目的 Jenkinsfile 文件

pipeline {
    agent any
     environment {
         //引入在Jenkins中安裝的SonarQube Scanner
        scannerHome = tool 'sonar-scanner-jenkins'
            }
    stages {
        stage('拉取代碼') {
            steps {
                checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'fbf87557-40b6-468a-91c5-2cfa1b2e33e8', url: 'http://192.168.1.121:82/test/ruoyi-ui.git']])
            }
        }
        stage('審查代碼') {
            steps { 
                    //引入在Jenkins中配置的SonarQube伺服器設置
                withSonarQubeEnv('SonarQube-jenkins') {
                    sh '${scannerHome}/bin/sonar-scanner'
                    }
            }
        }
               stage('打包,部署網站') {
		  steps {
		    script {
			    nodejs(nodeJSInstallationName: 'nodejs14') {
                              sh '''
                npm install
                # 構建生產環境
                npm run build:prod
            '''
               }
			    // 將構建產物部署到 Nginx 容器掛載的目錄
          sh '''
            
            # 將整個 dist 目錄複製到掛載目錄
            scp -r dist 192.168.1.125:/data/ruoyi/nginx/html/
            ssh 192.168.1.125 docker restart nginx
        '''
			   
			}
		  }
       
        }

    }
}

7)在 RuoYi-Vue 目錄下,創建 sonar-project.properties,寫入以下內容,添加 SonarQube 代碼審查

sonar.projectKey=ruoyi-api
sonar.projectName=ruoyi-api
sonar.projectVersion=1.0
sonar.sources=.
sonar.java.binaries=./ruoyi-admin/target/classes
sonar.exclusions=**/test/**,**/target/**
sonar.java.source=1.8
sonar.java.target=1.8
sonar.sourceEncoding=UTF-8

(8)在 RuoYi-Vue 目錄下創建後端項目的 Jenkinsfile 文件

pipeline {
    agent any
    environment {
         //引入在Jenkins中安裝的SonarQube Scanner
        scannerHome = tool 'sonar-scanner-jenkins'
            }
    stages {
        stage('拉取代碼') {
            steps {
                checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'fbf87557-40b6-468a-91c5-2cfa1b2e33e8', url: 'http://192.168.1.121:82/test/ruoyi-api.git']])
            }
        }
        stage('編譯構建') {
            steps {
                sh 'mvn clean package'
            }
        }
        stage('審查代碼') {
            steps { 
                    //引入在Jenkins中配置的SonarQube伺服器設置
                withSonarQubeEnv('SonarQube-jenkins') {
                    sh '${scannerHome}/bin/sonar-scanner'
                    }
            }
        }
        stage('發布項目') {
            steps {
                script {
                    sh '''
                       ssh 192.168.1.125  "mkdir -p /data/ruoyi-api"
                        scp ruoyi-admin/target/*.jar  192.168.1.125:/data/ruoyi-api/ruoyi.jar
                    '''
                    // 創建Dockerfile
                    sh '''
                             ssh 192.168.1.125 'cat > /data/ruoyi-api/Dockerfile <<-EOF
	FROM openjdk:8
	MAINTAINER xie
	VOLUME /tmp
	ADD ruoyi.jar ruoyi.jar
	ENTRYPOINT ["java","-jar","/ruoyi.jar"]
	EXPOSE 8080
	EOF'
                    '''

                    // 構建鏡像
                    sh '''
                        ssh 192.168.1.125 "docker build -t ruoyi:1.0 /data/ruoyi-api"
                    '''

                    // 停止並刪除現有的容器
                    sh '''
                        EXISTING_CONTAINER=$(ssh 192.168.1.125 "docker ps -a -q -f name=ruoyi")
                        if [ -n "$EXISTING_CONTAINER" ]; then
                            echo "容器 'ruoyi' 已存在,停止並刪除舊容器..."
                           ssh 192.168.1.125 "docker rm -f $EXISTING_CONTAINER"
                        fi
                    '''

                    // 運行新的容器
                    sh '''
                       ssh 192.168.1.125 "docker run -d --name ruoyi -p 8080:8080 ruoyi:1.0"
                    '''
                }
            }
        }
    }
}

部署項目所需容器#

該項目中要用到 nginx、mysql 和 redis,需提前部署好容器。對應容器版本為 nginx:1.18.0、mysql:8.0.19、redis:6.0.8

(1)創建所需目錄

mkdir -p /data/ruoyi
mkdir -p /data/ruoyi/nginx/conf
mkdir -p /data/ruoyi/mysql/db

(2)創建 nginx 臨時容器,修改配置文件

docker run --rm -v /data/ruoyi/nginx/conf:/backup nginx:1.18.0 \
  sh -c "cp -r /etc/nginx/. /backup"

修改/data/ruoyi/nginx/conf/conf.d中的 default.conf 文件

server {
    listen 80;

    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header REMOTE-HOST $remote_addr;

    server_name localhost;

    location / {
        root /usr/share/nginx/html/dist;
        index index.html index.htm;
        try_files $uri /index.html;
    }

    location /prod-api/ {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://192.168.1.125:8080/;   #注意修改ip
    }

    if ($request_uri ~ "/actuator") {
        return 403;
    }
}

(3)將RuoYi-Vue\sql中的 sql 文件,拷貝到 192.168.1.125 主機的/data/ruoyi/mysql/db目錄

(4)撰寫 yml,使用 docker compose 編排部署容器

#撰寫yml文件
vi ruoyi.yml


services:
  nginx:
    image: nginx:1.18.0
    container_name: nginx
    restart: always
    volumes:
      - /data/ruoyi/nginx/conf:/etc/nginx
      - /data/ruoyi/nginx/logs:/var/log/nginx
      - /data/ruoyi/nginx/html:/usr/share/nginx/html
    environment:
      TZ: "Asia/Shanghai"
    ports:
      - "80:80"
    networks:
      ruoyi:
        ipv4_address: 172.20.112.11
  mysql:
    container_name: mysql
    image: mysql:8.0.19
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "password"
      MYSQL_ALLOW_EMPTY_PASSWORD: "no"
      MYSQL_DATABASE: "ry-vue"
      TZ: "Asia/Shanghai"
    ports:
      - "3306:3306"
    volumes:
      - /data/ruoyi/mysql/db:/var/lib/mysql
      - /data/ruoyi/mysql/conf:/etc/my.cnf
      - /data/ruoyi/mysql/init:/docker-entrypoint-initdb.d
    command: --default-authentication-plugin=mysql_native_password
    networks:
      ruoyi:
        ipv4_address: 172.20.112.12
  redis:
    container_name: redis
    image: redis:6.0.8
    restart: always
    environment:
      TZ: "Asia/Shanghai"
    ports:
      - "6379:6379"
    volumes:
      - /data/ruoyi/redis/conf:/etc/redis/redis.conf
      - /data/ruoyi/redis/data:/data
    command: redis-server /etc/redis/redis.conf
    networks:
      ruoyi:
        ipv4_address: 172.20.112.13


networks:
 ruoyi:
  driver: bridge
  ipam:
   config:
    - subnet: 172.20.112.0/24

(5)執行命令創建容器

docker compose -f ruoyi.yml up -d
#查看容器運行狀態
docker ps
#導入數據庫
docker exec -it mysql bash
mysql -u root -ppassword ry-vue < /var/lib/mysql/ry_20250417.sql
mysql -u root -ppassword ry-vue < /var/lib/mysql/quartz.sql

上傳代碼到 GitLab#

(1)創建 ruoyi-ui 和 ruoyi-api 兩個倉庫分別存放前端和後端代碼

(2)在 ruoyi-ui 目錄下,打開 cmd,輸入命令上傳代碼

git init
git remote add origin http://192.168.1.121:82/test/ruoyi-ui.git
#添加該目錄下的git權限配置
git config  user.name "test1"
git config  user.email "test1@gitlab"
#繼續上傳
git add .
git commit -m "ruoyi-ui"
git push -u origin master

(3)在RuoYi-Vue目錄下,打開 cmd,輸入命令上傳代碼

git init
git remote add origin http://192.168.1.121:82/test/ruoyi-api.git
#添加該目錄下的git權限配置
git config  user.name "test1"
git config  user.email "test1@gitlab"
#繼續上傳
git add .
git commit -m "ruoyi-api"
git push -u origin master

配置 Jenkins 流水線#

(1)安裝 nodejs 和 NodeJS 插件

在 jenkins 伺服器上安裝 nodejs

wget https://nodejs.org/dist/latest-fermium/node-v14.21.3-linux-x64.tar.gz
tar -vxzf node-v14.21.3-linux-x64.tar.gz  -C /opt
mv /opt/node-v14.21.3-linux-x64 /opt/nodejs
#配置環境變量
echo "
export NODE_HOME=/opt/nodejs
export PATH=$NODE_HOME/bin:$PATH" >> /etc/profile
#變量生效
 source /etc/profile
#查看版版本
node -v
npm -v
#配置鏡像源
npm config set registry https://registry.npmmirror.com
npm config set sass_binary_site=https://npm.taobao.org/mirrors/node-sass

(2)配置 NodeJS 設置

Manage Jenkins -Tools-NodeJS 安裝中,點擊新增NodeJS,填寫 nodejs 的名稱為nodejs14, 輸入在伺服器安裝的 nodejs 路徑/opt/nodejs,保存應用。

(3)創建ruoyi-ui流水線任務,在流水線 - 定義中選擇Pipeline script from SCM,SCM 選擇Git,填寫 ruoyi-ui 的 git 倉庫地址和登錄憑證,其他選項保持默認,保存應用。

(4)點擊Build Now,等待任務執行完成。在瀏覽器中訪問http://192.168.1.125/,查看前端部署情況。

24

(5)創建ruoyi-api流水線任務,在流水線 - 定義中選擇Pipeline script from SCM,SCM 選擇Git,填寫 ruoyi-api 的 git 倉庫地址和登錄憑證,其他選項保持默認,保存應用。

(6)點擊Build Now,等待任務執行完成。在瀏覽器中訪問http://192.168.1.125/,可正常登錄,即為成功。

25

(7)訪問 sonarQube,分別查看前後端代碼的具體質量審查情況。

26

本篇知識來源於 B 站視頻 BV1pF411Y7tq

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。