日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Jenkins-自动化构建、测试和部署-学习笔记

發(fā)布時間:2024/4/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Jenkins-自动化构建、测试和部署-学习笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

來源于黑馬程序員jenkins文檔筆記

1、Jenkins介紹

Jenkins 是一款流行的開源持續(xù)集成(Continuous Integration)工具,廣泛用于項(xiàng)目開發(fā),具有自動
化構(gòu)建、測試和部署等功能。官網(wǎng): http://jenkins-ci.org/。
Jenkins的特征:
開源的Java語言開發(fā)持續(xù)集成工具,支持持續(xù)集成,持續(xù)部署。
易于安裝部署配置:可通過yum安裝,或下載war包以及通過docker容器等快速實(shí)現(xiàn)安裝部署,可
方便web界面配置管理。
消息通知及測試報告:集成RSS/E-mail通過RSS發(fā)布構(gòu)建結(jié)果或當(dāng)構(gòu)建完成時通過e-mail通知,生
成JUnit/TestNG測試報告。
分布式構(gòu)建:支持Jenkins能夠讓多臺計算機(jī)一起構(gòu)建/測試。
文件識別:Jenkins能夠跟蹤哪次構(gòu)建生成哪些jar,哪次構(gòu)建使用哪個版本的jar等。
豐富的插件支持:支持?jǐn)U展插件,你可以開發(fā)適合自己團(tuán)隊(duì)使用的工具,如git,svn,maven,
docker等。

2、Jenkins安裝和持續(xù)集成環(huán)境配置

持續(xù)集成流程說明

1)首先,開發(fā)人員每天進(jìn)行代碼提交,提交到Git倉庫
2)然后,Jenkins作為持續(xù)集成工具,使用Git工具到Git倉庫拉取代碼到集成服務(wù)器,再配合JDK,
Maven等軟件完成代碼編譯,代碼測試與審查,測試,打包等工作,在這個過程中每一步出錯,都重新
再執(zhí)行一次整個流程。
3)最后,Jenkins把生成的jar或war包分發(fā)到測試服務(wù)器或者生產(chǎn)服務(wù)器,測試人員或用戶就可以訪問
應(yīng)用。

持續(xù)集成環(huán)境(1)-Jenkins安裝

1)安裝JDK
Jenkins需要依賴JDK,所以先安裝JDK1.8
yum install java-1.8.0-openjdk* -y
安裝目錄為:/usr/lib/jvm
2)獲取jenkins安裝包
下載頁面:https://jenkins.io/zh/download/
安裝文件:jenkins-2.190.3-1.1.noarch.rpm
3)把安裝包上傳到192.168.66.101服務(wù)器,進(jìn)行安裝
rpm -ivh jenkins-2.190.3-1.1.noarch.rpm
4)修改Jenkins配置
vi /etc/syscofig/jenkins
修改內(nèi)容如下:
JENKINS_USER=“root”
JENKINS_PORT=“8888”
5)啟動Jenkins
systemctl start jenkins
6)打開瀏覽器訪問
http://192.168.66.101:8888
注意:本服務(wù)器把防火墻關(guān)閉了,如果開啟防火墻,需要在防火墻添加端口
7)獲取并輸入admin賬戶密碼
cat /var/lib/jenkins/secrets/initialAdminPassword
8)跳過插件安裝
因?yàn)镴enkins插件需要連接默認(rèn)官網(wǎng)下載,速度非常慢,而且經(jīng)過會失敗,所以我們暫時先跳過插件安



9)添加一個管理員賬戶,并進(jìn)入Jenkins后臺

保存并完成

開始使用Jenkins

持續(xù)集成環(huán)境(2)-Jenkins插件管理

Jenkins本身不提供很多功能,我們可以通過使用插件來滿足我們的使用。例如從Gitlab拉取代碼,使用
Maven構(gòu)建項(xiàng)目等功能需要依靠插件完成。接下來演示如何下載插件。
修改Jenkins插件下載地址
Jenkins國外官方插件地址下載速度非常慢,所以可以修改為國內(nèi)插件地址:
Jenkins->Manage Jenkins->Manage Plugins,點(diǎn)擊Available

這樣做是為了把Jenkins官方的插件列表下載到本地,接著修改地址文件,替換為國內(nèi)插件地址

cd /var/lib/jenkins/updates sed -i 's/http:\/\/updates.jenkinsci.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

最后,Manage Plugins點(diǎn)擊Advanced,把Update Site改為國內(nèi)插件下載地址

最后,Manage Plugins點(diǎn)擊Advanced,把Update Site改為國內(nèi)插件下載地址 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json


Sumbit后,在瀏覽器輸入: http://192.168.66.101:8888/restart ,重啟Jenkins。

下載中文漢化插件

Jenkins->Manage Jenkins->Manage Plugins,點(diǎn)擊Available,搜索"Chinese"

持續(xù)集成環(huán)境(3)-Jenkins用戶權(quán)限管理

我們可以利用Role-based Authorization Strategy 插件來管理Jenkins用戶權(quán)限

安裝Role-based Authorization Strategy插件


授權(quán)策略切換為"Role-Based Strategy",保存

創(chuàng)建角色

在系統(tǒng)管理頁面進(jìn)入 Manage and Assign Roles

點(diǎn)擊"Manage Roles"

Global roles(全局角色):管理員等高級用戶可以創(chuàng)建基于全局的角色 Project roles(項(xiàng)目角色):
針對某個或者某些項(xiàng)目的角色 Slave roles(奴隸角色):節(jié)點(diǎn)相關(guān)的權(quán)限
我們添加以下三個角色:
baseRole:該角色為全局角色。這個角色需要綁定Overall下面的Read權(quán)限,是為了給所有用戶綁
定最基本的Jenkins訪問權(quán)限。注意:如果不給后續(xù)用戶綁定這個角色,會報錯誤:用戶名 is
missing the Overall/Read permission
role1:該角色為項(xiàng)目角色。使用正則表達(dá)式綁定"itcast.",意思是只能操作itcast開頭的項(xiàng)目。
role2:該角色也為項(xiàng)目角色。綁定"itheima.",意思是只能操作itheima開頭的項(xiàng)目。

保存。

創(chuàng)建用戶

在系統(tǒng)管理頁面進(jìn)入 Manage Users

分別創(chuàng)建兩個用戶:jack和eric

給用戶分配角色
系統(tǒng)管理頁面進(jìn)入Manage and Assign Roles,點(diǎn)擊Assign Roles
綁定規(guī)則如下:
eric用戶分別綁定baseRole和role1角色
jack用戶分別綁定baseRole和role2角色

保存。

創(chuàng)建項(xiàng)目測試權(quán)限

以itcast管理員賬戶創(chuàng)建兩個項(xiàng)目,分別為itcast01和itheima01

結(jié)果為:
eric用戶登錄,只能看到itcast01項(xiàng)目
jack用戶登錄,只能看到itheima01項(xiàng)目

持續(xù)集成環(huán)境(4)-Jenkins憑證管理

憑據(jù)可以用來存儲需要密文保護(hù)的數(shù)據(jù)庫密碼、Gitlab密碼信息、Docker私有倉庫密碼等,以便
Jenkins可以和這些第三方的應(yīng)用進(jìn)行交互。

安裝Credentials Binding插件

要在Jenkins使用憑證管理功能,需要安裝Credentials Binding插件

安裝插件后,左邊多了"憑證"菜單,在這里管理所有憑證

可以添加的憑證有5種:

Username with password:用戶名和密碼
SSH Username with private key: 使用SSH用戶和密鑰
Secret file:需要保密的文本文件,使用時Jenkins會將文件復(fù)制到一個臨時目錄中,再將文件路徑
設(shè)置到一個變量中,等構(gòu)建結(jié)束后,所復(fù)制的Secret file就會被刪除。
Secret text:需要保存的一個加密的文本串,如釘釘機(jī)器人或Github的api token
Certificate:通過上傳證書文件的方式
常用的憑證類型有:Username with password(用戶密碼)和SSH Username with private key(SSH
密鑰)
接下來以使用Git工具到Gitlab拉取項(xiàng)目源碼為例,演示Jenkins的如何管理Gitlab的憑證。

安裝Git插件和Git工具

為了讓Jenkins支持從Gitlab拉取源碼,需要安裝Git插件以及在CentOS7上安裝Git工具。
Git插件安裝:

CentOS7上安裝Git工具:
yum install git -y 安裝
git --version 安裝后查看版本

用戶密碼類型

1)創(chuàng)建憑證
Jenkins->憑證->系統(tǒng)->全局憑證->添加憑證


選擇"Username with password",輸入Gitlab的用戶名和密碼,點(diǎn)擊"確定"。

