Jenkins+GitLab+SonnarQube搭建CI/CD全流程

1. CI/CD

1.1 CI – 持續集成

持續集成( Continuous integration , 簡稱 CI )指的是,頻繁地(一天多次)將程式碼集成到主幹。持續集成的目的就是讓產品可以快速迭代,同時還能保持高品質。它的核心措施是程式碼集成到主幹之前,必須通過自動化測試。只要有一個測試用例失敗,就不能集成。通過持續集成團隊可以快速的從一個功能到另一個功能,簡而言之,敏捷軟體開發很大一部分都要歸功於持續集成。

image-20210110001719420

持續集成的組成要素

  • 一個自動構建過程, 從檢出程式碼、 編譯構建、 運行測試、 結果記錄、 測試統計等都是自動完成的, 無需人工干預。

  • 一個程式碼存儲庫,即需要版本控制軟體來保障程式碼的可維護性,同時作為構建過程的素材庫,一般使用SVN或Git。

  • 一個持續集成伺服器, Jenkins 就是一個配置簡單和使用方便的持續集成伺服器。

1.2 CD – 持續部署

持續部署則是在持續集成的基礎上,把部署到生產環境的過程自動化。

image-20210110002137822

2. 整體架構說明

單體項目 / 前後端分離項目 解決方案(已實現)

image-20210110013036681

微服務項目 解決方案

image-20210110012819398

3. GitLab程式碼管理私服

3.1 理解

GitLab和GitHub一樣屬於第三方基於Git開發的作品,免費且開源(基於MIT協議),與Github類似,可以註冊用戶,任意提交你的程式碼,添加SSHKey等等。不同的是GitLab是可以部署到自己的伺服器上,資料庫等一切資訊都掌握在自己手上,適合團隊內部協作開發,你總不可能把團隊內部的智慧總放在別人的伺服器上吧?簡單來說可把GitLab看作個人版的GitHub。

3.2 安裝(CentOS7)

這裡我使用的是Docker-compose安裝,基於twang2218/gitlab-ce-zh漢化版鏡像

version: '2'
services:
    gitlab:
      image: 'twang2218/gitlab-ce-zh'
      restart: unless-stopped
      hostname: '192.168.0.200'
      environment:
        TZ: 'Asia/Shanghai'
        GITLAB_OMNIBUS_CONFIG: |
          external_url '//192.168.0.200'
          gitlab_rails['time_zone'] = 'Asia/Shanghai'
          gitlab_rails['gitlab_shell_ssh_port'] = 2222
      ports:
        - '8089:80'
        - '8443:443'
        - '2222:22'
      volumes:
        - ./config:/etc/gitlab
        - ./data:/var/opt/gitlab
        - ./logs:/var/log/gitlab
volumes:
    config:
    data:
    logs:
3.3 相關配置
# 安裝相關依賴
yum -y install policycoreutils openssh-server openssh-clients postfix
# 啟動ssh服務&設置為開機啟動
systemctl enable sshd && sudo systemctl start sshd
# 設置postfix開機自啟,並啟動,postfix支援gitlab發信功能
systemctl enable postfix && systemctl start postfix
# 開放ssh以及http服務,然後重新載入防火牆列表
firewall-cmd --add-service=ssh --permanent
firewall-cmd --add-service=http --permanent
firewall-cmd --reload
# 可以修改gitlab配置,配置文件已被掛載到Linux宿主機
vim /root/docker/gitlab/config/gitlab.rb
3.4 頁面配置
  1. 管理員帳號

image-20210110015514060

  1. 添加組

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

image-20210110015921647

  1. 創建用戶

image-20210110020138137

  1. 將用戶添加到組中

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

Guest:可以創建issue、發表評論,不能讀寫版本庫

Reporter:可以克隆程式碼,不能提交,QA、PM可以賦予這個許可權

Developer:可以克隆程式碼、開發、提交、push,普通開發可以賦予這個許可權

Maintainer:可以創建項目、添加tag、保護分支、添加項目成員、編輯項目,核心開發可以賦予這個許可權

Owner:可以設置項目訪問許可權 – Visibility Level、刪除項目、遷移項目、管理組成員,開發組組長可以賦予這個許可權

