DevOps
DevOps概述
軟件開發(fā)最初是由兩個團(tuán)隊共同組成:(沒有采用DevOps之前)
- 開發(fā)團(tuán)隊:從頭開始設(shè)計和整體系統(tǒng)的構(gòu)建(編寫代碼)。需要系統(tǒng)不停的迭代更新。
- 運維團(tuán)隊:將開發(fā)團(tuán)隊的代碼進(jìn)行測試通過后再部署上線。確保系統(tǒng)穩(wěn)定運行。
沒有采用DevOps的缺點:
- 這看似兩個目標(biāo)不同的團(tuán)隊需要協(xié)同完成一個軟件的開發(fā)。在開發(fā)團(tuán)隊指定好計劃并完成編寫代碼后,需要把代碼交給運維團(tuán)隊。運維團(tuán)隊向開發(fā)團(tuán)隊反饋需要修復(fù)的BUG以及一些需要返工的任務(wù)。這時開發(fā)團(tuán)隊需要經(jīng)常等待運維團(tuán)隊的反饋。這無疑會延長整個軟件開發(fā)的周期。
采用DevOps的優(yōu)點?
- DevOps的方式可以讓公司能夠更快地應(yīng)對更新和市場發(fā)展變化,開發(fā)可以快速交付,部署也更加穩(wěn)定。核心就在于簡化Dev和Ops團(tuán)隊之間的流程,使整體軟件開發(fā)過程更快速。說白了就是DevOps有利于快速完成項目,不會浪費時間)
整體的軟件開發(fā)流程:
- PLAN:開發(fā)團(tuán)隊根據(jù)客戶的目標(biāo)制定開發(fā)計劃
- CODE:根據(jù)PLAN開始編碼過程,需要將不同版本的代碼存儲在一個庫中。
- BUILD:編碼完成后,需要將代碼構(gòu)建并且運行。
- TEST:成功構(gòu)建項目后,需要測試代碼是否存在BUG或錯誤。
- DEPLOY:代碼經(jīng)過手動測試和自動化測試后,認(rèn)定代碼已經(jīng)準(zhǔn)備好部署并且交給運維團(tuán)隊。
- OPERATE:運維團(tuán)隊將代碼部署到生產(chǎn)環(huán)境中。
- MONITOR:項目部署上線后,需要持續(xù)的監(jiān)控產(chǎn)品。
- INTEGRATE:然后將監(jiān)控階段收到的反饋發(fā)送回PLAN階段,整體反復(fù)的流程就是DevOps的核心,即持續(xù)集成、持續(xù)部署。
為了保證整體流程可以高效的完成,各個階段都有比較常見的工具,如下圖:
Jenkins流水線任務(wù)入門?
Jenkins流水線任務(wù)的Hello World體驗?
Jenkins流水線語法例子
// 所有腳本命令包含在pipeline{}中
pipeline {
// 指定任務(wù)在哪個Jenkins集群節(jié)點中執(zhí)行(Jenkins是支持分布式)
// 這里的agent any是指該任務(wù)可以在任何Jenkins集群節(jié)點上執(zhí)行。
agent any
// 聲明全局變量,格式為:key='value'
environment{
host = '192.168.184.80'
}
// 存放所有任務(wù)的合集
stages {
// 單個任務(wù)1
stage('任務(wù)1') {
// 實現(xiàn)任務(wù)的具體流程
steps {
echo '做任務(wù)1'
}
}
// 單個任務(wù)2
stage('任務(wù)2') {
// 實現(xiàn)任務(wù)的具體流程
steps {
echo '做任務(wù)2'
}
}
// 單個任務(wù)3
stage('任務(wù)3') {
// 實現(xiàn)任務(wù)的具體流程
steps {
echo '做任務(wù)3'
}
}
}
}
Jenkins流水線語法生成器?
Jenkins實戰(zhàn)4:構(gòu)建pipeline(流水線)的Jenkins項目?
項目架構(gòu)圖
Jenkins實戰(zhàn)4的初步流水線模板(功能全部都未實現(xiàn))?
pipeline {
agent any
// 存放所有任務(wù)的集合
stages {
stage('拉取Git倉庫代碼') {
steps {
echo '拉取Git倉庫代碼 - SUCCESS'
}
}
stage('通過maven構(gòu)建項目') {
steps {
echo '通過maven構(gòu)建項目 - SUCCESS'
}
}
stage('通過SonarQube做代碼質(zhì)量檢測') {
steps {
echo '通過SonarQube做代碼質(zhì)量檢測 - SUCCESS'
}
}
stage('通過Docker制作自定義鏡像') {
steps {
echo '通過Docker制作自定義鏡像 - SUCCESS'
}
}
stage('將自定義鏡像推送到Harbor倉庫') {
steps {
echo '將自定義鏡像推送到Harbor倉庫 - SUCCESS'
}
}
stage('通過Publish Over SSH通知目標(biāo)服務(wù)器') {
steps {
echo '通過Publish Over SSH通知目標(biāo)服務(wù)器 - SUCCESS'
}
}
}
}
Jenkinsfile配置?
在項目中編寫Jenkinsfile來維護(hù)pipeline模板(以后我們的pipeline語法都放在這個文件上)?
- 注意:該文件名一定要為:Jenkinsfile
- Jenkinsfile文件內(nèi)容放在了上面,可以直接復(fù)制!
在Jenkins中配置Jenkinsfile在gitlab上的地址?
測試構(gòu)建,看看Jenkinsfile是否能生效
架構(gòu)圖第2步案例:將gitlab上面的項目代碼拉取到Jenkins中?
-
1:配置git參數(shù):(根據(jù)tag去拉取代碼)
-
2:生成拉取git代碼的流水線語法:
- 生成的語法代碼塊如下:(注意:下面有個地方(branches的name從原來是/main被我改成了${tag},如果安裝默認(rèn)生成的話,則是拉取最新版本代碼,我們這個意思就是安裝tag去拉取對應(yīng)代碼)和系統(tǒng)生成的語法不一樣!?。?/em>*
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.184.70:8929/root/mytest.git']]])
- 3:把生成的pipeline語法放到Jenkinsfile文件的指定位置:
- 4:測試構(gòu)建:
架構(gòu)圖第3步案例:利用Maven構(gòu)建項目的jar包?
-
1:生成流水線語法:(生成如下)
- 注意:/var/jenkins_home/maven/bin/mvn要改成你的maven的mvn地址。
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
- 2:將上面生成的語法放到Jenkinsfile的對應(yīng)位置上去,然后上傳到gitlab即可。(省略?。?/strong>
架構(gòu)圖第4步案例:給Jenkins的pipeline任務(wù)配置SonarQube自動進(jìn)行代碼質(zhì)量檢測?
-
1:生成流水線語法:(生成如下)
- 注意:下面的-Dsonar.login要用自己的SonarQube的token
- 注意:/var/jenkins_home/sonar-scanner/bin/sonar-scanner要改成你的sonar-scanner地址
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7ad2200f7cca90c37a909fdba8db049ac700909f'
- 2:將上面生成的語法放到Jenkinsfile的對應(yīng)位置上去,然后上傳到gitlab即可。(省略!)
架構(gòu)圖第5步案例:Jenkins制作自定義鏡像并上傳到Harbor?
- 1:生成制作自定義鏡像的流水線語法(生成如下):
sh '''mv ./target/*.jar ./docker/
docker build -t ${JOB_NAME}:${tag} ./docker/'''
-
2:在Jenkinsfile文件定義全局變量environment:(記得要把下面的內(nèi)容改成你自己的?。?/strong>
- harborAddress是harbor地址
- harborRepo是harbor倉庫名
- harborUser是harbor賬號
- harborPasswd是Harbor密碼
environment{
harborAddress = '192.168.184.80:80'
harborRepo = 'repo'
harborUser = 'admin'
harborPasswd = 'Harbor12345'
}
- 3:生成將鏡像上傳到Harbor倉庫的流水線語法(生成如下):
sh '''docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}'''
-
4:防止Jenkins內(nèi)部不能使用Docker,所以重新設(shè)置一下權(quán)限:(有時候即使設(shè)置了權(quán)限也會自動變回來,導(dǎo)致pipeline報錯)
- 切換目錄到/var/run/:
[root@centos7-jenkins harbor]# cd /var/run/
- 修改docker.sock文件的所屬組:
[root@centos7-jenkins run]# chown root:root docker.sock
- 修改docker.sock文件的權(quán)限:
[root@centos7-jenkins run]# chmod o+rw docker.sock
-
5:將上面生成的語法放到Jenkinsfile的對應(yīng)位置上去,然后上傳到gitlab即可。
- 6:執(zhí)行構(gòu)建即可。
- 7:進(jìn)入Harbor可視化界面,查看pipeline鏡像是否push成功:
架構(gòu)圖第6-7步案例:通知目標(biāo)服務(wù)器可以從Harbor上拉取鏡像,并運行容器(注意:這里有個坑?。?
-
1:在所有目標(biāo)服務(wù)器上都放一份shell腳本文件:(原理是:Jenkins通知目標(biāo)服務(wù)器去執(zhí)行shell腳本文件,從而讓目標(biāo)服務(wù)器在Harbor上面拉取指定鏡像。)
- 原來的架構(gòu)圖上是把Dockerfile傳到目標(biāo)服務(wù)器,讓目標(biāo)服務(wù)器通過docker build構(gòu)建鏡像(缺點是當(dāng)目標(biāo)服務(wù)器有多臺,那每一臺目標(biāo)服務(wù)器都需要build構(gòu)建一次,n臺服務(wù)器就是n次,這樣十分浪費服務(wù)器資源)。
- 現(xiàn)在的架構(gòu)圖是把鏡像在Jenkins容器內(nèi)構(gòu)建,然后把鏡像push到Harbor上,Jenkins通知所有目標(biāo)服務(wù)器(不管有多少臺),然后目標(biāo)服務(wù)器就會執(zhí)行下面的shell腳本,會從Harbor拉取指定鏡像,這樣一來,不管有多少臺目標(biāo)服務(wù)器都只是build構(gòu)建一次,節(jié)省了很多資源。
vi /root/deploy.sh
內(nèi)容如下:
harbor_addr=$1
harbor_repo=$2
project=$3
version=$4
host_port=$5
container_port=$6
imageName=$harbor_addr/$harbor_repo/$project:$version
containerId=`docker ps -a | grep ${project} | awk '{print $1}'`
if [ "$containerId" != "" ] ; then
docker stop $containerId
docker rm $containerId
fi
tag=`docker images | grep ${project} | awk '{print $2}'`
if [[ "$tag" =~ "$version" ]] ; then
docker rmi -f $imageName
fi
docker login -u admin -p Harbor12345 $harbor_addr
docker pull $imageName
docker run -d -p $host_port:$container_port --name $project $imageName
echo "SUCCESS"
- 2:給deploy.sh權(quán)限:
chmod a+x /root/deploy.sh
- 3:把所有目標(biāo)服務(wù)器的deploy.sh都放到/usr/bin下:
[root@centos7-jenkins ~]# mv /root/deploy.sh /usr/bin/
- 4:配置Jenkins參數(shù):
-
5:生成流水線語法:
- 提示Exec command:
deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $host_port $container_port
-
6:將生成的語法放到Jenkinsfile的對應(yīng)位置上去,然后上傳到gitlab即可。(?注意這里有個坑!?)
- 坑坑坑?。。。簊shPublisher的execCommand要用雙引號,默認(rèn)是單引號。(一定要改成雙引號,否則語法無法生效!?)
?下面的是修改之后的,并且是測試通過的流水線語法!?。?/strong>
sshPublisher(publishers: [sshPublisherDesc(configName: 'mytest', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $host_port $container_port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
- 7:最后測試構(gòu)建即可(省略?。?/strong>
Jenkins流水線整合釘釘:在構(gòu)建完成后通知信息(新增?)
下載安裝釘釘,并且注冊賬號(電腦版和手機(jī)版都行)?
釘釘下載官網(wǎng)
在Jenkins中下載釘釘插件(DingTalk 2.4.7版本)?
在釘釘創(chuàng)建一個企業(yè)(不然無法申請項目群)?
在釘釘創(chuàng)建一個新的項目群?
在釘釘?shù)捻椖咳豪飫?chuàng)建一個機(jī)器人?
在Jenkins中配置這個機(jī)器人?
Jenkinsfile配置釘釘?
-
1:編寫流水線語法:
- 注意:robot的值就是我們在Jenkins的系統(tǒng)配置所設(shè)置的機(jī)器人id!?。ㄒ欢ㄒM(jìn)行修改)
post {
success {
dingtalk (
robot: 'Jenkins-dingding',
type:'MARKDOWN',
title: "success: ${JOB_NAME}",
text: ["- 成功構(gòu)建:${JOB_NAME}項目!\n- 版本:${tag}\n- 持續(xù)時間:${currentBuild.durationString}\n- 任務(wù):#${JOB_NAME}"]
)
}
failure {
dingtalk (
robot: 'Jenkins-dingding',
type:'MARKDOWN',
title: "fail: ${JOB_NAME}",
text: ["- 失敗構(gòu)建:${JOB_NAME}項目!\n- 版本:${tag}\n- 持續(xù)時間:${currentBuild.durationString}\n- 任務(wù):#${JOB_NAME}"]
)
}
}
- 2:將上面的語法放到Jenkinsfile的stages外面,并上傳gitlab:
- 3:點擊構(gòu)建Jenkins
文章來源:http://www.zghlxwxcb.cn/news/detail-716916.html
- 4:查看釘釘項目群:
文章來源地址http://www.zghlxwxcb.cn/news/detail-716916.html
實戰(zhàn)4的Jenkinsfile全部代碼?
pipeline {
agent any
environment{
harborAddress = '192.168.184.80:80'
harborRepo = 'repo'
harborUser = 'admin'
harborPasswd = 'Harbor12345'
}
// 存放所有任務(wù)的集合
stages {
stage('拉取Git倉庫代碼') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.184.70:8929/root/mytest.git']]])
}
}
stage('通過maven構(gòu)建項目') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}
stage('通過SonarQube做代碼質(zhì)量檢測') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7ad2200f7cca90c37a909fdba8db049ac700909f'
}
}
stage('通過Docker制作自定義鏡像') {
steps {
sh '''mv ./target/*.jar ./docker/
docker build -t ${JOB_NAME}:${tag} ./docker/'''
}
}
stage('將自定義鏡像推送到Harbor倉庫') {
steps {
sh '''docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}'''
}
}
stage('通過Publish Over SSH通知目標(biāo)服務(wù)器') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'mytest', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $host_port $container_port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
post {
success {
dingtalk (
robot: 'Jenkins-dingding',
type:'MARKDOWN',
title: "success: ${JOB_NAME}",
text: ["- 成功構(gòu)建:${JOB_NAME}項目!\n- 版本:${tag}\n- 持續(xù)時間:${currentBuild.durationString}\n- 任務(wù):#${JOB_NAME}"]
)
}
failure {
dingtalk (
robot: 'Jenkins-dingding',
type:'MARKDOWN',
title: "fail: ${JOB_NAME}",
text: ["- 失敗構(gòu)建:${JOB_NAME}項目!\n- 版本:${tag}\n- 持續(xù)時間:${currentBuild.durationString}\n- 任務(wù):#${JOB_NAME}"]
)
}
}
}
到了這里,關(guān)于DevOps持續(xù)集成-Jenkins(4)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!