集成工具Jenkins部署全流程:從安裝到流水線實(shí)戰(zhàn))
我最早接觸持續(xù)集成工具就是因?yàn)楸灰淮问謩?dòng)發(fā)版折磨到天亮。那次經(jīng)歷讓我下定決心必須把構(gòu)建、測(cè)試、部署這套流程徹底自動(dòng)化。而聊到持續(xù)集成工具Jenkins 幾乎是繞不開的名字。這篇文章我就結(jié)合自己部署 Jenkins 的完整過程把從環(huán)境準(zhǔn)備、安裝配置到流水線搭建的每個(gè)環(huán)節(jié)包括踩過的坑和處理方案原原本本寫出來。項(xiàng)目標(biāo)題是“持續(xù)集成工具-Jenkins的部署流程”那我們就從最實(shí)際的問題開始Jenkins 到底怎么部署部署完該怎么用才能讓持續(xù)集成真正跑起來。這套內(nèi)容適合剛接手 CI 建設(shè)、準(zhǔn)備在團(tuán)隊(duì)里落地自動(dòng)化構(gòu)建的開發(fā)者也適合那些已經(jīng)把 Jenkins 跑起來但總出問題、想搞清楚原理的運(yùn)維同學(xué)。我會(huì)盡量少講空泛概念多給能直接照做的步驟和參數(shù)。1. 先把持續(xù)集成這件事想清楚1.1 持續(xù)集成到底解決了什么問題在聊 Jenkins 部署之前得先明確一個(gè)前提持續(xù)集成Continuous IntegrationCI不是裝個(gè)工具就完事它是一套工程實(shí)踐。核心思想是頻繁地把代碼變更合并到主干每次合并都自動(dòng)觸發(fā)構(gòu)建和測(cè)試盡早暴露集成問題。舉個(gè)例子。沒有 CI 的時(shí)候團(tuán)隊(duì)幾個(gè)人各自開發(fā)代碼合并集中在發(fā)版前。結(jié)果就是A 改的接口把 B 的調(diào)用弄掛了C 加的依賴和 D 用的版本沖突這些問題全在發(fā)版窗口集中爆發(fā)修一個(gè)冒一個(gè)。引入 CI 之后每次代碼推送到遠(yuǎn)端自動(dòng)觸發(fā)編譯、跑單測(cè)有問題當(dāng)場(chǎng)就發(fā)現(xiàn)定位成本低得多。需要說明的是CI 不等于 CD持續(xù)交付/持續(xù)部署。CI 側(cè)重“提交代碼后自動(dòng)驗(yàn)證”CD 側(cè)重“驗(yàn)證通過后自動(dòng)交付到環(huán)境”。Jenkins 兩者都能做但我個(gè)人建議先專注 CI把構(gòu)建和測(cè)試做扎實(shí)再考慮自動(dòng)部署。1.2 Jenkins 憑什么成為首選工具持續(xù)集成工具不少市面上有 GitLab CI、GitHub Actions、Travis CI還有云廠商自帶的各種流水線服務(wù)。但 Jenkins 在自建場(chǎng)景下依然有不可替代的位置。第一插件生態(tài)太豐富了。從代碼拉取、編譯構(gòu)建、測(cè)試報(bào)告展示到釘釘/郵件通知幾乎你能想到的環(huán)節(jié)都有插件支持。我統(tǒng)計(jì)過我這邊生產(chǎn)環(huán)境用的插件常年保持在 30 個(gè)左右覆蓋了多語言構(gòu)建、憑證管理、Kubernetes 集成整個(gè)鏈路都很順。第二完全自托管。代碼倉庫是內(nèi)網(wǎng)的或者需要訪問內(nèi)網(wǎng)私有化環(huán)境的Jenkins 部署在公司內(nèi)網(wǎng)最省事。相比 SaaS 服務(wù)數(shù)據(jù)不出內(nèi)網(wǎng)合規(guī)問題也少。第三Pipeline 能力強(qiáng)。Jenkins 的 Pipeline 用代碼定義整個(gè)構(gòu)建流程可以做成 Jenkinsfile 放進(jìn)代碼庫這樣構(gòu)建邏輯跟著項(xiàng)目走誰改了都看得見回滾也方便。當(dāng)然選型也不是非它不可。如果團(tuán)隊(duì)規(guī)模小、代碼量不大且倉庫托管在某個(gè)代碼托管平臺(tái)上用平臺(tái)自帶的 CI 功能會(huì)更快。但如果你需要一個(gè)長(zhǎng)期穩(wěn)定、可控性強(qiáng)的方案Jenkins 依然是自建 CI/CD 基礎(chǔ)設(shè)施中很扎實(shí)的選擇。2. 部署前的環(huán)境評(píng)估與版本選型2.1 硬件與操作系統(tǒng)選型建議部署 Jenkins 之前先把運(yùn)行環(huán)境定下來。我踩過的一個(gè)最直接的坑就是低估了資源需求。Jenkins 本體是個(gè) Java Web 應(yīng)用占用內(nèi)存不大但任務(wù)并發(fā)起來之后尤其是要同時(shí)構(gòu)建多個(gè)項(xiàng)目時(shí)內(nèi)存和 CPU 消耗漲得很快。我建議最低配置2 核 CPU、4GB 內(nèi)存、40GB 以上可用磁盤。如果你們還要在 Jenkins 上跑編譯、跑鏡像構(gòu)建這類重活那最好 4 核 8GB 起步。磁盤要留足因?yàn)闃?gòu)建產(chǎn)物、插件、日志都會(huì)持續(xù)增長(zhǎng)后期可以靠定期清理策略控制但初期空間別太摳。操作系統(tǒng)方面我推薦用某個(gè)長(zhǎng)期維護(hù)的 Linux 發(fā)行版。Windows 和 macOS 也能裝但生產(chǎn)環(huán)境不推薦原因很簡(jiǎn)單Linux 環(huán)境下做腳本調(diào)試、權(quán)限管理和 Docker 集成都更順手。我這里演示用的是 Linux 的環(huán)境具體發(fā)行版大家按自己熟悉的來。2.2 JDK 與 Jenkins 版本的配對(duì)策略Jenkins 是 Java 應(yīng)用JDK 版本必須匹配。這里有個(gè)非常關(guān)鍵的細(xì)節(jié)不同版本的 Jenkins 對(duì) Java 版本的要求不同。以我部署時(shí)的情況為例當(dāng)時(shí)的 Jenkins 版本要求 JDK 17 或更新版本。如果你用的是老一點(diǎn)的 Jenkins 版本可能只支持 JDK 8 或 JDK 11。裝之前先去官網(wǎng)查一下版本兼容矩陣別裝完發(fā)現(xiàn) Jenkins 啟動(dòng)不了。安裝 JDK 時(shí)還有個(gè)小細(xì)節(jié)盡量用發(fā)行版?zhèn)}庫里的包或者用某廠商的官方 JDK 發(fā)行版。有些公版腳本會(huì)默認(rèn)裝一個(gè)版本路徑還不一定對(duì)后面排查起來很麻煩。裝完用 java -version 確認(rèn)版本沒問題再進(jìn)入下一步。注意Jenkins 安裝程序自帶的 setup 向?qū)?huì)檢測(cè) Java 環(huán)境檢測(cè)不通過會(huì)直接報(bào)錯(cuò)。提前確認(rèn)java -version輸出符合要求能省很多事。3. 安裝部署全流程實(shí)操3.1 基于安裝包的常規(guī)部署步驟部署方式上我優(yōu)先推薦用發(fā)行版的軟件倉庫安裝 Jenkins。這樣做的最大好處是后續(xù)升級(jí)方便Jenkins 出新版本直接執(zhí)行包管理器升級(jí)命令就能完成插件和新功能也能及時(shí)跟上。第一步添加官方軟件源。這步很關(guān)鍵如果不添加源直接用系統(tǒng)的默認(rèn)源裝版本會(huì)非常老容易出現(xiàn)兼容性問題。不同發(fā)行版添加源的方式不同大概是導(dǎo)入官方的 GPG 密鑰然后把 Jenkins 的倉庫地址寫進(jìn)源列表最后刷新源緩存。這個(gè)流程做完之后再安裝。第二步安裝。包管理器會(huì)自動(dòng)把 Jenkins 依賴的組件拉下來。裝完檢查一下服務(wù)狀態(tài)是否正常運(yùn)行。如果遇到啟動(dòng)失敗多半是 JDK 版本不對(duì)回到上一節(jié)重新核對(duì)。第三步防火墻放行。Jenkins 默認(rèn)監(jiān)聽 8080 端口你需要確保這個(gè)端口可訪問。如果是內(nèi)網(wǎng)機(jī)器且大家都用跳板機(jī)那防火墻規(guī)則自己按需調(diào)整。然后就可以通過http://服務(wù)器IP:8080訪問了。首次訪問會(huì)要求輸入一個(gè)初始密碼這個(gè)密碼在服務(wù)器上有明確的文件路徑取出來填進(jìn)去就行。3.2 基于 Docker 的容器化部署方案如果你的團(tuán)隊(duì)已經(jīng)在用容器或者希望 Jenkins 實(shí)例能快速遷移和重建那用 Docker 部署也是不錯(cuò)的方案。這里我簡(jiǎn)單說一下思路不展開具體命令因?yàn)椴煌h(huán)境差異較大。用 Docker 部署 Jenkins 一個(gè)大坑是權(quán)限問題。Jenkins 容器里的用戶不是 root如果要掛載宿主機(jī)的 Docker 套接字來實(shí)現(xiàn)“容器內(nèi)構(gòu)建再生成容器”的方案必須處理好用戶 ID 和權(quán)限映射否則會(huì)一直報(bào)權(quán)限不足。我的建議是如果只是驗(yàn)證功能用 Docker 跑一個(gè)臨時(shí)實(shí)例沒問題如果要做生產(chǎn)級(jí)部署優(yōu)先用安裝包方式控制面更簡(jiǎn)單排查問題也更直接。容器化雖然靈活但引入了額外的存儲(chǔ)、網(wǎng)絡(luò)、權(quán)限維度的問題初期容易勸退。3.3 初始化配置與插件安裝策略首次登錄后Jenkins 會(huì)讓你選擇安裝插件的方式。推薦的選項(xiàng)是“Install suggested plugins”也就是安裝官方推薦插件。這個(gè)組合穩(wěn)定覆蓋面也夠適合多數(shù)場(chǎng)景。但如果你明確知道自己不需要某些插件也可以選擇自由選擇安裝。我個(gè)人建議先裝推薦的跑通流程之后再按需增減。這一步追求的是快速可用的初始狀態(tài)。初始化時(shí)還會(huì)要求創(chuàng)建管理員賬號(hào)。這里有個(gè)容易忽略的問題初始密碼在首次登錄后可以用但創(chuàng)建完管理員賬號(hào)后后續(xù)登錄就用新賬號(hào)了。如果之后想給別人開賬號(hào)需要在系統(tǒng)管理里配置用戶權(quán)限。加載插件的速度有時(shí)會(huì)比較慢特別是需要訪問外網(wǎng)才能下載插件的場(chǎng)景。建議在系統(tǒng)配置里改一下插件更新中心地址換成國(guó)內(nèi)可訪問的鏡像源速度會(huì)明顯改善。這一步具體地址各環(huán)境不同但我建議大家都提前確認(rèn)一下是部署流暢度的重要影響因素。4. 第一個(gè)自動(dòng)化構(gòu)建任務(wù)的完整配置4.1 構(gòu)建任務(wù)的核心三要素拆解初始化完成后我們來創(chuàng)建一個(gè)實(shí)際可用的構(gòu)建任務(wù)。以我之前部署時(shí)用的模擬項(xiàng)目 X 為例這是一個(gè)常規(guī)的 Web 項(xiàng)目代碼托管在內(nèi)網(wǎng)的 Git 倉庫里。在 Jenkins 里創(chuàng)建任務(wù)時(shí)建議選擇“自由風(fēng)格”來入門。一個(gè)自由風(fēng)格任務(wù)離不開三個(gè)要素源碼管理、構(gòu)建觸發(fā)器、構(gòu)建步驟。源碼管理這塊選 Git然后把倉庫地址和憑證填進(jìn)去。憑證可以先用用戶名密碼方式后續(xù)再升級(jí)成部署密鑰。需要注意分支配置默認(rèn)是*/master如果你的默認(rèn)分支是 main一定要改過來。構(gòu)建觸發(fā)器決定了什么時(shí)候跑。常用的觸發(fā)方式有三種定時(shí)輪詢代碼倉庫、Webhook 觸發(fā)、以及上游任務(wù)觸發(fā)。Webhook 是體驗(yàn)最好的方式代碼一推就觸發(fā)不用等輪詢。但設(shè)置 Webhook 需要代碼倉庫平臺(tái)能訪問到 Jenkins 地址內(nèi)網(wǎng)環(huán)境通常沒問題外網(wǎng)就需要做端口映射。構(gòu)建步驟是最有文章的地方。對(duì)于 Java 項(xiàng)目可以加一個(gè) Maven 構(gòu)建步驟執(zhí)行 clean package 命令來產(chǎn)出編譯包。這一步建議加上單元測(cè)試的閘門測(cè)試不通過就直接失敗避免壞代碼往下流。4.2 參數(shù)化構(gòu)建與構(gòu)建后動(dòng)作實(shí)際使用中你會(huì)發(fā)現(xiàn)固定不變的構(gòu)建流程太少。很多時(shí)候要區(qū)分測(cè)試環(huán)境和正式環(huán)境要能手動(dòng)指定版本號(hào)要選擇只跑某項(xiàng)測(cè)試。這時(shí)候就需要參數(shù)化構(gòu)建。在任務(wù)配置里勾選“參數(shù)化構(gòu)建過程”添加字符參數(shù)、選項(xiàng)參數(shù)或布爾參數(shù)。比如我加一個(gè)BRANCH_NAME參數(shù)構(gòu)建時(shí)就能臨時(shí)指定要構(gòu)建的分支。構(gòu)建步驟里的 Git 分支就用${BRANCH_NAME}這個(gè)變量來引用。這樣同一個(gè)任務(wù)既能跑最新代碼也能用來補(bǔ)發(fā)歷史版本。構(gòu)建后動(dòng)作也別忽略。最基礎(chǔ)的是構(gòu)建結(jié)果通知可以郵件通知也可以推到即時(shí)通訊工具。另外強(qiáng)烈建議把構(gòu)建產(chǎn)物歸檔配置上這樣每次構(gòu)建后在任務(wù)頁面就能直接下載 war 包或 jar 包排查問題不用再到服務(wù)器上翻目錄。4.3 憑證管理與敏感信息處理第一次配置 Git 密碼的人很容易直接把密碼明文填在任務(wù)里。這樣做短期方便但后患無窮任務(wù)配置頁在瀏覽器里任何能看到頁面的人都能看到密碼多人協(xié)作后密碼改動(dòng)又要跑到每個(gè)任務(wù)里去更新極其痛苦。正確做法是在系統(tǒng)配置中先創(chuàng)建“憑證”把用戶名密碼或部署密鑰存進(jìn)去然后在任務(wù)里引用這個(gè)憑證 ID。這樣做的好處是密碼只存一份更換時(shí)不用逐個(gè)任務(wù)去改。還有一個(gè)細(xì)節(jié)如果在構(gòu)建腳本里需要用到私有源或者鏡像倉庫密碼不要直接硬編碼。可以在參數(shù)化構(gòu)建的變量里引用或者用憑證綁定插件在構(gòu)建時(shí)動(dòng)態(tài)注入環(huán)境變量。Jenkins 對(duì)這個(gè)場(chǎng)景支持得不錯(cuò)關(guān)鍵是要養(yǎng)成敏感信息全部走憑證管理的習(xí)慣而不是圖省事。5. 從自由風(fēng)格任務(wù)到流水線的持續(xù)集成升級(jí)5.1 為什么要用 Pipeline 替代多條自由風(fēng)格任務(wù)用了一段時(shí)間的自由風(fēng)格任務(wù)后你會(huì)感受到它的局限。最明顯的問題是流程散落在各個(gè)任務(wù)的配置頁里沒法直觀看到整個(gè)鏈路。比如 commit 觸發(fā)構(gòu)建構(gòu)建完要手動(dòng)去點(diǎn)部署或者靠多個(gè)任務(wù)之間的上下游關(guān)系串聯(lián)出了問題時(shí)很難定位是哪一段的問題。Pipeline 把整個(gè)流程用腳本描述出來從拉代碼、編譯、測(cè)試、鏡像構(gòu)建到推送制品、部署到某環(huán)境一條流程清晰可見。你可以直觀看到當(dāng)前卡在哪一步每步日志也獨(dú)立分段排查效率高很多。我這里強(qiáng)烈建議如果團(tuán)隊(duì)流程已經(jīng)開始復(fù)雜化盡早轉(zhuǎn)到 Pipeline 上。雖然寫 Jenkinsfile 比在界面上點(diǎn)配置要多學(xué)一點(diǎn) Groovy 語法但這個(gè)學(xué)習(xí)成本是必要的。更重要的是Jenkinsfile 是代碼像項(xiàng)目源碼一樣維護(hù)代碼評(píng)審和變更記錄都有了這才是工程化。5.2 一個(gè)可復(fù)用的多階段流水線示例分享一個(gè)我實(shí)際用過的流水線骨架拿來做參考非常合適。整個(gè)流程大概四個(gè) stage拉取代碼、構(gòu)建與單測(cè)、產(chǎn)出鏡像并推送、按參數(shù)決定是否部署。拉取代碼階段直接用 checkout 步驟分支從參數(shù)里讀這樣手動(dòng)構(gòu)建時(shí)可以指定分支。構(gòu)建與單測(cè)階段用 Maven 或前端構(gòu)建工具跑編譯然后歸檔測(cè)試報(bào)告。如果用了 GitLab 這類平臺(tái)還可以假裝測(cè)試報(bào)告讀回去。鏡像構(gòu)建和推送階段基礎(chǔ)是構(gòu)建產(chǎn)物已經(jīng)準(zhǔn)備好。這里會(huì)用到 Docker 的構(gòu)建能力建議把鏡像倉庫地址和憑證做成環(huán)境變量避免寫死在 Jenkinsfile 里。鏡像 tag 可以用構(gòu)建號(hào)加上 Git 短 commit hash 拼接保證可追溯。這個(gè) tag 命名習(xí)慣非常重要后期回溯線上版本全靠它。部署階段如果只是測(cè)試環(huán)境可以直接在 Jenkins 機(jī)器上執(zhí)行腳本或者調(diào)用遠(yuǎn)端宿主機(jī)的部署接口。生產(chǎn)環(huán)境我建議加入人工確認(rèn)步驟用 input 指令卡一下等有權(quán)限的人點(diǎn)擊“繼續(xù)”才執(zhí)行后續(xù)操作。初次嘗試時(shí)這個(gè)門檻能擋住很多誤操作。5.3 多分支流水線與分支策略匹配當(dāng)你把 Jenkinsfile 提交到代碼庫之后你會(huì)發(fā)現(xiàn)“多分支流水線”這個(gè)功能特別香。它會(huì)自動(dòng)掃描倉庫里的所有分支每個(gè)分支都能有獨(dú)立的構(gòu)建記錄和狀態(tài)展示保護(hù)分支額外設(shè)置超時(shí)與告警。這與團(tuán)隊(duì)的 Git 工作流直接關(guān)聯(lián)。如果你們做主分支開發(fā)模式那每次合并到主干都會(huì)自動(dòng)觸發(fā)構(gòu)建和測(cè)試如果做 Git Flow那 release 分支要額外跑一遍完整測(cè)試和部署到預(yù)發(fā)環(huán)境。這些策略都靠多分支流水線來落地每個(gè)分支類型用不同的構(gòu)建參數(shù)和發(fā)布目標(biāo)。我實(shí)際用下來的體會(huì)是分支策略不用復(fù)雜但要明確“哪類分支觸發(fā)哪類構(gòu)建”。這一條在 Jenkinsfile 里用 when 條件就能實(shí)現(xiàn)不用維護(hù)一大堆任務(wù)配置清晰多了。6. 高頻問題排查與避坑實(shí)錄6.1 部署和日常使用中的高頻故障速查我把這些年遇到過的高頻問題按現(xiàn)象、原因、解決方案整理成一個(gè)表方便你在出問題時(shí)直接對(duì)照。問題現(xiàn)象常見原因處理思路啟動(dòng)失敗日志提示 Java 版本不支持JDK 版本與當(dāng)前 Jenkins 版本不兼容查版本兼容矩陣更換 JDK 版本插件安裝極慢或超時(shí)默認(rèn)插件中心地址訪問受限更換為可用的鏡像源再做一次插件更新構(gòu)建任務(wù)一直卡在拉取代碼憑證無效或機(jī)器人不允許訪問倉庫檢查憑證有效期用部署密鑰替換密碼Git 拉取失敗提示臨時(shí)文件目錄不可寫工作空間目錄權(quán)限不對(duì)檢查 Jenkins 進(jìn)程用戶的目錄寫權(quán)限構(gòu)建產(chǎn)物找不到步驟里沒配置歸檔或產(chǎn)物路徑不對(duì)確認(rèn)構(gòu)建結(jié)果的相對(duì)路徑并勾選歸檔Webhook 不觸發(fā)構(gòu)建出口 IP 限制、地址不通或憑證不匹配在倉庫端手動(dòng)測(cè)試 hook檢查消息記錄定時(shí)任務(wù)到了時(shí)間不執(zhí)行時(shí)區(qū)配置錯(cuò)誤服務(wù)器時(shí)區(qū)與預(yù)期不符修改 JVM 時(shí)區(qū)為指定的本地時(shí)區(qū)構(gòu)建歷史丟失頁面報(bào)空間不足磁盤占用超過閾值清理舊的構(gòu)建記錄和日志設(shè)置保留策略這張表涵蓋了我最常遇到的幾類問題。其中“構(gòu)建歷史丟失”這個(gè)現(xiàn)象初期我以為是 Jenkins 的 bug后來排查發(fā)現(xiàn)是磁盤滿了系統(tǒng)自動(dòng)清理了部分舊數(shù)據(jù)。磁盤空間監(jiān)測(cè)對(duì) Jenkins 來說真的很重要建議直接配置系統(tǒng)監(jiān)控插件空間低于閾值主動(dòng)告警。6.2 并發(fā)構(gòu)建與權(quán)限控制的一些心得Jenkins 默認(rèn)是支持并發(fā)構(gòu)建的但并發(fā)度過高會(huì)直接拖垮機(jī)器。我遇到過一臺(tái) 4 核 8GB 的機(jī)器上同時(shí)跑 6 個(gè)構(gòu)建任務(wù)每個(gè)都是前端編譯加單測(cè)結(jié)果內(nèi)存直接打滿構(gòu)建大面積失敗。后來給主節(jié)點(diǎn)設(shè)置了最大并發(fā)構(gòu)建數(shù)限制才算穩(wěn)定下來。并發(fā)控制還有一個(gè)容易被忽視的維度多個(gè)任務(wù)同時(shí)寫同一個(gè)代碼目錄或者同時(shí)操作同一個(gè)輸出路徑會(huì)產(chǎn)生不可預(yù)期的構(gòu)建結(jié)果。我后來把所有構(gòu)建任務(wù)都配置成“不允許并行執(zhí)行”也就是使用自定義工作空間把每個(gè)項(xiàng)目的構(gòu)建目錄完全隔離。雖然犧牲了一點(diǎn)并發(fā)度但換來的是構(gòu)建結(jié)果的確定性。權(quán)限方面我推薦一開始就啟用 Jenkins 自帶的基于角色的權(quán)限控制。團(tuán)隊(duì)規(guī)模小的時(shí)候可能感覺不到一旦加了新人或需要外部同事看構(gòu)建日志沒有權(quán)限隔離就會(huì)很尷尬。我吃過這個(gè)虧一個(gè)臨時(shí)同事進(jìn)來幫忙看問題順手就動(dòng)了一個(gè)生產(chǎn)部署任務(wù)的配置雖然沒有造成事故但徹底改變了我對(duì) Jenkins 權(quán)限管理的態(tài)度。提示Jenkins 默認(rèn)是“任何人都可以操作所有任務(wù)”的模式這在開發(fā)環(huán)境無所謂只要你們的環(huán)境涉及生產(chǎn)部署操作就一定要做權(quán)限隔離。好的權(quán)限模型是“按角色分場(chǎng)景”開發(fā)角色只能觸發(fā)構(gòu)建和查看日志運(yùn)維角色才有權(quán)限改配置和執(zhí)行部署。6.3 多環(huán)境發(fā)布的一個(gè)穩(wěn)定實(shí)踐Jenkins 部署還有一個(gè)進(jìn)階問題怎么用一套流程管理開發(fā)、測(cè)試、預(yù)發(fā)、生產(chǎn)多個(gè)環(huán)境的發(fā)布。我的做法是用參數(shù)化構(gòu)建區(qū)分環(huán)境每個(gè)環(huán)境對(duì)應(yīng)的目標(biāo)主機(jī)列表、配置文件模板不一樣。在 Jenkinsfile 中可以定義一個(gè)環(huán)境分支的判斷然后根據(jù)參數(shù)選擇不同的部署目標(biāo)。這里有一個(gè)很關(guān)鍵的細(xì)節(jié)構(gòu)建產(chǎn)物應(yīng)該只構(gòu)建一次然后多次部署。不要在每個(gè)環(huán)境都重新編譯一遍那樣既有性能損耗又可能因?yàn)榄h(huán)境差異產(chǎn)生出不同產(chǎn)物。正確做法是構(gòu)建階段統(tǒng)一產(chǎn)出制品部署階段按不同環(huán)境參數(shù)拉取同一物件的不同配置。這套模式幫我解決了很大的維護(hù)成本。以前每個(gè)環(huán)境都要維護(hù)一套任務(wù)現(xiàn)在核心流程就一條環(huán)境差異只體現(xiàn)在參數(shù)和配置里加一個(gè)環(huán)境基本是幾分鐘的事。寫在最后一次部署帶來的長(zhǎng)期收益從第一臺(tái) Jenkins 部署到現(xiàn)在我最深的體會(huì)是工具本身不難難的是想清楚你要把它用成什么樣。很多人裝 Jenkins 只是為了“有個(gè)持續(xù)集成工具”結(jié)果裝完沒人維護(hù)任務(wù)三天兩頭掛最后反而不如手動(dòng)構(gòu)建穩(wěn)當(dāng)。Jenkins 部署只是一個(gè)開始。它能發(fā)揮多大價(jià)值取決于你愿不愿意把構(gòu)建、測(cè)試、制品管理這些環(huán)節(jié)都接入進(jìn)來。我建議第一周先只做一個(gè)項(xiàng)目的編譯加單測(cè)跑穩(wěn)了再加鏡像構(gòu)建再加自動(dòng)部署到測(cè)試環(huán)境一步步來別貪多。等整套流程真正轉(zhuǎn)起來你會(huì)發(fā)現(xiàn)之前手動(dòng)發(fā)版的那些擔(dān)驚受怕都會(huì)變成一次很輕松的流水線操作。