image-20210110020435952
image-20210110020643983

  1. 組中創建項目

  2. 源碼上傳到Gitlab倉庫(這裡我們通過SSH的方式)

  • 登錄GitLab私服地址:192.168.0.200:8089

  • 配置SSH免密登錄,以SSH方式push,pull程式碼

    • 下載安裝Git客戶端
    • 打開Git Bash
    # 配置Git使用者用戶名
    git config--global user.name 「xxxx」
    # 配置GIt 使用者郵箱
    git config --global user.email 「xxxx」
    # 查看是否存在ssh keys
    cd  ~/.ssh 
    # 若出現」No such file or directory」,則表示需要創建一個ssh keys
    ssh-keygen -t rsa -C "你的郵箱"  #郵箱寫GitLab賬戶設置的郵箱
    
    • 然後打開~/.ssh/id_rsa.pub文件(~表示用戶目錄,比如我的windows就是C:\Users\Administrator),複製其中的內容
    • 打開gitlab,搜索SSH Key,並把上一步中複製的內容粘貼到Key所對應的文本框,在Title對應的文本框中給這個sshkey設置一個名字,點擊Add key按鈕

    image-20210110022438786

    • 嘗試拉取程式碼和提交程式碼,此時已不需要輸入密碼了
git clone ssh://[email protected]:2222/DianJianQiJu/jp-console.git

4. Jenkins環境搭建

4.1 安裝環境(CentOS7)
名稱 安裝包 版本號
Jenkins jenkins-2.190.3-1.1.noarch.rpm 2.190.3
JDK 1.8
Maven 3.6.2
4.2 Jenkins安裝與配置
# 把安裝包上傳到伺服器,進行安裝
rpm -ivh jenkins-2.190.3-1.1.noarch.rpm
# 修改Jenkins配置
vim /etc/syscofig/jenkins
JENKINS_USER="root"
JENKINS_PORT="CenterSoft123"
# 啟動Jenkins
systemctl start jenkins
4.3 頁面配置
  1. 第一次進入需要輸入admin賬戶密碼
cat /var/lib/jenkins/secrets/initialAdminPassword
  1. 選擇插件來安裝 => 選擇無 => 安裝。 以此來跳過插件安裝,因為Jenkins插件需要連接默認官網下載,速度非常慢而且經過會失敗,所以我們暫時先跳過插件安裝

  2. 添加一個管理員賬戶,並進入Jenkins後台

# Username
root
# Password
xxx
# Full name
root
  1. JenKins URL默認即可
4.4 Jenkins插件下載加速
  1. Jenkins本身沒有提供多少功能,我們可以通過使用插件來滿足我們的使用。例如從Gitlab拉取程式碼,使用Maven構建項目等功能需要依靠插件完成。接下來演示如何下載插件。
  2. 修改Jenkins插件下載地址,Jenkins國外官方插件地址下載速度非常慢,所以可以修改為中國插件地址。

enkins->Manage Jenkins->Manage Plugins,點擊可選插件待其載入完成。這樣做是為了把Jenkins官方的插件列表下載到本地,接著修改地址文件替換為中國插件地址。

image-20210110024604394

cd /var/lib/jenkins/updates

sed -i 's#http:\/\/updates.jekins-ci.org\/download#https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins#g' default.json

sed -i '#/http:\/\/www.google.com#https:\/\/www.baidu.com#g' default.json

最後,Manage Plugins點擊Advanced,把Update Site改為中國插件下載地址

//mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

Submit後,在瀏覽器輸入: //192.168.66.101:8888/restart ,重啟Jenkins。

4.5 Jenkins用戶許可權管理

我們可以利用Role-based Authorization Strategy 插件來管理Jenkins用戶許可權

  1. Role-based Authorization Strategy插件

image-20210110025645710

  1. 開啟許可權全局安全配置

Manage Jenkins -> Configure Global Security

image-20210110025905790

  1. 創建角色

Manage Jenkins -> Manage and Assign Roles -> Manage Roles

Global roles(全局角色):管理員等高級用戶可以創建基於全局的角色

Project roles(項目角色):針對某個或者某些項目的角色

Node roles(節點角色):節點相關的許可權

image-20210110030254595

  1. 我們添加以下三個角色
  • baseRole:該角色為全局角色。這個角色需要綁定Overall下面的Read許可權,是為了給所有用戶綁定最基本的Jenkins訪問許可權。注意:如果不給後續用戶綁定這個角色會報錯誤:”用戶名 ismissing the Overall/Read permission”

