DevOps實(shí)踐——打造自服務(wù)持續(xù)交付(下)
在上一篇文章中,主要講了DevOps轉(zhuǎn)型的動(dòng)機(jī)、策略和方法,本文將會(huì)為大家?guī)?lái)更多DevOps轉(zhuǎn)型的落地策略和實(shí)踐。
實(shí)踐過(guò)程
下圖是我們?yōu)閳F(tuán)隊(duì)設(shè)計(jì)的持續(xù)交付流水線,目的是能讓Platform團(tuán)隊(duì)和交付團(tuán)隊(duì)之間的觸點(diǎn)能夠被融入到持續(xù)交付流水線中,并且以基礎(chǔ)設(shè)施即代碼作為協(xié)同媒介,通過(guò)自動(dòng)化的方式實(shí)現(xiàn)開(kāi)發(fā)于運(yùn)維(即基礎(chǔ)設(shè)施與軟件系統(tǒng))的無(wú)縫對(duì)接。
我們來(lái)看看我們給持續(xù)交付流水線賦予了哪些能力:
- 站在交付團(tuán)隊(duì)的視角,我們決定將基礎(chǔ)設(shè)施構(gòu)建,流水線構(gòu)建、部署等活動(dòng)都代碼化,與應(yīng)用代碼放在同一個(gè)代碼倉(cāng)庫(kù)中。
- 交付團(tuán)隊(duì)通過(guò)提交我們的基礎(chǔ)設(shè)施代碼到倉(cāng)庫(kù)后,自動(dòng)觸發(fā)持續(xù)交付工具創(chuàng)建或更新流水線。
- 接著會(huì)自動(dòng)觸發(fā)構(gòu)建,靜態(tài)檢查,測(cè)試覆蓋率校測(cè),代碼規(guī)范驗(yàn)證等任務(wù),最終輸出構(gòu)建產(chǎn)物并將構(gòu)建產(chǎn)物推送到倉(cāng)庫(kù)。
- 然后會(huì)根據(jù)交付團(tuán)隊(duì)對(duì)基礎(chǔ)設(shè)施和環(huán)境的定義到當(dāng)前要部署的網(wǎng)絡(luò)環(huán)境中去創(chuàng)建或更改虛擬機(jī)、網(wǎng)絡(luò)、存儲(chǔ)方式等。
- ***,當(dāng)基礎(chǔ)設(shè)施創(chuàng)建成功以后,就會(huì)去倉(cāng)庫(kù)下載指定版本的構(gòu)建產(chǎn)物進(jìn)行最終的部署活動(dòng)。
但需要注意的是:
- 為了持續(xù)優(yōu)化交付流程,我們對(duì)開(kāi)發(fā)的許多活動(dòng)進(jìn)行的數(shù)據(jù)收集和分析,以報(bào)表的形式去分析展示代碼提交頻率,系統(tǒng)和代碼的質(zhì)量情況,缺陷和構(gòu)建情況等,幫助團(tuán)隊(duì)找到自己的瓶頸或問(wèn)題。
- 幫助團(tuán)隊(duì)能夠?qū)崟r(shí)監(jiān)控自己應(yīng)用的運(yùn)行狀態(tài),設(shè)計(jì)和查看不同緯度的日志總匯等。
那我們來(lái)看看通過(guò)什么技術(shù)可以實(shí)現(xiàn)這樣的持續(xù)交付流程:
我們選擇了一種輕量級(jí)、低耦合的技術(shù)組合Ansible+Jenkins+AWS。我認(rèn)為其核心是Ansible。
下面我們來(lái)看看Ansible可以幫助我們做些什么:
- 創(chuàng)建和更改AWS中的資源;
- 自動(dòng)化部署和基礎(chǔ)設(shè)施測(cè)試;
- 建立開(kāi)發(fā)與平臺(tái)團(tuán)隊(duì)之間的溝通體系。
考慮到基于yaml語(yǔ)法的Ansible配置簡(jiǎn)潔且易讀,所以我們選擇直接用它作為提供給交付團(tuán)隊(duì)的公有DSL模板,利用Ansible Playbook的模塊化思想將開(kāi)發(fā)團(tuán)隊(duì)的職責(zé)和平臺(tái)團(tuán)隊(duì)的職責(zé)很清晰的分離,平臺(tái)團(tuán)隊(duì)關(guān)注Ansible提供給交付團(tuán)隊(duì)的服務(wù)是否滿足需求和DSL模板是否易用,而交付團(tuán)隊(duì)只用關(guān)注如何基于公有DSL去定制自己的基礎(chǔ)設(shè)施,環(huán)境依賴和部署等。
于此同時(shí)也滿足了很多開(kāi)發(fā)對(duì)于Ansible和AWS的興趣和熱情,更使得之后在交付團(tuán)隊(duì)落地變得更容易。
接下來(lái)通過(guò)一個(gè)實(shí)例來(lái)看看:
左邊是Platform團(tuán)隊(duì)的倉(cāng)庫(kù),這個(gè)倉(cāng)庫(kù)里面包含了創(chuàng)建基礎(chǔ)設(shè)施、環(huán)境配置和部署的實(shí)現(xiàn)。
右邊是交付團(tuán)隊(duì)的倉(cāng)庫(kù),其中deployment目錄下,是公有的DSL模板,其中包含多種環(huán)境(開(kāi)發(fā)、測(cè)試、預(yù)生產(chǎn)環(huán)境等的獨(dú)立配置),以及一套基于DSL的代碼模板,其中包含創(chuàng)建基礎(chǔ)設(shè)施和部署應(yīng)用這兩部分DSL代碼模板。
接下來(lái),我們來(lái)看看它們配合與集成的方式:
他們會(huì)在持續(xù)集成流水線中被動(dòng)態(tài)組合到一起:
- 在創(chuàng)建基礎(chǔ)設(shè)施和部署的時(shí)候會(huì)分別拉取基礎(chǔ)設(shè)施代碼庫(kù)和應(yīng)用代碼庫(kù)。
- 此時(shí)應(yīng)用代碼為調(diào)用入庫(kù),公有基礎(chǔ)設(shè)施為功能框架庫(kù),兩者配合,完成環(huán)境的創(chuàng)建和應(yīng)用部署。
在做微服務(wù)的團(tuán)隊(duì),接受度非常高,能夠快速上手,而且甚至有團(tuán)隊(duì)因?yàn)樽陨淼囊恍┬枨?,自己去寫一些Ansible模塊,然后向我們發(fā)起pull request。
當(dāng)然,我們?cè)谕茝V這套流程的過(guò)程中發(fā)現(xiàn),一些實(shí)踐能夠幫助我們更快速落地:
- DevOps團(tuán)隊(duì)的成員由各交付團(tuán)隊(duì)和原運(yùn)維團(tuán)隊(duì)組成,這樣的組成方式,能夠保證團(tuán)隊(duì)的視角可以關(guān)注到整個(gè)持續(xù)交付過(guò)程的每個(gè)環(huán)節(jié)。
- 交付團(tuán)隊(duì)成員與DevOps團(tuán)隊(duì)成員定期輪崗制,DevOps小組中的文化(如自動(dòng)化優(yōu)先)可以蔓延開(kāi),讓交付團(tuán)隊(duì)更快適應(yīng)。
- 結(jié)對(duì)、Showcase和培訓(xùn),主要目的是知識(shí)的傳遞,讓更多地團(tuán)隊(duì)逐步采用新的交付模式,得到更多改進(jìn)中的反饋。
- 提供給交付團(tuán)隊(duì)的自服務(wù)代碼倉(cāng)庫(kù)對(duì)每個(gè)人開(kāi)放,交付團(tuán)隊(duì)被授權(quán)優(yōu)化、新增基礎(chǔ)設(shè)施,讓DevOps文化和職責(zé)落地到交付流程中。
現(xiàn)在來(lái)看,集中式、審批式、被動(dòng)響應(yīng)請(qǐng)求的中央運(yùn)維團(tuán)隊(duì)不再是整個(gè)交付流程中的依賴和瓶頸,已基本轉(zhuǎn)向帶自服務(wù)化、審查式、主動(dòng)優(yōu)化的去中心化交付團(tuán)隊(duì):
我們通過(guò)技術(shù)驅(qū)動(dòng)改進(jìn),讓團(tuán)隊(duì)之間的合作方式發(fā)生了巨大改變,開(kāi)發(fā)與運(yùn)維之間的那道墻也漸漸消失,以前被動(dòng)響應(yīng)請(qǐng)求的中央運(yùn)維團(tuán)隊(duì)逐步被平臺(tái)團(tuán)隊(duì)所替代,平臺(tái)團(tuán)隊(duì)中一部分人會(huì)負(fù)責(zé)基礎(chǔ)設(shè)施平臺(tái)的發(fā)展,負(fù)責(zé)公有云與企業(yè)內(nèi)部系統(tǒng)的對(duì)接、完善安全、災(zāi)備、提供基礎(chǔ)設(shè)施的自服務(wù)機(jī)制,另一部分人會(huì)為產(chǎn)品團(tuán)隊(duì)提供可定制的工作、平臺(tái)、并為產(chǎn)品團(tuán)隊(duì)賦能。這時(shí)交付團(tuán)隊(duì)開(kāi)始管理自己的環(huán)境、維護(hù)流水線、負(fù)責(zé)生產(chǎn)環(huán)境變更。
在推廣和落地自服務(wù)持續(xù)交付流程的過(guò)程中,我們也遇到了很多遺留系統(tǒng)和復(fù)雜部署應(yīng)用的交付團(tuán)隊(duì),他們無(wú)法直接對(duì)接這套交付流程。
例如有一個(gè)40-50人的團(tuán)隊(duì),它是基于AEM開(kāi)發(fā)整個(gè)公司所有的前端門戶,AEM是Adobe公司的CMS系統(tǒng),其安裝和部署很復(fù)雜,以前都是通過(guò)手工安裝和拷貝的方式進(jìn)行部署,而且他們?cè)陂_(kāi)發(fā)→測(cè)試→部署階段可能會(huì)動(dòng)態(tài)擴(kuò)張多套環(huán)境來(lái)支持,且每次代碼變更的提交都會(huì)對(duì)已經(jīng)安裝的AEM進(jìn)行修改、配置、重啟等操作。
整個(gè)開(kāi)發(fā)和測(cè)試流程都很復(fù)雜,而且效率很低,出現(xiàn)問(wèn)題和故障的風(fēng)險(xiǎn)也很大,如果我們直接利用Ansible把AEM的安裝和部署過(guò)程都自動(dòng)化,由于AEM本身部署的復(fù)雜性,可以預(yù)見(jiàn)以后這部分更新和維護(hù)的工作還是很難交由交付團(tuán)隊(duì)自治。所以我們***步要做的就是為其設(shè)計(jì)新的持續(xù)交付流水線,然后在這個(gè)流程中去定義和識(shí)別兩個(gè)團(tuán)隊(duì)的職責(zé)和關(guān)注重心,***再通過(guò)打造高效的自服務(wù)使整個(gè)交付流程得到改進(jìn)。
首先我們根據(jù)校服團(tuán)隊(duì)提交變更的平率,從低到高依次定義了三條持續(xù)集成流水線(如下圖):
- 創(chuàng)建和測(cè)試基礎(chǔ)設(shè)施資源;
- 配置基礎(chǔ)設(shè)施資源和環(huán)境;
- 部署應(yīng)用程。
因?yàn)锳EM安裝和更新很復(fù)雜,所以我們引入了鏡像技術(shù)?;A(chǔ)設(shè)施和基礎(chǔ)設(shè)施配置兩條流水線的產(chǎn)物為一個(gè)image,應(yīng)用流水線在部署階段會(huì)去檢查是否存在新的環(huán)境鏡像,如果存在,就會(huì)基于快速創(chuàng)建一個(gè)新的AEM環(huán)境,然后進(jìn)行應(yīng)用代碼的部署。
通過(guò)新的自動(dòng)化持續(xù)交付流水線大大加速了AEM團(tuán)隊(duì)的開(kāi)發(fā)和測(cè)試速度,也使得整個(gè)環(huán)境更加可控和易維護(hù)。對(duì)于交付團(tuán)隊(duì)來(lái)說(shuō),他們可以自己去維護(hù)包括基礎(chǔ)設(shè)施、環(huán)境變更和應(yīng)用部署等全生命周期交付活動(dòng)。
對(duì)于Platform團(tuán)隊(duì)來(lái)說(shuō),只用去考慮鏡像的生命周期管理,如何去優(yōu)化鏡像的創(chuàng)建速度等,這些可以幫助到更多其它團(tuán)隊(duì)解決類似問(wèn)題的領(lǐng)域。對(duì)于這種特殊情況,我們盡管引入很多與大多數(shù)團(tuán)隊(duì)不同的交付流程和技術(shù),但所有的工作和優(yōu)化都是基于之前打造的自服務(wù)持續(xù)交付流程、協(xié)議和工具平臺(tái)之上的,保證了不同的交付團(tuán)隊(duì)與Platform的配合方式的一致性。
實(shí)踐啟示
通過(guò)在大量交付團(tuán)隊(duì)落地基于自服務(wù)的持續(xù)交付流程,兩種團(tuán)隊(duì)的職責(zé)更加清晰了:
所有好的實(shí)踐都必須考慮規(guī)模化的問(wèn)題,如果無(wú)法大規(guī)模的被接受和落地,再好的實(shí)踐也沒(méi)用。對(duì)于咱們這個(gè)轉(zhuǎn)型的過(guò)程,我也給出一個(gè)套路:
有了套路,接下來(lái)總結(jié)一下應(yīng)用這個(gè)套路進(jìn)行DevOps轉(zhuǎn)型過(guò)程中的一些經(jīng)驗(yàn)和思考:
- 易用的通用DSL模板設(shè)計(jì),提供交付與Platform團(tuán)隊(duì)統(tǒng)一的DSL模板(build and update anything)。
- 構(gòu)建通用持續(xù)交付流水框架,提供給交付團(tuán)隊(duì)定制化流水線的能力,使流水線主要關(guān)注點(diǎn)始終在產(chǎn)品的成功交付。
- 以技術(shù)驅(qū)動(dòng)DevOps文化大面積傳播,讓Platform團(tuán)隊(duì)成員走入交付團(tuán)隊(duì),協(xié)作改進(jìn)、知識(shí)傳遞,確保實(shí)踐落地。
- 將一切自動(dòng)化、自服務(wù)化。交付團(tuán)隊(duì)?wèi)?yīng)該被授權(quán)優(yōu)化、新增基礎(chǔ)設(shè)施服務(wù),讓DevOps能力和職責(zé)在交付團(tuán)隊(duì)落地生根。
***,我提取了5點(diǎn)對(duì)我們來(lái)說(shuō)非常重要的策略或是推進(jìn)方法:
- 小步快跑,在有大方向的基礎(chǔ)上,需要將每一步改變都設(shè)計(jì)得足夠小,這樣才能足夠快的去改進(jìn)。
- 交付團(tuán)隊(duì)賦能,給每個(gè)人都留一扇門,在他意識(shí)到要做些事情的時(shí)候,可以很快付諸行動(dòng)。
- 逐步用基礎(chǔ)設(shè)施自服務(wù)化替代運(yùn)維部門的審批流程。 建立持續(xù)反饋和改進(jìn)機(jī)制。
- 以DevOps團(tuán)隊(duì)為杠桿,撬動(dòng)更大范圍自服務(wù)交付。
非常感謝你的耐心閱讀,希望我的文章能夠給你帶來(lái)哪怕一點(diǎn)點(diǎn)啟示。有任何問(wèn)題或是想與我討論的點(diǎn),歡迎留言。
【本文是51CTO專欄作者“ThoughtWorks”的原創(chuàng)稿件,微信公眾號(hào):思特沃克,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】