架構(gòu)背景:
惠農(nóng)網(wǎng)目前后端采用的微服務(wù)的架構(gòu),有近100個(gè)不同的微服務(wù)。同時(shí)前端項(xiàng)目也包括很多單頁(yè)的h5項(xiàng)目,還有一些基于微前端的中臺(tái)項(xiàng)目。所以前后端的項(xiàng)目在gitlab倉(cāng)庫(kù)里面有200+個(gè)不同的倉(cāng)庫(kù)。
以前的情況:
之前的上線和發(fā)布流程是基于JetBrains公司的TeamCity的免費(fèi)版本結(jié)合Ansible來(lái)完成的,隨著項(xiàng)目越來(lái)越多,TeamCity免費(fèi)版本凸顯了越來(lái)越多的問(wèn)題:
免費(fèi)的TeamCity只支持配置100個(gè)項(xiàng)目, 目前我們的項(xiàng)目已經(jīng)大大超過(guò)了支持的上限,沒(méi)有辦法進(jìn)行繼續(xù)添加了。
每次創(chuàng)建一個(gè)TeamCity的項(xiàng)目都是基于以前的配置進(jìn)行copy,然后再去修改一些配置,在配置的過(guò)程中容易出現(xiàn)錯(cuò)誤,排查和定位比較花費(fèi)時(shí)間。
整體的打包、測(cè)試、部署、上線的流程都是通過(guò)復(fù)制的方法來(lái)創(chuàng)建的。如果要進(jìn)行修改,則需要把這些項(xiàng)目一個(gè)一個(gè)的修改,改動(dòng)的成本較大。
整個(gè)流程都是管控在研發(fā)手中,上線的時(shí)候缺乏質(zhì)量的管控,容易引發(fā)線上的bug,并且有時(shí)候發(fā)布是靜默發(fā)布,對(duì)應(yīng)的測(cè)試和項(xiàng)目負(fù)責(zé)人把控力度不足。
如果對(duì)于一個(gè)或者少數(shù)項(xiàng)目修改上線流程,沒(méi)有記錄的地方,導(dǎo)致接手的人對(duì)于上線流程把控不嚴(yán)。
打包和發(fā)布流程隔離,實(shí)現(xiàn)打包自動(dòng)化,發(fā)布手動(dòng)化的兩個(gè)階段, 達(dá)到由研發(fā)人員根據(jù)hook來(lái)自動(dòng)打包,由測(cè)試人員手動(dòng)進(jìn)行發(fā)布,這樣測(cè)試人員可以馬上進(jìn)行發(fā)布后的驗(yàn)證。
統(tǒng)一通知流程,在不同的階段失敗和成功都進(jìn)行統(tǒng)一通知。
基于以上的情況,決定把TeamCity上面的項(xiàng)目遷移到Jenkins上面,并且用IaC的理念重構(gòu)整個(gè)ci/cd的流程。
遷移改造的方案:
所有的部署的流程全部代碼化,利用jenkins的shared library插件,把項(xiàng)目的發(fā)布流程pipeline作為一個(gè)gitlab上的項(xiàng)目進(jìn)行管理,這樣通過(guò)代碼就可以進(jìn)行流程的統(tǒng)一管理和修改。
每個(gè)項(xiàng)目中加入ci的必要配置的配置文件,配置文件抽象出來(lái)就是項(xiàng)目四要素(項(xiàng)目所屬倉(cāng)庫(kù)的:group,項(xiàng)目名稱:project,項(xiàng)目部署機(jī)器: host, 項(xiàng)目部署端口: port)。
利用gitlab的global server hook來(lái)監(jiān)聽ci配置文件的變化,如果是有新增或者修改,則通過(guò)jenkins的api來(lái)創(chuàng)建和修改對(duì)應(yīng)的項(xiàng)目的發(fā)布頁(yè)面,通過(guò)gitlab的api來(lái)創(chuàng)建對(duì)應(yīng)的項(xiàng)目的webhook的配置
利用jenkins的配置文件,每個(gè)項(xiàng)目都根據(jù)配置文件,構(gòu)建不同的發(fā)布頁(yè)面,研發(fā)人員可以完全不關(guān)注jenkins的存在。減輕研發(fā)的思維負(fù)擔(dān)。
改造得到的成果
項(xiàng)目個(gè)數(shù)沒(méi)有上限,并且統(tǒng)一在一個(gè)jenkins環(huán)境就可以看到所有不同的項(xiàng)目。
測(cè)試環(huán)境流程和生產(chǎn)環(huán)境的流程全部在一個(gè)gitlab的倉(cāng)庫(kù),用代碼進(jìn)行管理,有g(shù)itlab的操作記錄,更好的管控每次的修改。
統(tǒng)一修改流程,只需要修改統(tǒng)一的流程,并會(huì)影響所有的項(xiàng)目,對(duì)于ci/cd流程的改動(dòng)達(dá)到了一次修改,全局生效的效果。
對(duì)于新增項(xiàng)目配置,只需要一個(gè)配置文件即可完成所有的流程,創(chuàng)建新項(xiàng)目只需要10秒即可創(chuàng)建完成。
因?yàn)榇虬桶l(fā)布流程隔離,所以發(fā)布或者回滾流程進(jìn)行了統(tǒng)一,一個(gè)tag只需要一次打包,就可以完成發(fā)布或者是回滾,并且提示了發(fā)布和回滾的效率。
整體ci的架構(gòu)流程圖

整體項(xiàng)目的工作流程
- 項(xiàng)目提交Jenkinsfile到gitlab倉(cāng)庫(kù)。
- gitlab倉(cāng)庫(kù)的Global Server Hook感知到Jenkinsfile文件的添加。
- 根據(jù)添加的Jenkinsfile里面的項(xiàng)目信息,初始化構(gòu)建Jenkins的job信息和gitlab的hook配置。
- 項(xiàng)目代碼變化了之后,Jenkins拉取變化的代碼,根據(jù)代碼里面的Jenkinsfile,讀取pipeline-library倉(cāng)庫(kù)的代碼,并且執(zhí)行代碼里面的流程(打包,運(yùn)行單元測(cè)試,運(yùn)行靜態(tài)檢查,打包,部署,通知)。
- 如果是線上環(huán)境,構(gòu)建最終發(fā)布頁(yè)面,通知測(cè)試,手動(dòng)進(jìn)行發(fā)布。
- 發(fā)布流程則是調(diào)用Ansible寫好的playbook的腳本,進(jìn)行多個(gè)服務(wù)器的最終發(fā)布
項(xiàng)目的Jenkinsfile例子截圖

總結(jié)
通過(guò)整體流程的改造,使得所有項(xiàng)目的ci/cd的流程一氣呵成。 大大提升了項(xiàng)目的配置和發(fā)布效率,減輕了維護(hù)的成本(研發(fā)人員只需要關(guān)注Jenkinsfile一個(gè)配置文件)。 雖然項(xiàng)目中沒(méi)有放出所有的代碼,但是這個(gè)整體流程已經(jīng)說(shuō)明的很明白了,如果想要溝通和了解細(xì)節(jié), 可以進(jìn)行留言。歡迎大家提出更好的想法。