image-20210110030632431

  • role1:該角色為項目角色。使用正則表達式綁定”jp.*”,意思是只能操作jp開頭的項目。

  • role2:該角色也為項目角色。綁定”web.*”,意思是只能操作web開頭的項目。

image-20210110030818917

  1. 創建用戶

Manage Jenkins -> Manage Users -> 新建兩個用戶如xixi / haha

  1. 給用戶分配角色

Manage Jenkins -> Manage and Assign Roles -> Assign Roles

綁定規則如下:

xixi用戶綁定baseRole和role1角色,haha綁定baseRole和role2角色

創建項目測試許可權!

4.6 Jenkins憑證管理
  1. 憑據可以用來存儲需要密文保護的資料庫密碼、Gitlab密碼資訊、Docker私有倉庫密碼等,以便Jenkins可以和這些第三方的應用進行交互。
  2. 安裝Credentials Binding插件,要在Jenkins使用憑證管理功能,安裝後Manage Jenkins出現如下菜單

image-20210110031507425

  1. 五種憑據類型
# Username with password:用戶名和密碼

# SSH Username with private key: 使用SSH用戶和密鑰

# Secret file:需要保密的文本文件,使用時Jenkins會將文件複製到一個臨時目錄中,再將文件路徑設置到一個變數中,等構建結束後,所複製的Secret file就會被刪除。

# Secret text:需要保存的一個加密的文本串,如釘釘機器人或Github的api token

# Certificate:通過上傳證書文件的方式
  1. Jenkins管理Gitlab憑證 – 用戶密碼類型
  • 安裝Git插件。為了讓Jenkins支援從Gitlab拉取源碼,需要安裝Git插件

image-20210110031908618

  • 安裝Git工具,為了讓Jenkins支援從Gitlab拉取源碼,需要在CentOS7上安裝Git工具
# 安裝
yum install git -y 
# 安裝後查看版本
git --version 
  • 創建用戶密碼類型憑證

Manage Jenkins -> Manage Credentials -> 添加憑據

image-20210110032453963

  • 測試憑證是否可用

創建一個自由風格的項目,找到”源碼管理”->”Git”,在Repository URL複製Gitlab中的項目URL。

image-20210110032659717
image-20210110032908956
image-20210110032927972

查看/var/lib/jenkins/workspace/目錄,發現已經從Gitlab成功拉取了程式碼到Jenkins中。

  1. Jenkins管理Gitlab憑證 – SSH類型
# 在Jenkins所在CentOS系統使用root用戶生成公鑰與私鑰
ssh-keygen -t rsa
# 在/root/.ssh/目錄保存了公鑰和私鑰
  • 把生成的公鑰放在Gitlab中。

以root賬戶登錄->點擊頭像->Settings->SSH Keys。複製剛才id_rsa.pub文件的內容到這裡,點擊”Add Key”

  • 在Jenkins中添加憑證,配置私鑰

在Jenkins添加一個新的憑證,類型為”SSH Username with private key”,把剛才生成私有文件內容複製過來

image-20210110033708635

4.7 Maven安裝和配置

在Jenkins集成伺服器上,我們需要安裝Maven來編譯和打包項目。

  1. 安裝Maven

  2. 配置環境變數

vim /etc/profile

export MAVEN_HOME=/home/apache-maven-3.5.4
export PATH=${PATH}:${MAVEN_HOME}/bin

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
export JRE_HOME=$JAVA_HOME/jre
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin

# 使環境變數生效
source /etc/profile

#查看Maven版本
mvn -v 
  1. 全局工具配置關聯JDK和Maven

Jenkins -> Global Tool Confifiguration -> JDK->新增JDK

image-20210110034220985

Jenkins->Global Tool Confifiguration->Maven->新增Maven

image-20210110034329697

  1. 添加Jenkins全局變數

Manage Jenkins->Confifigure System->Global Properties ,添加三個全局變數

image-20210110034512889

  1. 修改Maven的settings.xml
# 創建本地倉庫目錄
mkdir /root/repo 
# 修改本地倉庫路徑
vim /opt/maven/conf/settings.xml

/root/maven_repository

# 添加阿里雲私服地址
alimaven aliyun maven //maven.aliyun.com/nexus/content/groups/public/ central
  1. 測試Maven是否配置成功
  • 使用之前的測試項目,修改配置