2)測試憑證是否可用
創(chuàng)建一個FreeStyle項(xiàng)目:新建Item->FreeStyle Project->確定

找到"源碼管理"->“Git”,在Repository URL復(fù)制Gitlab中的項(xiàng)目URL

這時會報錯說無法連接倉庫!在Credentials選擇剛剛添加的憑證就不報錯啦

保存配置后,點(diǎn)擊構(gòu)建”Build Now“ 開始構(gòu)建項(xiàng)目


查看/var/lib/jenkins/workspace/目錄,發(fā)現(xiàn)已經(jīng)從Gitlab成功拉取了代碼到Jenkins中。

SSH密鑰類型

SSH免密登錄示意圖

1)使用root用戶生成公鑰和私鑰

ssh-keygen -t rsa

在/root/.ssh/目錄保存了公鑰和使用

id_rsa:私鑰文件
id_rsa.pub:公鑰文件
2)把生成的公鑰放在Gitlab中
以root賬戶登錄->點(diǎn)擊頭像->Settings->SSH Keys
復(fù)制剛才id_rsa.pub文件的內(nèi)容到這里,點(diǎn)擊"Add Key"

3)在Jenkins中添加憑證,配置私鑰
在Jenkins添加一個新的憑證,類型為"SSH Username with private key",把剛才生成私有文件內(nèi)容復(fù)制過來

4)測試憑證是否可用
新建"test02"項(xiàng)目->源碼管理->Git,這次要使用Gitlab的SSH連接,并且選擇SSH憑證


同樣嘗試構(gòu)建項(xiàng)目,如果代碼可以正常拉取,代表憑證配置成功!

持續(xù)集成環(huán)境(5)-Maven安裝和配置

在Jenkins集成服務(wù)器上,我們需要安裝Maven來編譯和打包項(xiàng)目。

安裝Maven

先上傳Maven軟件到192.168.66.101

