jenkins如何部署應(yīng)用到多個(gè)環(huán)境
jenkins部署應(yīng)用到多個(gè)環(huán)境
在日常開發(fā)的過程中,我們經(jīng)常會(huì)遇到將應(yīng)用程序部署到多個(gè)環(huán)境的需求場(chǎng)景,如會(huì)先發(fā)布到測(cè)試環(huán)境,由測(cè)試人員進(jìn)行測(cè)試,成功之后,會(huì)繼續(xù)將當(dāng)前應(yīng)用部署到集成環(huán)境,進(jìn)行集成測(cè)試,全部通過后,再繼續(xù)將應(yīng)用部署到生產(chǎn)環(huán)境,即完成一整個(gè)上線的流程。
本文將介紹如何基于流水線的方式,將應(yīng)用部署到多個(gè)環(huán)境,本次之多兩個(gè)環(huán)境,分別是測(cè)試環(huán)境和生產(chǎn)環(huán)境,可以根據(jù)實(shí)際情況進(jìn)行優(yōu)化調(diào)整。
創(chuàng)建項(xiàng)目
如上,創(chuàng)建一個(gè)流水線的項(xiàng)目
設(shè)置參數(shù)
如上圖所示,設(shè)置一個(gè)標(biāo)識(shí)參數(shù),是否部署到生產(chǎn)環(huán)境
配置流水線
流水線的配置,如下圖所示,是整個(gè)項(xiàng)目配置的核心所在,我們需要在此處設(shè)置項(xiàng)目構(gòu)建工具maven,拉取項(xiàng)目代碼,構(gòu)建項(xiàng)目代碼,將打包后的文件上傳到部署的服務(wù)器上,在遠(yuǎn)程服務(wù)器上啟動(dòng)應(yīng)用以及最后的清理等步驟。
設(shè)置環(huán)境變量
設(shè)置環(huán)境變量是為了將之前配置的參數(shù)寫到環(huán)境變量中,供后續(xù)階段使用
environment { DEPLOY_TO_PROD = "${params.deployToProd}" }
以上配置之后,后續(xù)便可以通過env.DEPLOY_TO_PROD進(jìn)行引用。
配置maven
tools { maven "maven" }
以上配置了項(xiàng)目的構(gòu)建工具maven,maven的值是之前在全局設(shè)置中配置的,可參考之前的文章。
構(gòu)建
stages { }
配置了構(gòu)建的階段,可以在里面配置多個(gè)stage代碼塊,每個(gè)塊代表一個(gè)階段,如構(gòu)建、部署測(cè)試、部署生產(chǎn)等。
構(gòu)建項(xiàng)目階段
在構(gòu)建階段,我們拉取代碼,并使用maven進(jìn)行構(gòu)建,構(gòu)建成功后,將構(gòu)建成功的包進(jìn)行歸檔,供后續(xù)階段使用
stage('構(gòu)建') { steps { // Get some code from a GitHub repository git branch: 'main', credentialsId: 'git', url: 'http://ip:port/projectName.git' // Run Maven on a Unix agent. sh "mvn -Dmaven.test.skip=true clean package" } post { // If Maven was able to run the tests, even if some of the test // failed, record the test results and archive the jar file. success { archiveArtifacts 'target/*.jar' archiveArtifacts 'Dockerfile' } } }
在stage中,通過steps配置當(dāng)前階段的構(gòu)建步驟,在上述片段中,先拉取代碼,并使用mvaven進(jìn)行構(gòu)建。
post片段是在maven執(zhí)行成功后進(jìn)行構(gòu)建,我們將項(xiàng)目構(gòu)建成功后的jar包以及項(xiàng)目根目錄下的Dockerfile進(jìn)行歸檔。
在下一個(gè)步驟中,會(huì)將歸檔后的文件上傳到部署的服務(wù)器中。
部署測(cè)試環(huán)境
在將項(xiàng)目的部署文件歸檔后,便可以部署到測(cè)試環(huán)境了,片段如下
在上個(gè)階段,我們配置的是部署到測(cè)試環(huán)境,首先使用ssh over publisher插件,將歸檔的構(gòu)建上傳到服務(wù)器,在post中,設(shè)置了success 片段,是在上傳成功后執(zhí)行的片段,在此我們使用sh 命令,在遠(yuǎn)程服務(wù)器上執(zhí)行命令,本項(xiàng)目使用了docker,因此,ssh中的命令都是關(guān)于docker的,大家可以根據(jù)實(shí)際情況,進(jìn)行調(diào)整。
此外,需要注意 ssh -o StrictHostKeyChecking=no root@ip,其中ip是遠(yuǎn)程服務(wù)器的ip地址,需要提前配置私匙,之前文章有講解,可以參考下。此處,無須設(shè)置密碼的操作。
部署生產(chǎn)環(huán)境
在部署生產(chǎn)環(huán)境時(shí),需要判斷環(huán)境變量DEPLOY_TO_PROD是否符合條件,如果符合,則執(zhí)行生產(chǎn)階段的代碼,否則不執(zhí)行。
如下圖所示:
本例子中,實(shí)在生產(chǎn)環(huán)境部署了兩臺(tái)服務(wù)器,因此sshPublisher是兩個(gè),而在post中,使用了script腳本,因?yàn)橐僮鲀膳_(tái)服務(wù)器,變臉執(zhí)行每臺(tái)服務(wù)器的命令,大家可以根據(jù)需要調(diào)整。
清理階段
post { always { // 清理工作空間 cleanWs() } }
如上,執(zhí)行部署完成后的清理操作。
整體代碼如下:
pipeline { agent any parameters { choice( name: 'deployToProd', choices: ['否','是'], description: "如果需要部署到生產(chǎn),選擇【是】" ) } environment { DEPLOY_TO_PROD = "${params.deployToProd}" } tools { // Install the Maven version configured as "M3" and add it to the path. maven "maven" } stages { stage('構(gòu)建') { steps { // Get some code from a GitHub repository git branch: 'main', credentialsId: 'git', url: 'http://ip:port/projectName.git' // Run Maven on a Unix agent. sh "mvn -Dmaven.test.skip=true clean package" } post { // If Maven was able to run the tests, even if some of the test // failed, record the test results and archive the jar file. success { archiveArtifacts 'target/*.jar' archiveArtifacts 'Dockerfile' } } } stage("測(cè)試") { steps { sshPublisher(publishers: [sshPublisherDesc(configName: 'ss', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "s"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'target/*.jar'), sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "Success"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'Dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } post { success { sh ''' ssh -o StrictHostKeyChecking=no root@remote_ip " cd /app/dir " ''' } } } stage('線上環(huán)境') { when { expression { return env.DEPLOY_TO_PROD == '是' } } steps { sshPublisher(publishers: [sshPublisherDesc(configName: '10_202', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "s"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'target/*.jar'), sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "s"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'Dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) sshPublisher(publishers: [sshPublisherDesc(configName: '10_201', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "s"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'target/*.jar'), sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "s"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'Dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } post { success { script { def servers = ['remote_ip1','remote_ip2'] servers.each { server -> echo "Processing server: ${server}" sh """ ssh -o StrictHostKeyChecking=no root@${server} " cd /home/app/dir # 其他linux命令 " """ } } } } } } post { always { // 清理工作空間 cleanWs() } } }
以上是完成的流水線代碼,大家可以根據(jù)實(shí)際情況進(jìn)行調(diào)整。
部署效果,如上圖所示!
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
生產(chǎn)者消費(fèi)者模型ThreadLocal原理及實(shí)例詳解
這篇文章主要介紹了生產(chǎn)者消費(fèi)者模型ThreadLocal原理及實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09Java實(shí)現(xiàn)簡(jiǎn)單酒店管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單酒店管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05Mybatis實(shí)現(xiàn)分頁的注意點(diǎn)
Mybatis提供了強(qiáng)大的分頁攔截實(shí)現(xiàn),可以完美的實(shí)現(xiàn)分功能。下面小編給大家分享小編在使用攔截器給mybatis進(jìn)行分頁所遇到的問題及注意點(diǎn),需要的朋友一起看看吧2017-07-07一文教會(huì)你使用jmap和MAT進(jìn)行堆內(nèi)存溢出分析
本文介紹關(guān)于jmap和MAT的使用來進(jìn)行堆內(nèi)存溢出分析,因?yàn)檫@個(gè)內(nèi)存溢出是我們手動(dòng)構(gòu)造出來的,查找比較簡(jiǎn)單,真的到了生產(chǎn)上面需要我們仔細(xì)排除2021-09-09Springboot使用RabbitMQ實(shí)現(xiàn)關(guān)閉超時(shí)訂單(示例詳解)
介紹了如何在Spring Boot項(xiàng)目中使用RabbitMQ實(shí)現(xiàn)訂單的延時(shí)處理和超時(shí)關(guān)閉,通過配置RabbitMQ的交換機(jī)、隊(duì)列和綁定關(guān)系,以及編寫監(jiān)聽方法,實(shí)現(xiàn)了訂單數(shù)據(jù)的發(fā)送和延時(shí)消費(fèi),感興趣的朋友一起看看吧2025-01-01java StringBuilder類的詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了java StringBuilder類的詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,實(shí)現(xiàn)了StringBuilder類的追加、插入、替換、刪除等操作,需要的朋友可以參考下2017-08-08Java?深入理解創(chuàng)建型設(shè)計(jì)模式之建造者模式
建造者(Builder)模式和工廠模式的關(guān)注點(diǎn)不同:建造者模式注重零部件的組裝過程,而工廠方法模式更注重零部件的創(chuàng)建過程,但兩者可以結(jié)合使用2022-02-02