image-20210110034912951

  • 構建 -> 增加構建步驟 -> Execute Shell

image-20210110035056063

  • 再次構建,如果可以把項目打成war包,代表maven環境配置成功!

image-20210110035209898

4.8 Tomcat安裝與配置

這裡使用的是window伺服器。配置與Linux伺服器並無差異

  1. 安裝Tomcat8.5
  2. 配置Tomcat用戶角色許可權

默認情況下Tomcat是沒有配置用戶角色許可權的。但是,後續Jenkins部署項目到Tomcat伺服器,需要用到Tomcat的用戶,所以修改tomcat以下配置,添加用戶及許可權。

image-20210110035636656

<!-- 進入 tomcat的conf/tomcat-users.xml添加如下配置 -->
<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,還需要修改以下配置 -->
<!-- 進入 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" /> 
-->
  1. 重啟Tomcat,訪問測試

image-20210110040411004

  1. Tomcat調優,調整Jvm記憶體大小(解決後端項目無端部署失敗的bug)

由於公司項目體積較大,我多次使用Jenkins自動部署項目都失敗了,但是程式碼並無明顯錯誤。後來發現是tomcat的jvm設置太小容易記憶體溢出,可以適當調整jvm記憶體大下,重啟下即可。

  • 使用剛才創建的角色進入manager應用,點擊Server Status查看JVM狀態

  • 修改JVM記憶體大小

修改方式:打開Tomcat的bin/catalina.bat文件進行修改

注意:記憶體不宜設置太大,根據伺服器記憶體大小適當配置

增大堆記憶體

增大非堆記憶體

5. Jenkins各種類型項目構建

5.1 自動構建項目類型

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

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

每種類型的構建其實都可以完成一樣的構建過程與結果,只是在操作方式、靈活度等方面有所區別,在實際開發中可以根據自己的需求和習慣來選擇。(PS:個人推薦使用流水線類型,因為靈活度非常高)

5.2 自由風格項目搭建

演示集成過程:拉取程式碼 -> 編譯 -> 打包 -> 部署

  1. 創建自由風格項目web_test2
  2. 配置源碼管理,從GitLab拉取程式碼

image-20210110094018780

  1. 編譯打包

image-20210110091925493

  1. 部署

把項目部署到遠程的Tomcat裡面

  • 安裝 Deploy to container插件。Jenkins本身無法實現遠程部署到Tomcat的功能,需要安裝Deploy to container插件實現

image-20210110092550846

  • 添加Tomcat用戶憑證

image-20210110092757022

  • 添加構建後操作

image-20210110092427472

  • 點擊Build Now,開始構建過程

image-20210110094128822
image-20210110094204122

  • 之後改動程式碼再push到GitLab,在Jenkins中對項目進行重新構建部署即可
5.3 Maven項目搭建
  1. 安裝Maven Integration插件

image-20210110094441917

  1. 創建Maven項目web_test2_maven

image-20210110094838925

  1. 配置項目

拉取程式碼和遠程部署的過程和自由風格項目一樣,只是”構建”部分不同

image-20210110095048285

5.4 流水線項目搭建
  1. Pipeline簡介

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

使用Pipeline有以下好處:

  • 程式碼:Pipeline以程式碼的形式實現,通常被檢入源程式碼控制,使團隊能夠編輯,審查和迭代其傳送流程。

  • 持久:無論是計劃內的還是計劃外的伺服器重啟,Pipeline都是可恢復的。

  • 可停止:Pipeline可接收互動式輸入,以確定是否繼續執行Pipeline。

  • 多功能:Pipeline支援現實世界中複雜的持續交付要求。它支援fork/join、循環執行,並行執行任務的功能。

  • 可擴展:Pipeline插件支援其DSL的自定義擴展 ,以及與其他插件集成的多個選項。

如何創建 Jenkins Pipeline?

  • Pipeline 腳本是由 Groovy 語言實現的,但是我們沒必要單獨去學習 Groovy

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

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

  1. 安裝Pipeline插件

image-20210110095437371

  1. 安裝插件後,創建項目的時候多了「流水線」類型

image-20210110095651694

  1. Pipeline語法快速入門
  • Declarative聲明式-Pipeline