tar -xzf apache-maven-3.6.2-bin.tar.gz 解壓 mkdir -p /opt/maven 創(chuàng)建目錄 mv apache-maven-3.6.2/* /opt/maven 移動文件

配置環(huán)境變量

vi /etc/profile export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export MAVEN_HOME=/opt/maven export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin source /etc/profile 配置生效 mvn -v 查找Maven版本

全局工具配置關(guān)聯(lián)JDK和Maven

Jenkins->Global Tool Configuration->JDK->新增JDK,配置如下:

Jenkins->Global Tool Configuration->Maven->新增Maven,配置如下:

添加Jenkins全局變量

Manage Jenkins->Configure System->Global Properties ,添加三個全局變量
JAVA_HOME、M2_HOME、PATH+EXTRA

修改Maven的settings.xml

mkdir /root/repo 創(chuàng)建本地倉庫目錄 vi /opt/maven/conf/settings.xml

本地倉庫改為:/root/repo/
添加阿里云私服地址:

alimaven aliyun maven http://maven.aliyun.com/nexus/content/groups/public/ central

測試Maven是否配置成功

使用之前的gitlab密碼測試項(xiàng)目,修改配置

構(gòu)建->增加構(gòu)建步驟->Execute Shell

輸入

mvn clean package


再次構(gòu)建,如果可以把項(xiàng)目打成war包,代表maven環(huán)境配置成功啦!

持續(xù)集成環(huán)境(6)-Tomcat安裝和配置

安裝Tomcat8.5

把Tomcat壓縮包上傳到192.168.66.102服務(wù)器

yum install java-1.8.0-openjdk* -y 安裝JDK(已完成) tar -xzf apache-tomcat-8.5.47.tar.gz 解壓 mkdir -p /opt/tomcat 創(chuàng)建目錄 mv /root/apache-tomcat-8.5.47/* /opt/tomcat 移動文件 /opt/tomcat/bin/startup.sh 啟動tomcat

注意:服務(wù)器已經(jīng)關(guān)閉了防火墻,所以可以直接訪問Tomcat啦
地址為:http://192.168.66.102/8080

配置Tomcat用戶角色權(quán)限

默認(rèn)情況下Tomcat是沒有配置用戶角色權(quán)限的


但是,后續(xù)Jenkins部署項(xiàng)目到Tomcat服務(wù)器,需要用到Tomcat的用戶,所以修改tomcat以下配置,
添加用戶及權(quán)限

vi /opt/tomcat/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,managerscript,tomcat,admin-gui,admin-script"/> </tomcat-users>

用戶和密碼都是:tomcat
注意:為了能夠剛才配置的用戶登錄到Tomcat,還需要修改以下配置

vi /opt/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" /> -->

把上面這行注釋掉即可!

重啟Tomcat,訪問測試

/opt/tomcat/bin/shutdown.sh 停止 /opt/tomcat/bin/startup.sh 啟動

訪問: http://192.168.66.102:8080/manager/html ,輸入tomcat和tomcat,看到以下頁面代表成功

3、Jenkins構(gòu)建Maven項(xiàng)目

Jenkins項(xiàng)目構(gòu)建類型(1)-Jenkins構(gòu)建的項(xiàng)目類型介紹

Jenkins中自動構(gòu)建項(xiàng)目的類型有很多,常用的有以下三種:

自由風(fēng)格軟件項(xiàng)目(FreeStyle Project)
Maven項(xiàng)目(Maven Project)
流水線項(xiàng)目(Pipeline Project)

每種類型的構(gòu)建其實(shí)都可以完成一樣的構(gòu)建過程與結(jié)果,只是在操作方式、靈活度等方面有所區(qū)別,在
實(shí)際開發(fā)中可以根據(jù)自己的需求和習(xí)慣來選擇。(PS:個人推薦使用流水線類型,因?yàn)殪`活度非常高)

Jenkins項(xiàng)目構(gòu)建類型(2)-自由風(fēng)格項(xiàng)目構(gòu)建

下面演示創(chuàng)建一個自由風(fēng)格項(xiàng)目來完成項(xiàng)目的集成過程:
拉取代碼->編譯->打包->部署

拉取代碼

1)創(chuàng)建項(xiàng)目

2)配置源碼管理,從gitlab拉取代碼

編譯打包

構(gòu)建->添加構(gòu)建步驟->Executor Shell

echo "開始編譯和打包" mvn clean package echo "編譯和打包結(jié)束"

部署

把項(xiàng)目部署到遠(yuǎn)程的Tomcat里面
1)安裝 Deploy to container插件
Jenkins本身無法實(shí)現(xiàn)遠(yuǎn)程部署到Tomcat的功能,需要安裝Deploy to container插件實(shí)現(xiàn)

2)添加Tomcat用戶憑證

3)添加構(gòu)建后操作


點(diǎn)擊"Build Now",開始構(gòu)建過程

4)部署成功后,訪問項(xiàng)目

演示改動代碼后的持續(xù)集成

1)IDEA中源碼修改并提交到gitlab
2)在Jenkins中項(xiàng)目重新構(gòu)建
3)訪問Tomcat

Jenkins項(xiàng)目構(gòu)建類型(3)-Maven項(xiàng)目構(gòu)建

1)安裝Maven Integration插件

2)創(chuàng)建Maven項(xiàng)目

3)配置項(xiàng)目
拉取代碼和遠(yuǎn)程部署的過程和自由風(fēng)格項(xiàng)目一樣,只是"構(gòu)建"部分不同

Jenkins項(xiàng)目構(gòu)建類型(4)-Pipeline流水線項(xiàng)目構(gòu)建(*)

Pipeline簡介

1)概念
Pipeline,簡單來說,就是一套運(yùn)行在 Jenkins 上的工作流框架,將原來獨(dú)立運(yùn)行于單個或者多個節(jié)點(diǎn)
的任務(wù)連接起來,實(shí)現(xiàn)單個任務(wù)難以完成的復(fù)雜流程編排和可視化的工作。
2)使用Pipeline有以下好處(來自翻譯自官方文檔):
代碼:Pipeline以代碼的形式實(shí)現(xiàn),通常被檢入源代碼控制,使團(tuán)隊(duì)能夠編輯,審查和迭代其傳送流
程。 持久:無論是計劃內(nèi)的還是計劃外的服務(wù)器重啟,Pipeline都是可恢復(fù)的。 可停止:Pipeline可接
收交互式輸入,以確定是否繼續(xù)執(zhí)行Pipeline。 多功能:Pipeline支持現(xiàn)實(shí)世界中復(fù)雜的持續(xù)交付要
求。它支持fork/join、循環(huán)執(zhí)行,并行執(zhí)行任務(wù)的功能。 可擴(kuò)展:Pipeline插件支持其DSL的自定義擴(kuò)
展 ,以及與其他插件集成的多個選項(xiàng)。
3)如何創(chuàng)建 Jenkins Pipeline呢?
Pipeline 腳本是由 Groovy 語言實(shí)現(xiàn)的,但是我們沒必要單獨(dú)去學(xué)習(xí) Groovy
Pipeline 支持兩種語法:Declarative(聲明式)和 Scripted Pipeline(腳本式)語法
Pipeline 也有兩種創(chuàng)建方法:可以直接在 Jenkins 的 Web UI 界面中輸入腳本;也可以通過創(chuàng)建一
個 Jenkinsfile 腳本文件放入項(xiàng)目源碼庫中(一般我們都推薦在 Jenkins 中直接從源代碼控制(SCM)
中直接載入 Jenkinsfile Pipeline 這種方法)。

安裝Pipeline插件

Manage Jenkins->Manage Plugins->可選插件

安裝插件后,創(chuàng)建項(xiàng)目的時候多了“流水線”類型

Pipeline語法快速入門

1)Declarative聲明式-Pipeline

創(chuàng)建項(xiàng)目

流水線->選擇HelloWorld模板

生成內(nèi)容如下:

pipeline {agent anystages {stage('Hello') {steps {echo 'Hello World'}}} }

stages:代表整個流水線的所有執(zhí)行階段。通常stages只有1個,里面包含多個stage
stage:代表流水線中的某個階段,可能出現(xiàn)n個。一般分為拉取代碼,編譯構(gòu)建,部署等階段。
steps:代表一個階段內(nèi)需要執(zhí)行的邏輯。steps里面是shell腳本,git拉取代碼,ssh遠(yuǎn)程發(fā)布等任意內(nèi)
容。
編寫一個簡單聲明式Pipeline:

pipeline {agent anystages {stage('拉取代碼') {steps {echo '拉取代碼'}}stage('編譯構(gòu)建') {steps {echo '編譯構(gòu)建'}}stage('項(xiàng)目部署') {steps {echo '項(xiàng)目部署'}}} }

點(diǎn)擊構(gòu)建,可以看到整個構(gòu)建過程

2)Scripted Pipeline腳本式-Pipeline

創(chuàng)建項(xiàng)目

這次選擇"Scripted Pipeline"

node {def mvnHomestage('Preparation') { // for display purposes}stage('Build') {}stage('Results') {} }

Node:節(jié)點(diǎn),一個 Node 就是一個 Jenkins 節(jié)點(diǎn),Master 或者 Agent,是執(zhí)行 Step 的具體運(yùn)行
環(huán)境,后續(xù)講到Jenkins的Master-Slave架構(gòu)的時候用到。
Stage:階段,一個 Pipeline 可以劃分為若干個 Stage,每個 Stage 代表一組操作,比如:
Build、Test、Deploy,Stage 是一個邏輯分組的概念。
Step:步驟,Step 是最基本的操作單元,可以是打印一句話,也可以是構(gòu)建一個 Docker 鏡像,
由各類 Jenkins 插件提供,比如命令:sh ‘make’,就相當(dāng)于我們平時 shell 終端中執(zhí)行 make 命令
一樣。
編寫一個簡單的腳本式Pipeline

node {def mvnHomestage('拉取代碼') { // for display purposesecho '拉取代碼'}stage('編譯構(gòu)建') {echo '編譯構(gòu)建'}stage('項(xiàng)目部署') {echo '項(xiàng)目部署'} }

構(gòu)建結(jié)果和聲明式一樣!

腳本式Pipeline可以使用腳本生成器生成

拉取代碼

pipeline {agent anystages {stage('拉取代碼') {steps {checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '68f2087f-a034-4d39-a9ff-1f776dd3dfa8', url: 'git@192.168.66.100:itheima_group/web_demo.git']]])}}} }

編譯打包

pipeline {agent anystages {stage('拉取代碼') {steps {checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '68f2087f-a034-4d39-a9ff-1f776dd3dfa8', url: 'git@192.168.66.100:itheima_group/web_demo.git']]])}}stage('編譯構(gòu)建') {steps {sh label: '', script: 'mvn clean package'}}} }

部署

pipeline {agent anystages {stage('拉取代碼') {steps {checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '68f2087f-a034-4d39-a9ff-1f776dd3dfa8', url: 'git@192.168.66.100:itheima_group/web_demo.git']]])}}stage('編譯構(gòu)建') {steps {sh label: '', script: 'mvn clean package'}}stage('項(xiàng)目部署') {steps {deploy adapters: [tomcat8(credentialsId: 'afc43e5e-4a4e-4de6-984fb1d5a254e434', path: '', url: 'http://192.168.66.102:8080')], contextPath: null, war: 'target/*.war'}} } }

Pipeline Script from SCM

剛才我們都是直接在Jenkins的UI界面編寫Pipeline代碼,這樣不方便腳本維護(hù),建議把Pipeline腳本放
在項(xiàng)目中(一起進(jìn)行版本控制)
1)在項(xiàng)目根目錄建立Jenkinsfile文件,把內(nèi)容復(fù)制到該文件中

把Jenkinsfile上傳到Gitlab
2)在項(xiàng)目中引用該文件

Jenkins項(xiàng)目構(gòu)建細(xì)節(jié)(1)-常用的構(gòu)建觸發(fā)器

Jenkins內(nèi)置4種構(gòu)建觸發(fā)器:
觸發(fā)遠(yuǎn)程構(gòu)建
其他工程構(gòu)建后觸發(fā)(Build after other projects are build)
定時構(gòu)建(Build periodically)
輪詢SCM(Poll SCM)

觸發(fā)遠(yuǎn)程構(gòu)建

其他工程構(gòu)建后觸發(fā)

1)創(chuàng)建pre_job流水線工程

2)配置需要觸發(fā)的工程

定時構(gòu)建


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

一些定時表達(dá)式的例子: 每30分鐘構(gòu)建一次:H代表形參 H/30 * * * * 10:02 10:32 每2個小時構(gòu)建一次: H H/2 * * * 每天的8點(diǎn),12點(diǎn),22點(diǎn),一天構(gòu)建3次: (多個時間點(diǎn)中間用逗號隔開) 0 8,12,22 * * * 每天中午12點(diǎn)定時構(gòu)建一次 H 12 * * * 每天下午18點(diǎn)定時構(gòu)建一次 H 18 * * * 在每個小時的前半個小時內(nèi)的每10分鐘 H(0-29)/10 * * * * 每兩小時一次,每個工作日上午9點(diǎn)到下午5點(diǎn)(也許是上午10:38,下午12:38,下午2:38,下午 4:38) H H(9-16)/2 * * 1-5

輪詢SCM

輪詢SCM,是指定時掃描本地代碼倉庫的代碼是否有變更,如果代碼有變更就觸發(fā)項(xiàng)目構(gòu)建。

注意:這次構(gòu)建觸發(fā)器,Jenkins會定時掃描本地整個項(xiàng)目的代碼,增大系統(tǒng)的開銷,不建議使用。

Jenkins項(xiàng)目構(gòu)建細(xì)節(jié)(2)-Git hook自動觸發(fā)構(gòu)建(*)

剛才我們看到在Jenkins的內(nèi)置構(gòu)建觸發(fā)器中,輪詢SCM可以實(shí)現(xiàn)Gitlab代碼更新,項(xiàng)目自動構(gòu)建,但是
該方案的性能不佳。那有沒有更好的方案呢? 有的。就是利用Gitlab的webhook實(shí)現(xiàn)代碼push到倉
庫,立即觸發(fā)項(xiàng)目自動構(gòu)建。

安裝Gitlab Hook插件

需要安裝兩個插件:
Gitlab Hook和GitLab

Jenkins設(shè)置自動構(gòu)建


等會需要把生成的webhook URL配置到Gitlab中。

Gitlab配置webhook

1)開啟webhook功能
使用root賬戶登錄到后臺,點(diǎn)擊Admin Area -> Settings -> Network
勾選"Allow requests to the local network from web hooks and services"

2)在項(xiàng)目添加webhook
點(diǎn)擊項(xiàng)目->Settings->Integrations

注意:以下設(shè)置必須完成,否則會報錯!
Manage Jenkins->Configure System

Jenkins項(xiàng)目構(gòu)建細(xì)節(jié)(3)-Jenkins的參數(shù)化構(gòu)建

有時在項(xiàng)目構(gòu)建的過程中,我們需要根據(jù)用戶的輸入動態(tài)傳入一些參數(shù),從而影響整個構(gòu)建結(jié)果,這時
我們可以使用參數(shù)化構(gòu)建。
Jenkins支持非常豐富的參數(shù)類型

接下來演示通過輸入gitlab項(xiàng)目的分支名稱來部署不同分支項(xiàng)目。

項(xiàng)目創(chuàng)建分支,并推送到Gitlab上


新建分支:v1,代碼稍微改動下,然后提交到gitlab上。
這時看到gitlab上有一個兩個分支:master和v1

在Jenkins添加字符串類型參數(shù)


改動pipeline流水線代碼

點(diǎn)擊Build with Parameters

Jenkins+SonarQube代碼審查(1) - 安裝SonarQube

SonaQube簡介

SonarQube是一個用于管理代碼質(zhì)量的開放平臺,可以快速的定位代碼中潛在的或者明顯的錯誤。目前
支持java,C#,C/C++,Python,PL/SQL,Cobol,JavaScrip,Groovy等二十幾種編程語言的代碼質(zhì)量管理與檢
測。
官網(wǎng):https://www.sonarqube.org/

安裝SonarQube
1)安裝MySQL(已完成)
2)安裝SonarQube
在MySQL創(chuàng)建sonar數(shù)據(jù)庫

下載sonar壓縮包:
https://www.sonarqube.org/downloads/
解壓sonar,并設(shè)置權(quán)限

yum install unzip unzip sonarqube-6.7.4.zip 解壓 mkdir /opt/sonar 創(chuàng)建目錄 mv sonarqube-6.7.4/* /opt/sonar 移動文件 useradd sonar 創(chuàng)建sonar用戶,必須sonar用于啟動,否則報錯 chown -R sonar. /opt/sonar 更改sonar目錄及文件權(quán)限

修改sonar配置文件

vi /opt/sonarqube-6.7.4/conf/sonar.properties 內(nèi)容如下: sonar.jdbc.username=root sonar.jdbc.password=Root@123 sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar? useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs= maxPerformance&useSSL=false

注意:sonar默認(rèn)監(jiān)聽9000端口,如果9000端口被占用,需要更改。
啟動sonar

cd /opt/sonarqube-6.7.4 su sonar ./bin/linux-x86-64/sonar.sh start 啟動 su sonar ./bin/linux-x86-64/sonar.sh status 查看狀態(tài) su sonar ./bin/linux-x86-64/sonar.sh stop 停止 tail -f logs/sonar.logs 查看日志

訪問sonar
http://192.168.66.101:9000

默認(rèn)賬戶:admin/admin
創(chuàng)建token

token要記下來后面要使用
0151ae8c548a143eda9253e4334ad030b56047ee

Jenkins+SonarQube代碼審查(2) - 實(shí)現(xiàn)代碼審查

安裝SonarQube Scanner插件

添加SonarQube憑證

Jenkins進(jìn)行SonarQube配置

Manage Jenkins->Configure System->SonarQube servers

SonaQube關(guān)閉審查結(jié)果上傳到SCM功能


在項(xiàng)目添加SonaQube代碼審查(非流水線項(xiàng)目)
添加構(gòu)建步驟:

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

在項(xiàng)目添加SonaQube代碼審查(流水線項(xiàng)目)

1)項(xiàng)目根目錄下,創(chuàng)建sonar-project.properties文件

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

2)修改Jenkinsfile,加入SonarQube代碼審查階段

pipeline { agent any stages { stage('拉取代碼') { steps { checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '68f2087f-a034-4d39-a9ff-1f776dd3dfa8', url: 'git@192.168.66.100:itheima_group/web_demo.git']]]) } } stage('編譯構(gòu)建') { steps { sh label: '', script: 'mvn clean package' } } stage('SonarQube代碼審查') { steps{ script { scannerHome = tool 'sonarqube-scanner' } withSonarQubeEnv('sonarqube6.7.4') { sh "${scannerHome}/bin/sonar-scanner" } } } stage('項(xiàng)目部署') { steps { deploy adapters: [tomcat8(credentialsId: 'afc43e5e-4a4e-4de6-984fb1d5a254e434', path: '', url: 'http://192.168.66.102:8080')], contextPath: null, war: 'target/*.war' } } } post { always { emailext( subject: '構(gòu)建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}!', body: '${FILE,path="email.html"}', to: '1014671449@qq.com' ) } } }

3)到SonarQube的UI界面查看審查結(jié)果

4、Jenkins+Docker+SpringCloud微服務(wù)持續(xù)集成(上)

Jenkins+Docker+SpringCloud持續(xù)集成流程說明


大致流程說明:
1)開發(fā)人員每天把代碼提交到Gitlab代碼倉庫
2)Jenkins從Gitlab中拉取項(xiàng)目源碼,編譯并打成jar包,然后構(gòu)建成Docker鏡像,將鏡像上傳到
Harbor私有倉庫。
3)Jenkins發(fā)送SSH遠(yuǎn)程命令,讓生產(chǎn)部署服務(wù)器到Harbor私有倉庫拉取鏡像到本地,然后創(chuàng)建容器。
4)最后,用戶可以訪問到容器
服務(wù)列表(紅色的軟件為需要安裝的軟件,黑色代表已經(jīng)安裝)

SpringCloud微服務(wù)源碼概述
項(xiàng)目架構(gòu):前后端分離
后端技術(shù)棧:SpringBoot+SpringCloud+SpringDataJpa(Spring全家桶)
微服務(wù)項(xiàng)目結(jié)構(gòu):

tensquare_parent:父工程,存放基礎(chǔ)配置
tensquare_common:通用工程,存放工具類
tensquare_eureka_server:SpringCloud的Eureka注冊中心
tensquare_zuul:SpringCloud的網(wǎng)關(guān)服務(wù)
tensquare_admin_service:基礎(chǔ)權(quán)限認(rèn)證中心,負(fù)責(zé)用戶認(rèn)證(使用JWT認(rèn)證)
tensquare_gathering:一個簡單的業(yè)務(wù)模塊,活動微服務(wù)相關(guān)邏輯

數(shù)據(jù)庫結(jié)構(gòu):

tensquare_user:用戶認(rèn)證數(shù)據(jù)庫,存放用戶賬戶數(shù)據(jù)。對應(yīng)tensquare_admin_service微服務(wù)
tensquare_gathering:活動微服務(wù)數(shù)據(jù)庫。對應(yīng)tensquare_gathering微服務(wù)
微服務(wù)配置分析:
tensquare_eureka
tensquare_zuul
tensquare_admin_service
tensquare_gathering

本地部署(1)-SpringCloud微服務(wù)部署

本地運(yùn)行微服務(wù)

1)逐一啟動微服務(wù)
2)使用postman測試功能是否可用

本地部署微服務(wù)

1)SpringBoot微服務(wù)項(xiàng)目打包
必須導(dǎo)入該插件

<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin>

打包后在target下產(chǎn)生jar包
2)本地運(yùn)行微服務(wù)的jar包

java -jar xxx.jar

3)查看效果

本地部署(2)-前端靜態(tài)web網(wǎng)站

前端技術(shù)棧:NodeJS+VueJS+ElementUI
使用Visual Studio Code打開源碼
1)本地運(yùn)行

npm run dev

2)打包靜態(tài)web網(wǎng)站

npm run build

打包后,產(chǎn)生dist目錄的靜態(tài)文件
3)部署到nginx服務(wù)器
把dist目錄的靜態(tài)文件拷貝到nginx的html目錄,啟動nginx
4)啟動nginx,并訪問

環(huán)境準(zhǔn)備(1)-Docker快速入門(請查閱我的docker筆記)

Docker簡介

Docker 是一個開源的應(yīng)用容器引擎,基于 Go 語言 并遵從 Apache2.0 協(xié)議開源。
Docker 可以讓開發(fā)者打包他們的應(yīng)用以及依賴包到一個輕量級、可移植的容器中,然后發(fā)布到任何流
行的 Linux 機(jī)器上,也可以實(shí)現(xiàn)虛擬化。
容器是完全使用沙箱機(jī)制,相互之間不會有任何接口(類似 iPhone 的 app),更重要的是容器性能開銷
極低。

簡單一句話總結(jié):Docker技術(shù)就是讓我們更加高效輕松地將任何應(yīng)用在Linux服務(wù)器部署和使用。

環(huán)境準(zhǔn)備(2)-Dockerfile鏡像腳本快速入門

Dockerfile簡介

Dockerfile其實(shí)就是我們用來構(gòu)建Docker鏡像的源碼,當(dāng)然這不是所謂的編程源碼,而是一些命令的組
合,只要理解它的邏輯和語法格式,就可以編寫Dockerfile了。
簡單點(diǎn)說,Dockerfile的作用:它可以讓用戶個性化定制Docker鏡像。因?yàn)楣ぷ鳝h(huán)境中的需求各式各
樣,網(wǎng)絡(luò)上的鏡像很難滿足實(shí)際的需求。

Dockerfile常見命令

RUN、CMD、ENTRYPOINT的區(qū)別?

RUN:用于指定 docker build 過程中要運(yùn)行的命令,即是創(chuàng)建 Docker 鏡像(image)的步驟
CMD:設(shè)置容器的啟動命令, Dockerfile 中只能有一條 CMD 命令,如果寫了多條則最后一條生效,
CMD不支持接收docker run的參數(shù)。
ENTRYPOINT:入口程序是容器啟動時執(zhí)行的程序, docker run 中最后的命令將作為參數(shù)傳遞給入口
程序 ,ENTRYPOINY類似于 CMD 指令,但可以接收docker run的參數(shù) 。

以下是mysql官方鏡像的Dockerfile示例:

FROM oraclelinux:7-slim ARG MYSQL_SERVER_PACKAGE=mysql-community-server-minimal-5.7.28 ARG MYSQL_SHELL_PACKAGE=mysql-shell-8.0.18 # Install server RUN yum install -y https://repo.mysql.com/mysql-community-minimal-releaseel7.rpm \ https://repo.mysql.com/mysql-community-release-el7.rpm \ && yum-config-manager --enable mysql57-server-minimal \ && yum install -y \ $MYSQL_SERVER_PACKAGE \ $MYSQL_SHELL_PACKAGE \ libpwquality \ && yum clean all \ && mkdir /docker-entrypoint-initdb.d VOLUME /var/lib/mysql COPY docker-entrypoint.sh /entrypoint.sh COPY healthcheck.sh /healthcheck.sh ENTRYPOINT ["/entrypoint.sh"] HEALTHCHECK CMD /healthcheck.sh EXPOSE 3306 33060 CMD ["mysqld"]

使用Dockerfile制作微服務(wù)鏡像

我們利用Dockerfile制作一個Eureka注冊中心的鏡像
1)上傳Eureka的微服務(wù)jar包到linux
2)編寫Dockerfile

FROM openjdk:8-jdk-alpine ARG JAR_FILE COPY ${JAR_FILE} app.jar EXPOSE 10086 ENTRYPOINT ["java","-jar","/app.jar"]

3)構(gòu)建鏡像

docker build --build-arg JAR_FILE=tensquare_eureka_server-1.0-SNAPSHOT.jar -t eureka:v1 .

4)查看鏡像是否創(chuàng)建成功

docker images

5)創(chuàng)建容器

docker run -i --name=eureka -p 10086:10086 eureka:v1

6)訪問容器

環(huán)境準(zhǔn)備(3)-Harbor鏡像倉庫安裝及使用

Harbor簡介


Harbor(港口,港灣)是一個用于存儲和分發(fā)Docker鏡像的企業(yè)級Registry服務(wù)器。
除了Harbor這個私有鏡像倉庫之外,還有Docker官方提供的Registry。相對Registry,Harbor具有很
多優(yōu)勢:

  • 提供分層傳輸機(jī)制,優(yōu)化網(wǎng)絡(luò)傳輸 Docker鏡像是是分層的,而如果每次傳輸都使用全量文件(所以
    用FTP的方式并不適合),顯然不經(jīng)濟(jì)。必須提供識別分層傳輸?shù)臋C(jī)制,以層的UUID為標(biāo)識,確定
    傳輸?shù)膶ο蟆?/li>
  • 提供WEB界面,優(yōu)化用戶體驗(yàn) 只用鏡像的名字來進(jìn)行上傳下載顯然很不方便,需要有一個用戶界
    面可以支持登陸、搜索功能,包括區(qū)分公有、私有鏡像。
  • 支持水平擴(kuò)展集群 當(dāng)有用戶對鏡像的上傳下載操作集中在某服務(wù)器,需要對相應(yīng)的訪問壓力作分
    解。
  • 良好的安全機(jī)制 企業(yè)中的開發(fā)團(tuán)隊(duì)有很多不同的職位,對于不同的職位人員,分配不同的權(quán)限,
    具有更好的安全性。
  • Harbor安裝

    Harbor需要安裝在192.168.66.102上面
    1)先安裝Docker并啟動Docker(已完成)
    參考之前的安裝過程
    2)先安裝docker-compose

    sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/dockercompose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose

    3)給docker-compose添加執(zhí)行權(quán)限

    sudo chmod +x /usr/local/bin/docker-compose

    4)查看docker-compose是否安裝成功

    docker-compose -version

    5)下載Harbor的壓縮包(本課程版本為:v1.9.2)

    https://github.com/goharbor/harbor/releases

    6)上傳壓縮包到linux,并解壓

    tar -xzf harbor-offline-installer-v1.9.2.tgz mkdir /opt/harbor mv harbor/* /opt/harbor cd /opt/harbor

    7)修改Harbor的配置

    vi harbor.yml

    修改hostname和port

    hostname: 192.168.66.102 port: 85

    8)安裝Harbor

    ./prepare ./install.sh

    9)啟動Harbor

    docker-compose up -d 啟動 docker-compose stop 停止 docker-compose restart 重新啟動

    10)訪問Harbor
    http://192.168.66.102:85
    默認(rèn)賬戶密碼:admin/Harbor12345

    在Harbor創(chuàng)建用戶和項(xiàng)目

    1)創(chuàng)建項(xiàng)目
    Harbor的項(xiàng)目分為公開和私有的:
    公開項(xiàng)目:所有用戶都可以訪問,通常存放公共的鏡像,默認(rèn)有一個library公開項(xiàng)目。
    私有項(xiàng)目:只有授權(quán)用戶才可以訪問,通常存放項(xiàng)目本身的鏡像。

    把鏡像上傳到Harbor

    1)給鏡像打上標(biāo)簽

    docker tag eureka:v1 192.168.66.102:85/tensquare/eureka:v1

    2)推送鏡像

    docker push 192.168.66.102:85/tensquare/eureka:v1


    3)把Harbor地址加入到Docker信任列表

    vi /etc/docker/daemon.json { "registry-mirrors": ["https://zydiol88.mirror.aliyuncs.com"], "insecure-registries": ["192.168.66.102:85"] }

    需要重啟Docker
    4)再次執(zhí)行推送命令,會提示權(quán)限不足

    denied: requested access to the resource is denied

    需要先登錄Harbor,再推送鏡像
    5)登錄Harbor

    docker login -u 用戶名 -p 密碼 192.168.66.102:85

    從Harbor下載鏡像

    微服務(wù)持續(xù)集成(1)-項(xiàng)目代碼上傳到Gitlab

    在IDEA操作即可,參考之前的步驟。包括后臺微服務(wù)和前端web網(wǎng)站代碼

    微服務(wù)持續(xù)集成(2)-從Gitlab拉取項(xiàng)目源碼

    1)創(chuàng)建Jenkinsfile文件

    //gitlab的憑證 def git_auth = "68f2087f-a034-4d39-a9ff-1f776dd3dfa8" node { stage('拉取代碼') { checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: 'git@192.168.66.100:itheima_group/tensquare_back.git']]]) } }

    2)拉取Jenkinsfile文件

    微服務(wù)持續(xù)集成(3)-提交到SonarQube代碼審查

    1)創(chuàng)建項(xiàng)目,并設(shè)置參數(shù)
    創(chuàng)建tensquare_back項(xiàng)目,添加兩個參數(shù)

    2)每個項(xiàng)目的根目錄下添加sonar-project.properties

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

    注意:修改sonar.projectKey和sonar.projectName
    3)修改Jenkinsfile構(gòu)建腳本

    //gitlab的憑證 def git_auth = "68f2087f-a034-4d39-a9ff-1f776dd3dfa8" //構(gòu)建版本的名稱 def tag = "latest" node { stage('拉取代碼') { checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: 'git@192.168.66.100:itheima_group/tensquare_back.git']]]) } stage('代碼審查') { def scannerHome = tool 'sonarqube-scanner' withSonarQubeEnv('sonarqube6.7.4') { sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """ } } }

    微服務(wù)持續(xù)集成(4)-使用Dockerfile編譯、生成鏡像

    利用dockerfile-maven-plugin插件構(gòu)建Docker鏡像
    1)在每個微服務(wù)項(xiàng)目的pom.xml加入dockerfile-maven-plugin插件

    <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.3.6</version> <configuration> <repository>${project.artifactId}</repository> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin>

    2)在每個微服務(wù)項(xiàng)目根目錄下建立Dockerfile文件

    #FROM java:8 FROM openjdk:8-jdk-alpine ARG JAR_FILE COPY ${JAR_FILE} app.jar EXPOSE 10086 ENTRYPOINT ["java","-jar","/app.jar"]

    注意:每個項(xiàng)目公開的端口不一樣
    3)修改Jenkinsfile構(gòu)建腳本

    //gitlab的憑證 def git_auth = "68f2087f-a034-4d39-a9ff-1f776dd3dfa8" //構(gòu)建版本的名稱 def tag = "latest" //Harbor私服地址 def harbor_url = "192.168.66.102:85/tensquare/" node { stage('拉取代碼') { checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: 'git@192.168.66.100:itheima_group/tensquare_back.git']]]) } stage('代碼審查') { def scannerHome = tool 'sonarqube-scanner' withSonarQubeEnv('sonarqube6.7.4') { sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """ } } stage('編譯,構(gòu)建鏡像') { //定義鏡像名稱 def imageName = "${project_name}:${tag}" //編譯,安裝公共工程 sh "mvn -f tensquare_common clean install" //編譯,構(gòu)建本地鏡像 sh "mvn -f ${project_name} clean package dockerfile:build" } }

    注意:如果出現(xiàn)找不到父工程依賴,需要手動把父工程的依賴上傳到倉庫中

    微服務(wù)持續(xù)集成(5)-上傳到Harbor鏡像倉庫

    1)修改Jenkinsfile構(gòu)建腳本

    //gitlab的憑證 def git_auth = "68f2087f-a034-4d39-a9ff-1f776dd3dfa8" //構(gòu)建版本的名稱 def tag = "latest" //Harbor私服地址 def harbor_url = "192.168.66.102:85" //Harbor的項(xiàng)目名稱 def harbor_project_name = "tensquare" //Harbor的憑證 def harbor_auth = "ef499f29-f138-44dd-975e-ff1ca1d8c933" node { stage('拉取代碼') { checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: 'git@192.168.66.100:itheima_group/tensquare_back.git']]]) } stage('代碼審查') { def scannerHome = tool 'sonarqube-scanner' withSonarQubeEnv('sonarqube6.7.4') { sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """ } } stage('編譯,構(gòu)建鏡像') { //定義鏡像名稱 def imageName = "${project_name}:${tag}" //編譯,安裝公共工程 sh "mvn -f tensquare_common clean install" //編譯,構(gòu)建本地鏡像 sh "mvn -f ${project_name} clean package dockerfile:build" //給鏡像打標(biāo)簽 sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}" //登錄Harbor,并上傳鏡像 withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) { //登錄 sh "docker login -u ${username} -p ${password} ${harbor_url}" //上傳鏡像 sh "docker push ${harbor_url}/${harbor_project_name}/${imageName}" } //刪除本地鏡像 sh "docker rmi -f ${imageName}" sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${imageName}" } }

    2)使用憑證管理Harbor私服賬戶和密碼
    先在憑證建立Harbor的憑證,在生成憑證腳本代碼

    微服務(wù)持續(xù)集成(6)-拉取鏡像和發(fā)布應(yīng)用


    注意:192.168.66.103服務(wù)已經(jīng)安裝Docker并啟動

    安裝 Publish Over SSH 插件

    安裝以下插件,可以實(shí)現(xiàn)遠(yuǎn)程發(fā)送Shell命令

    配置遠(yuǎn)程部署服務(wù)器

    1)拷貝公鑰到遠(yuǎn)程服務(wù)器

    ssh-copy-id 192.168.66.103

    2)系統(tǒng)配置->添加遠(yuǎn)程服務(wù)器

    修改Jenkinsfile構(gòu)建腳本

    生成遠(yuǎn)程調(diào)用模板代碼

    添加一個port參數(shù)

    //gitlab的憑證 def git_auth = "68f2087f-a034-4d39-a9ff-1f776dd3dfa8" //構(gòu)建版本的名稱 def tag = "latest" //Harbor私服地址 def harbor_url = "192.168.66.102:85" //Harbor的項(xiàng)目名稱 def harbor_project_name = "tensquare" //Harbor的憑證 def harbor_auth = "ef499f29-f138-44dd-975e-ff1ca1d8c933" node { stage('拉取代碼') { checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: 'git@192.168.66.100:itheima_group/tensquare_back.git']]]) } stage('代碼審查') { def scannerHome = tool 'sonarqube-scanner' withSonarQubeEnv('sonarqube6.7.4') { sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """ } } stage('編譯,構(gòu)建鏡像,部署服務(wù)') { //定義鏡像名稱 def imageName = "${project_name}:${tag}" //編譯并安裝公共工程 sh "mvn -f tensquare_common clean install" //編譯,構(gòu)建本地鏡像 sh "mvn -f ${project_name} clean package dockerfile:build" //給鏡像打標(biāo)簽 sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}" //登錄Harbor,并上傳鏡像 withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) { //登錄 sh "docker login -u ${username} -p ${password} ${harbor_url}" //上傳鏡像 sh "docker push ${harbor_url}/${harbor_project_name}/${imageName}" } //刪除本地鏡像 sh "docker rmi -f ${imageName}" sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${imageName}" //=====以下為遠(yuǎn)程調(diào)用進(jìn)行項(xiàng)目部署======== sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/jenkins_shell/deploy.sh $harbor_url $harbor_project_name $project_name $tag $port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } }

    編寫deploy.sh部署腳本

    #! /bin/sh #接收外部參數(shù) harbor_url=$1 harbor_project_name=$2 project_name=$3 tag=$4 port=$5 imageName=$harbor_url/$harbor_project_name/$project_name:$tag echo "$imageName" #查詢?nèi)萜魇欠翊嬖?#xff0c;存在則刪除 containerId=`docker ps -a | grep -w ${project_name}:${tag} | awk '{print $1}'` if [ "$containerId" != "" ] ; then #停掉容器 docker stop $containerId #刪除容器 docker rm $containerId echo "成功刪除容器" fi #查詢鏡像是否存在,存在則刪除 imageId=`docker images | grep -w $project_name | awk '{print $3}'` if [ "$imageId" != "" ] ; then #刪除鏡像 docker rmi -f $imageId echo "成功刪除鏡像" fi # 登錄Harbor私服 docker login -u itcast -p Itcast123 $harbor_url # 下載鏡像 docker pull $imageName # 啟動容器 docker run -di -p $port:$port $imageName echo "容器啟動成功"

    上傳deploy.sh文件到/opt/jenkins_shell目錄下,且文件至少有執(zhí)行權(quán)限!

    chmod +x deploy.sh 添加執(zhí)行權(quán)限

    導(dǎo)入數(shù)據(jù),測試微服務(wù)

    微服務(wù)持續(xù)集成(7)-部署前端靜態(tài)web網(wǎng)站


    安裝Nginx服務(wù)器

    yum install epel-release yum -y install nginx 安裝

    修改nginx的端口,默認(rèn)80,改為9090:

    vi /etc/nginx/nginx.conf server { listen 9090 default_server; listen [::]:9090 default_server; server_name _; root /usr/share/nginx/html;

    還需要關(guān)閉selinux,將SELINUX=disabled

    setenforce 0 先臨時關(guān)閉 vi /etc/selinux/config 編輯文件,永久關(guān)閉 SELINUX=disabled

    啟動Nginx

    systemctl enable nginx 設(shè)置開機(jī)啟動 systemctl start nginx 啟動 systemctl stop nginx 停止 systemctl restart nginx 重啟

    訪問:http://192.168.66.103:9090/

    安裝NodeJS插件

    Jenkins配置Nginx服務(wù)器

    Manage Jenkins->Global Tool Configuration

    創(chuàng)建前端流水線項(xiàng)目


    建立Jenkinsfile構(gòu)建腳本

    //gitlab的憑證 def git_auth = "68f2087f-a034-4d39-a9ff-1f776dd3dfa8" node { stage('拉取代碼') { checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: 'git@192.168.66.100:itheima_group/tensquare_front.git']]]) } stage('打包,部署網(wǎng)站') { //使用NodeJS的npm進(jìn)行打包 nodejs('nodejs12'){ sh ''' npm install npm run build ''' } //=====以下為遠(yuǎn)程調(diào)用進(jìn)行項(xiàng)目部署======== sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/usr/share/nginx/html', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } }

    完成后,訪問:http://192.168.66.103:9090 進(jìn)行測試。

    5、Jenkins+Docker+SpringCloud微服務(wù)持續(xù)集成(下)

    Jenkins+Docker+SpringCloud部署方案優(yōu)化

    上面部署方案存在的問題:
    1)一次只能選擇一個微服務(wù)部署
    2)只有一臺生產(chǎn)者部署服務(wù)器
    3)每個微服務(wù)只有一個實(shí)例,容錯率低
    優(yōu)化方案:
    1)在一個Jenkins工程中可以選擇多個微服務(wù)同時發(fā)布
    2)在一個Jenkins工程中可以選擇多臺生產(chǎn)服務(wù)器同時部署
    3)每個微服務(wù)都是以集群高可用形式部署

    Jenkins+Docker+SpringCloud集群部署流程說明

    修改所有微服務(wù)配置

    注冊中心配置(*)
    yml 文件,下面配置代碼錯誤,沒有縮進(jìn)

    # 集群版 spring: application: name: EUREKA-HA --- server: port: 10086 spring: # 指定profile=eureka-server1 profiles: eureka-server1 eureka: instance: # 指定當(dāng)profile=eureka-server1時,主機(jī)名是eureka-server1 hostname: 192.168.66.103 client service-url: # 將自己注冊到eureka-server1、eureka-server2這個Eureka上面去 defaultZone: http://192.168.66.103:10086/eureka/,http://192.168.66.104:10086/eureka/ --- server: port: 10086 spring: profiles: eureka-server2 eureka: instance: hostname: 192.168.66.104 client: service-url: defaultZone: http://192.168.66.103:10086/eureka/,http://192.168.66.104:10086/eureka/

    在啟動微服務(wù)的時候,加入?yún)?shù): spring.profiles.active 來讀取對應(yīng)的配置

    其他微服務(wù)配置

    除了Eureka注冊中心以外,其他微服務(wù)配置都需要加入所有Eureka服務(wù)

    # Eureka配置 eureka: client: service-url: defaultZone: http://192.168.66.103:10086/eureka,http://192.168.66.104:10086/eureka # Eureka訪 問地址 instance: prefer-ip-address: true

    把代碼提交到Gitlab中

    設(shè)計Jenkins集群項(xiàng)目的構(gòu)建參數(shù)

    1)安裝Extended Choice Parameter插件
    支持多選框

    2)創(chuàng)建流水線項(xiàng)目

    3)添加參數(shù)
    字符串參數(shù):分支名稱

    多選框:項(xiàng)目名稱

    tensquare_eureka_server@10086,tensquare_zuul@10020,tensquare_admin_service@9001, tensquare_gathering@9002


    最后效果:

    完成微服務(wù)構(gòu)建鏡像,上傳私服

    //gitlab的憑證 def git_auth = "68f2087f-a034-4d39-a9ff-1f776dd3dfa8" //構(gòu)建版本的名稱 def tag = "latest" //Harbor私服地址 def harbor_url = "192.168.66.102:85" //Harbor的項(xiàng)目名稱 def harbor_project_name = "tensquare" //Harbor的憑證 def harbor_auth = "ef499f29-f138-44dd-975e-ff1ca1d8c933" node { //把選擇的項(xiàng)目信息轉(zhuǎn)為數(shù)組 def selectedProjects = "${project_name}".split(',') stage('拉取代碼') { checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '${git_auth}', url: 'git@192.168.66.100:itheima_group/tensquare_back_cluster.git']]]) } stage('代碼審查') { def scannerHome = tool 'sonarqube-scanner' withSonarQubeEnv('sonarqube6.7.4') { for(int i=0;i<selectedProjects.size();i++){ //取出每個項(xiàng)目的名稱和端口 def currentProject = selectedProjects[i]; //項(xiàng)目名稱 def currentProjectName = currentProject.split('@')[0] //項(xiàng)目啟動端口 def currentProjectPort = currentProject.split('@')[1] sh """ cd ${currentProjectName} ${scannerHome}/bin/sonar-scanner """ echo "${currentProjectName}完成代碼審查" } } } stage('編譯,構(gòu)建鏡像,部署服務(wù)') { //編譯并安裝公共工程 sh "mvn -f tensquare_common clean install" for(int i=0;i<selectedProjects.size();i++){ //取出每個項(xiàng)目的名稱和端口 def currentProject = selectedProjects[i]; //項(xiàng)目名稱 def currentProjectName = currentProject.split('@')[0] //項(xiàng)目啟動端口 def currentProjectPort = currentProject.split('@')[1] //定義鏡像名稱 def imageName = "${currentProjectName}:${tag}" //編譯,構(gòu)建本地鏡像 sh "mvn -f ${currentProjectName} clean package dockerfile:build" //給鏡像打標(biāo)簽 sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}" //登錄Harbor,并上傳鏡像 withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) { //登錄 sh "docker login -u ${username} -p ${password} ${harbor_url}" //上傳鏡像 sh "docker push ${harbor_url}/${harbor_project_name}/${imageName}" } //刪除本地鏡像 sh "docker rmi -f ${imageName}" sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${imageName}" //=====以下為遠(yuǎn)程調(diào)用進(jìn)行項(xiàng)目部署======== //sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/jenkins_shell/deployCluster.sh $harbor_url $harbor_project_name $currentProjectName $tag $currentProjectPort", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) echo "${currentProjectName}完成編譯,構(gòu)建鏡像" } } }

    完成微服務(wù)多服務(wù)器遠(yuǎn)程發(fā)布

    1)配置遠(yuǎn)程部署服務(wù)器
    拷貝公鑰到遠(yuǎn)程服務(wù)器

    ssh-copy-id 192.168.66.104

    系統(tǒng)配置->添加遠(yuǎn)程服務(wù)器

    2)修改Docker配置信任Harbor私服地址

    { "registry-mirrors": ["https://zydiol88.mirror.aliyuncs.com"], "insecure-registries": ["192.168.66.102:85"] }

    重啟Docker
    3)添加參數(shù)
    多選框:部署服務(wù)器


    最終效果:

    4)修改Jenkinsfile構(gòu)建腳本

    //gitlab的憑證 def git_auth = "68f2087f-a034-4d39-a9ff-1f776dd3dfa8" //構(gòu)建版本的名稱 def tag = "latest" //Harbor私服地址 def harbor_url = "192.168.66.102:85" //Harbor的項(xiàng)目名稱 def harbor_project_name = "tensquare" //Harbor的憑證 def harbor_auth = "ef499f29-f138-44dd-975e-ff1ca1d8c933" node { //把選擇的項(xiàng)目信息轉(zhuǎn)為數(shù)組 def selectedProjects = "${project_name}".split(',') //把選擇的服務(wù)區(qū)信息轉(zhuǎn)為數(shù)組 def selectedServers = "${publish_server}".split(',') stage('拉取代碼') { checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '${git_auth}', url: 'git@192.168.66.100:itheima_group/tensquare_back_cluster.git']]]) } stage('代碼審查') { def scannerHome = tool 'sonarqube-scanner' withSonarQubeEnv('sonarqube6.7.4') { for(int i=0;i<selectedProjects.size();i++){ //取出每個項(xiàng)目的名稱和端口 def currentProject = selectedProjects[i]; //項(xiàng)目名稱 def currentProjectName = currentProject.split('@')[0] //項(xiàng)目啟動端口 def currentProjectPort = currentProject.split('@')[1] sh """ cd ${currentProjectName} ${scannerHome}/bin/sonar-scanner """ echo "${currentProjectName}完成代碼審查" } } } stage('編譯,構(gòu)建鏡像,部署服務(wù)') { //編譯并安裝公共工程 sh "mvn -f tensquare_common clean install" for(int i=0;i<selectedProjects.size();i++){ //取出每個項(xiàng)目的名稱和端口 def currentProject = selectedProjects[i]; //項(xiàng)目名稱 def currentProjectName = currentProject.split('@')[0] //項(xiàng)目啟動端口 def currentProjectPort = currentProject.split('@')[1] //定義鏡像名稱 def imageName = "${currentProjectName}:${tag}" //編譯,構(gòu)建本地鏡像 sh "mvn -f ${currentProjectName} clean package dockerfile:build" //給鏡像打標(biāo)簽 sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}" //登錄Harbor,并上傳鏡像 withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) { //登錄 sh "docker login -u ${username} -p ${password} ${harbor_url}" //上傳鏡像 sh "docker push ${harbor_url}/${harbor_project_name}/${imageName}" } //刪除本地鏡像 sh "docker rmi -f ${imageName}" sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${imageName}" //=====以下為遠(yuǎn)程調(diào)用進(jìn)行項(xiàng)目部署======== for(int j=0;j<selectedServers.size();j++){ //每個服務(wù)名稱 def currentServer = selectedServers[j] //添加微服務(wù)運(yùn)行時的參數(shù):spring.profiles.active def activeProfile = "--spring.profiles.active=" if(currentServer=="master_server"){ activeProfile = activeProfile+"eureka-server1" }else if(currentServer=="slave_server1"){ activeProfile = activeProfile+"eureka-server2" } sshPublisher(publishers: [sshPublisherDesc(configName: "${currentServer}", transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/jenkins_shell/deployCluster.sh $harbor_url $harbor_project_name $currentProjectName $tag $currentProjectPort $activeProfile", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } echo "${currentProjectName}完成編譯,構(gòu)建鏡像" } } }

    5)編寫deployCluster.sh部署腳本

    #! /bin/sh #接收外部參數(shù) harbor_url=$1 harbor_project_name=$2 project_name=$3 tag=$4 port=$5 profile=$6 imageName=$harbor_url/$harbor_project_name/$project_name:$tag echo "$imageName" #查詢?nèi)萜魇欠翊嬖?#xff0c;存在則刪除 containerId=`docker ps -a | grep -w ${project_name}:${tag} | awk '{print $1}'` if [ "$containerId" != "" ] ; then #停掉容器 docker stop $containerId #刪除容器 docker rm $containerId echo "成功刪除容器" fi #查詢鏡像是否存在,存在則刪除 imageId=`docker images | grep -w $project_name | awk '{print $3}'` if [ "$imageId" != "" ] ; then #刪除鏡像 docker rmi -f $imageId echo "成功刪除鏡像" fi # 登錄Harbor私服 docker login -u itcast -p Itcast123 $harbor_url # 下載鏡像 docker pull $imageName # 啟動容器 docker run -di -p $port:$port $imageName $profile echo "容器啟動成功"

    6)集群效果

    Nginx+Zuul集群實(shí)現(xiàn)高可用網(wǎng)關(guān)


    1)安裝Nginx(已完成)
    2)修改Nginx配置

    vi /etc/nginx/nginx.conf

    內(nèi)容如下:

    upstream zuulServer{ server 192.168.66.103:10020 weight=1; server 192.168.66.104:10020 weight=1; } server { listen 85 default_server; listen [::]:85 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { ### 指定服務(wù)器負(fù)載均衡服務(wù)器 proxy_pass http://zuulServer/; }

    3)重啟Nginx: systemctl restart nginx
    4)修改前端Nginx的訪問地址

    6、基于Kubernetes/K8S構(gòu)建Jenkins持續(xù)集成平臺(上)

    Jenkins的Master-Slave分布式構(gòu)建

    什么是Master-Slave分布式構(gòu)建

    Jenkins的Master-Slave分布式構(gòu)建,就是通過將構(gòu)建過程分配到從屬Slave節(jié)點(diǎn)上,從而減輕Master節(jié)
    點(diǎn)的壓力,而且可以同時構(gòu)建多個,有點(diǎn)類似負(fù)載均衡的概念。

    如何實(shí)現(xiàn)Master-Slave分布式構(gòu)建

    1)開啟代理程序的TCP端口
    Manage Jenkins -> Configure Global Security

    2)新建節(jié)點(diǎn)
    Manage Jenkins—Manage Nodes—新建節(jié)點(diǎn)


    有兩種在Slave節(jié)點(diǎn)連接Master節(jié)點(diǎn)的方法

    我們選擇第二種:
    2)安裝和配置節(jié)點(diǎn)
    下載agent.jar,并上傳到Slave節(jié)點(diǎn),然后執(zhí)行頁面提示的命令:

    java -jar agent.jar -jnlpUrl http://192.168.66.101:8888/computer/slave1/slaveagent.jnlp -secret f2ecbb99e0c81331e8b7a7917a94d478f39cb9763fc6c66d9a9741c61f9ae6d6 -workDir "/root/jenkins"

    刷新頁面

    3)測試節(jié)點(diǎn)是否可用
    自由風(fēng)格和Maven風(fēng)格的項(xiàng)目:

    流水線風(fēng)格的項(xiàng)目:

    node('slave1') { stage('check out') { checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '68f2087f-a034-4d39-a9ff-1f776dd3dfa8', url: 'git@192.168.66.100:itheima_group/tensquare_back_cluster.git']]]) } }

    Kubernetes實(shí)現(xiàn)Master-Slave分布式構(gòu)建方案

    傳統(tǒng)Jenkins的Master-Slave方案的缺陷

    Master節(jié)點(diǎn)發(fā)生單點(diǎn)故障時,整個流程都不可用了
    每個 Slave節(jié)點(diǎn)的配置環(huán)境不一樣,來完成不同語言的編譯打包等操作,但是這些差異化的配置導(dǎo)
    致管理起來非常不方便,維護(hù)起來也是比較費(fèi)勁
    資源分配不均衡,有的 Slave節(jié)點(diǎn)要運(yùn)行的job出現(xiàn)排隊(duì)等待,而有的Slave節(jié)點(diǎn)處于空閑狀態(tài)
    資源浪費(fèi),每臺 Slave節(jié)點(diǎn)可能是實(shí)體機(jī)或者VM,當(dāng)Slave節(jié)點(diǎn)處于空閑狀態(tài)時,也不會完全釋放
    掉資源
    以上種種問題,我們可以引入Kubernates來解決!

    Kubernates簡介

    Kubernetes(簡稱,K8S)是Google開源的容器集群管理系統(tǒng),在Docker技術(shù)的基礎(chǔ)上,為容器化的
    應(yīng)用提供部署運(yùn)行、資源調(diào)度、服務(wù)發(fā)現(xiàn)和動態(tài)伸縮等一系列完整功能,提高了大規(guī)模容器集群管理的
    便捷性。 其主要功能如下:
    使用Docker對應(yīng)用程序包裝(package)、實(shí)例化(instantiate)、運(yùn)行(run)。
    以集群的方式運(yùn)行、管理跨機(jī)器的容器。以集群的方式運(yùn)行、管理跨機(jī)器的容器。
    解決Docker跨機(jī)器容器之間的通訊問題。解決Docker跨機(jī)器容器之間的通訊問題。
    Kubernetes的自我修復(fù)機(jī)制使得容器集群總是運(yùn)行在用戶期望的狀態(tài)。

    Kubernates+Docker+Jenkins持續(xù)集成架構(gòu)圖


    大致工作流程:手動/自動構(gòu)建 -> Jenkins 調(diào)度 K8S API ->動態(tài)生成 Jenkins Slave pod -> Slave pod
    拉取 Git 代碼/編譯/打包鏡像 ->推送到鏡像倉庫 Harbor -> Slave 工作完成,Pod 自動銷毀 ->部署
    到測試或生產(chǎn) Kubernetes平臺。(完全自動化,無需人工干預(yù))

    Kubernates+Docker+Jenkins持續(xù)集成方案好處

    服務(wù)高可用:
    當(dāng) Jenkins Master 出現(xiàn)故障時,Kubernetes 會自動創(chuàng)建一個新的 Jenkins Master容器,并且將 Volume 分配給新創(chuàng)建的容器,保證數(shù)據(jù)不丟失,從而達(dá)到集群服務(wù)高可用。

    動態(tài)伸縮,合理使用資源:
    每次運(yùn)行 Job 時,會自動創(chuàng)建一個 Jenkins Slave,Job 完成后,Slave自動注銷并刪除容器,資源自動釋放,而且 Kubernetes 會根據(jù)每個資源的使用情況,動態(tài)分配Slave 到空閑的節(jié)點(diǎn)上創(chuàng)建,降低出現(xiàn)因某節(jié)點(diǎn)資源利用率高,還排隊(duì)等待在該節(jié)點(diǎn)的情況。

    擴(kuò)展性好:
    當(dāng) Kubernetes 集群的資源嚴(yán)重不足而導(dǎo)致 Job 排隊(duì)等待時,可以很容易的添加一個Kubernetes Node 到集群中,從而實(shí)現(xiàn)擴(kuò)展。

    Kubeadm安裝Kubernetes

    Kubernetes的架構(gòu)


    API Server:用于暴露Kubernetes API,任何資源的請求的調(diào)用操作都是通過kube-apiserver提供的接口進(jìn)行的。

    Etcd:是Kubernetes提供默認(rèn)的存儲系統(tǒng),保存所有集群數(shù)據(jù),使用時需要為etcd數(shù)據(jù)提供備份計
    劃。

    Controller-Manager:作為集群內(nèi)部的管理控制中心,負(fù)責(zé)集群內(nèi)的Node、Pod副本、服務(wù)端點(diǎn)(Endpoint)、命名空間(Namespace)、服務(wù)賬號(ServiceAccount)、資源定額(ResourceQuota)的管理,當(dāng)某個Node意外宕機(jī)時,Controller Manager會及時發(fā)現(xiàn)并執(zhí)行自動化修復(fù)流程,確保集群始終處于預(yù)期的工作狀態(tài)。

    Scheduler:監(jiān)視新創(chuàng)建沒有分配到Node的Pod,為Pod選擇一個Node。

    Kubelet:負(fù)責(zé)維護(hù)容器的生命周期,同時負(fù)責(zé)Volume和網(wǎng)絡(luò)的管理

    Kube proxy:是Kubernetes的核心組件,部署在每個Node節(jié)點(diǎn)上,它是實(shí)現(xiàn)Kubernetes Service的通信與負(fù)載均衡機(jī)制的重要組件。
    安裝環(huán)境說明

    總結(jié)

    以上是生活随笔為你收集整理的Jenkins-自动化构建、测试和部署-学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。