流水線->選擇HelloWorld模板

image-20210110100122204

生成內容如下

stages:代表整個流水線的所有執行階段。通常stages只有1個,裡面包含多個stage

stage:代表流水線中的某個階段,可能出現n個。一般分為拉取程式碼,編譯構建,部署等階段。

steps:代表一個階段內需要執行的邏輯。steps裡面是shell腳本,git拉取程式碼,ssh遠程發布等任意內容。

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

編寫一個簡單聲明式的Pipeline

pipeline { 
	agent any 
	stages { 
	
		stage('拉取程式碼') { 
			steps { 
				echo '拉取程式碼' 
			} 
		}
		
		stage('編譯構建') { 
			steps { 
				echo '編譯構建'
			} 
		}
		
		stage('項目部署') { 
			steps { 
				echo '項目部署' 
			} 
		} 
	} 
}

點擊構建,可以看到整個構建過程

image-20210110100631651

  • Scripted Pipeline腳本式-Pipeline

流水線->選擇Scripted Pipeline

image-20210110100855260

生成內容如下

Node:節點,一個 Node 就是一個 Jenkins 節點,Master 或者 Agent,是執行 Step 的具體運行環境,後續講到Jenkins的Master-Slave架構的時候用到。

Stage:階段,一個 Pipeline 可以劃分為若干個 Stage,每個 Stage 代表一組操作,比如:Build、Test、Deploy,Stage 是一個邏輯分組的概念。

Step:步驟,Step 是最基本的操作單元,可以是列印一句話,也可以是構建一個 Docker 鏡像,由各類 Jenkins 插件提供,比如命令:sh 『make』,就相當於我們平時 shell 終端中執行 make 命令

一樣

node {
    def mvnHome
    stage('Preparation') { 
        
    }
    stage('Build') {
        
    }
    stage('Results') {
        
    }
}
  • 我們可以通過左下側流水線語法快速生成pipeline程式碼

以拉取程式碼為例,選擇片段生成器模板

image-20210110101327060
image-20210110101550186

pipeline {
    agent any

    stages {
        stage('拉取程式碼') {
            steps {
                checkout([$class: 'GitSCM', branches: [[name: '*/master']], 
                doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [],
                userRemoteConfigs: [[credentialsId: '0c93f73d-1e42-4d39-a8ab-f07d5dda668f',
                url: 'ssh://[email protected]:2222/DianJianQiJu/web_test2.git']]])
            }
        }
        stage('編譯打包') {
            steps {
                sh label: '', script: 'mvn clean package'
            }
        }
        stage('項目部署') {
            steps {
                deploy adapters: [tomcat8(credentialsId: '22b62c37-4009-4ac3-b82b-fbf926a0cc63', path: '',
                url: '//8.136.103.128:8085')], contextPath: null, war: 'target/*.war'
            }
        }
    }
}
  • Pipeline Script from SCM

剛才我們都是直接在Jenkins的UI介面編寫Pipeline程式碼,這樣不方便腳本維護,建議把Pipeline腳本放在項目中(一起進行版本控制),在項目根目錄建立Jenkinsfifile文件,把腳本內容複製到該文件中即可

image-20210110102351961

6. Jenkins構建觸發器

6.1 Jenkins內置4種構建觸發器
  • 觸發遠程構建

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

  • 定時構建(Build periodically)

  • 輪詢SCM(Poll SCM)

6.2 觸發遠程構建演示

觸發構建url://192.168.0.200:8888/job/web_test2/build?token=123456

image-20210110103123388

6.3 其他工程構建後觸發

image-20210110103406753

6.4 定時構建
  • 定時字元串從左往右分別為: 分 時 日 月 周
  • 一些定時表達式的例子:

每30分鐘構建一次:H代表形參 H/30 * * * * 10:02 10:32

每2個小時構建一次: H H/2 * * *

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

每天中午12點定時構建一次 H 12 * * *

每天下午18點定時構建一次 H 18 * * *

在每個小時的前半個小時內的每10分鐘 H(0-29)/10 * * * *

每兩小時一次,每個工作日上午9點到下午5點(也許是上午10:38,下午12:38,下午2:38,下午4:38) H H(9-16)/2 * * 1-5

image-20210110103535689

6.5 輪詢SCM

輪詢SCM,是指定時掃描本地程式碼倉庫的程式碼是否有變更,如果程式碼有變更就觸發項目構建。

注意:這次構建觸發器,Jenkins會定時掃描本地整個項目的程式碼,增大系統的開銷,不建議使用。

image-20210110104737747

6.6 Git hook自動觸發構建插件
  1. 剛才我們看到在Jenkins的內置構建觸發器中,輪詢SCM可以實現Gitlab程式碼更新,項目自動構建,但是該方案的性能不佳。那有沒有更好的方案呢? 有的。就是利用Gitlab的webhook實現程式碼push到倉庫,立即觸發項目自動構建。

image-20210110104312235

  1. 安裝GitLab Hook插件:Gitlab Hook 與 GitLab兩個插件

image-20210110104507071

  1. Jenkins設置自動構建

image-20210110104909770

  1. GitLab配置webhook
  • 開啟webhook功能

使用root賬戶登錄到後台,點擊Admin Area -> Settings

勾選”允許鉤子和服務訪問本地網路”

image-20210110105138792

  • 在項目中添加webhook

image-20210110105446860

  • 注意:以下設置必須完成,否則會報錯!

image-20210110105630756

7. Jenkins參數化構建

7.1 理解

有時在項目構建的過程中,我們需要根據用戶的輸入動態傳入一些參數,從而影響整個構建結果,這時我們可以使用參數化構建。

Jenkins支援非常豐富的參數類型。

7.2 演示通過分支名稱來部署不同分支項目

流水線項目作為演示

  1. 項目創建分支,並推送到Gitlab上

image-20210110110424748

  1. 在Jenkins項目配置中添加字元串類型參數

image-20210110110624415
image-20210110110750738

  1. 修改pipeline流水線拉取步驟的程式碼

image-20210110111429375

  1. 點擊Build with Parameters

輸入分支名稱構建即可!構建完成後訪問Tomcat查看結果

image-20210110111553860

8. Jenkins配置郵箱伺服器發送構建結果

8.1 安裝Email Extension Plugin插件

image-20210110120925380

8.2 Jenkins設置郵箱相關參數

Manage Jenkins -> Confifigure System

  1. 設置管理員郵箱

image-20210110111840639

  1. 設置郵件參數

image-20210110121649762

  1. 設置Jenkins默認郵箱資訊

image-20210110112321447

  1. 準備郵件內容(模板)

在項目根目錄編寫email.html,並把文件推送到Gitlab,內容如下:

<!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>(本郵件是Jenkins程式自動下發的,請勿回復!)</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>項目名稱:${PROJECT_NAME}</li>
                    <li>構建編號:第${BUILD_NUMBER}次構建</li>
                    <!--
                    <li>SVN 版本: ${SVN_REVISION}</li>
                    -->
                    <li>觸發原因:${CAUSE}</li>
                    <li>構建日誌:<a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
                    <li>構建地址:<a href="${BUILD_URL}">${BUILD_URL}</a></li>
                    <li>工作目錄:<a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
                    <li>項目地址:<a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
                    <li>變更集:${JELLY_SCRIPT,template="html"}</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="%p"}
            </td>
        </tr>
        <tr>
            <td><b><font color="#0B610B">Failed Test Results:</font></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>Test Logs (if test has ran): <a
                href="${PROJECT_URL}ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip">${PROJECT_URL}/ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip</a>
                <br />
            <br />
            </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>
  1. 編寫腳本添加構建後發送郵件

流水線語法介面選擇post模板

image-20210110115326928

流水線語法介面選擇郵件模板

image-20210110115712143

pipeline {
    agent any

    stages {
        stage('拉取程式碼') {
            steps {
                checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], 
                doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [],
                userRemoteConfigs: [[credentialsId: '0c93f73d-1e42-4d39-a8ab-f07d5dda668f',
                url: 'ssh://[email protected]:2222/DianJianQiJu/web_test2.git']]])
            }
        }
        stage('編譯打包') {
            steps {
                sh label: '', script: 'mvn clean package'
            }
        }
        stage('項目部署') {
            steps {
                deploy adapters: [tomcat8(credentialsId: '22b62c37-4009-4ac3-b82b-fbf926a0cc63', path: '',
                url: '//8.136.103.128:8085')], contextPath: null, war: 'target/*.war'
            }
        }
    }
    post { 
        always { 
            emailext( 
                subject: '構建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}!', 
                body: '${FILE,path="email.html"}', 
                to: '[email protected]' 
            ) 
        } 
        
    }
}
  1. 郵件結果展示

image-20210110121945913

  1. 郵件相關全局參數參考列表:

Configure System -> Extended E-mail Notifification -> Content Token Reference,點擊旁邊的?號即可參考

image-20210110122425975

9. SonarQube程式碼審查工具

SonarQube是一個用於管理程式碼品質的開放平台,可以快速的定位程式碼中潛在的或者明顯的錯誤。目前支援java,C#,C/C++,Python,PL/SQL,Cobol,JavaScrip,Groovy等二十幾種程式語言的程式碼品質管理與檢測。

底層使用Elasticsearch作為程式碼檢索工具。

9.1 Jenkins整合SonarQube圖示

image-20210109191722454

9.2 安裝環境(CentOS7)
軟體 伺服器 版本
MySQL 192.168.0.204 5.7(8+版本會報錯)
SonarQube 192.168.0.200 6.7.4
SonarQube漢化jar包 192.168.0.200 1.19
Sonar-Scanner客戶端 192.168.0.200 4.2.0
9.3 安裝步驟
  1. 在MySQL資料庫中創建sonar資料庫

  2. 安裝SonarQube並設置許可權

yum install unzip
unzip sonarqube-6.7.4.zip #解壓
mkdir /opt/sonar #創建目錄
mv sonarqube-6.7.4/* /opt/sonar #移動文件
user add sonar #創建sonar用戶,必須sonar用於啟動,否則報錯
chown -R sonar. /opt/sonar #更改sonar目錄及文件許可權
  1. 修改SonarQube配置文件
vim /opt/sonar/conf/sonar.properties
#內容如下:
sonar.jdbc.username=root 
sonar.jdbc.password=xxxx
sonar.jdbc.url=jdbc:mysql://192.168.0.204:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false

注意:SonarQube默認監聽9000埠,如果9000埠被佔用需要更改。

  1. 啟動sonar
cd /opt/sonar
su sonar ./bin/linux-x86-64/sonar.sh start #啟動
su sonar ./bin/linux-x86-64/sonar.sh status #查看狀態
su sonar ./bin/linux-x86-64/sonar.sh stop #停止
tail -f logs/sonar.log #查看日誌
  1. 訪問sonar

//192.168.0.200:9000 默認賬戶:admin/admin

  1. 創建token,用於jenkins對sonarqube的憑證管理
#這裡的憑證我已生成 - SonarQube token
root: f0e71f7e7f194dfe4912d20ed5fa0d481b20e7cf

image-20210109182904796

  1. 漢化SonarQube

將漢化jar包放入SonarQube安裝目錄extensions/plugins下,重啟SonarQube)

image-20210109185806332

  1. 關閉將審查結果上傳到SCM的功能

image-20210109185330031

  1. Jenkins安裝SonarQube插件

image-20210109184023896

  1. Jenkins添加SonarQube憑證

image-20210109184426164

  1. Jenkins安裝SonarQube Scanner客戶端

Manage Jenkins->Global Tool Confifiguration

image-20210109185008754

  1. Jenkins進行SonarQube配置

Manage Jenkins -> Confifigure System -> SonarQube servers

image-20210109184733792

9.4 Jenkins項目程式碼審查
  1. 非流水線項目添加構建步驟

image-20210109194606823

  1. 流水線項目添加構建步驟
stage('SonarQube程式碼審查') { 
    steps{ 
    	script { 
    	   # 引入SonarQubeScanner工具
    		scannerHome = tool 'sonarqube-scanner' 
    	}
    	# 引入SonarQube的伺服器環境
    	withSonarQubeEnv('sonarqube6.7.4') { 
    		sh "${scannerHome}/bin/sonar-scanner" 
    	} 
    }
}
  1. 配置文件模板
# 項目的唯一標記(這裡我直接寫項目名)
sonar.projectKey=jp-console 

# 項目名字
sonar.projectName=jp-console

# 項目版本號
sonar.projectVersion=1.0

# 指定掃描程式碼的路徑,.表示在當前項目的根目錄下掃描所有
#sonar.sources=.
sonar.sources=stidem/src/main # 掃描指定目錄

# 巨坑!新版sonar插件需指定sonar.java.binaries
sonar.java.binaries=**/target/classes

# 排除不需要掃描的
sonar.exclusions=**/test/**,**/target/**

# Jdk版本
sonar.java.source=1.8
sonar.java.target=1.8

# 源碼編碼格式
sonar.sourceEncoding=UTF-8
  1. 常見Bug

image-20210109203719921

  1. 程式碼審查結果

image-20210110000116888
image-20210110000252883

10 Jenkins部署Vue項目靜態資源到Nginx

10.1 圖示

image-20210110125417437

10.2 安裝與配置Nginx伺服器
  1. 安裝Nginx伺服器

  2. 以Jeeplus Vue項目為例修改nginx.conf配置文件

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #access_log  logs/access.log  main;

    sendfile        on;
    
    keepalive_timeout  65;
	

    gzip on;
    gzip_min_length 1k;
    gzip_comp_level 9;
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.";
	
    proxy_connect_timeout    600;
    proxy_read_timeout       600;
    proxy_send_timeout       600;	

    server {
        listen       80;
        server_name  生產伺服器域名或ip;
		
	    location ^~ /jeeplus-customer {
            proxy_pass              //127.0.0.1:8085/jeeplus;
            proxy_set_header        Host 127.0.0.1;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location ^~ /userfiles {
            proxy_pass              //127.0.0.1:8085/jeeplus/userfiles;
            proxy_set_header        Host 127.0.0.1;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        }
	
        location / { 
            root   html/jp-ui/dist;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

}
  1. Windows下Nginx相關命令
cmd 進入Nginx解壓目錄 執行以下命令

# 啟動nginx服務
start nginx
# 修改配置後重新載入生效
nginx -s reload
# 快速停止或關閉Nginx
nginx -s stop
# 正常停止或關閉Nginx
nginx -s quit


# 重新打開日誌文件
nginx -s reopen
# 測試nginx配置文件是否正確
nginx -t -c /path/to/nginx.conf 
# 驗證配置是否正確:
nginx -t
# 查看Nginx的版本號
nginx -V
10.3 Jenkins安裝NodeJS插件

image-20210110130301825

10.4 Jenkins配置Nginx伺服器
  1. 安裝Node.js環境

Manage Jenkins -> Global Tool Configuration

image-20210110130506191

  1. Jenkins安裝SSH插件

image-20210110131151335

  1. Jenkins配置SSH遠程伺服器

Manage Jenkins ->Configure System

image-20210110131530375

  1. 創建前端自由風格項目jp-ui並配置

其他步驟與之前的項目配置一致,下面只列出不一樣的

image-20210110130812722
image-20210110130843824
image-20210110131014463

  1. Window生產伺服器安裝SSH工具
  • 在拿不到Linux root賬戶的情況下winscp等工具是無法實現文件傳輸的,此時我們可以借用Bitvise SSH;

  • 下載地址://www.bitvise.com/ssh-server-download Bitvise SSH Server installer – version 7.32, size 14.0 MB。我們需要server版軟體該工具可以實現雙向傳輸,即linux到Windows和 Linux 獲取Windows端文件。

  • 下載後雙擊安裝 -> 勾選個人版本 -> 輸入個人資訊,此處的資訊不作為scp賬戶。下面會講到scp賬戶

  • 進入後點擊「open easy setting」

    • server setting,勾選開放防火牆,當然為了安全你可以自己設置僅限區域網

    image-20210110132308513

    • virtual account 設置,這裡就是scp賬戶資訊,很重要。點擊添加

    image-20210110132523355

    • 設置賬戶資訊

    image-20210110132636018

    • 點擊virtual account password,設置賬戶密碼

    image-20210110132738386

  • 點擊save changes回到server介面。點擊start server,即可啟動ssh服務。如有殺毒軟體攔截請全部攔截

image-20210110132916022

  • 下面我們測試一下,注意window目錄寫法

    • 從Linux獲取Windows文件

    image-20210110133157902

    • 從Linux發送文件到Windows目錄

    image-20210110133256947

  1. Jenkins點擊構建開始執行,查看是否成功。並訪問Nginx進行測試

image-20210110133507941

11. Jenkins + Docker + SpringCloud微服務持續集成

未完待續…

12. 基於Kubernetes/K8S容器編排工具構建Jenkins持續集成

未完待續…