|
在前文《依賴管理》中,我們討論了如何在代碼變得龐大,組件增多的情況下,做好外部庫和內(nèi)部組件依賴管理,從而提高構(gòu)建效率。可以應(yīng)用的實踐包括:一次生成,多次復(fù)用;建立統(tǒng)一制品庫,外部依賴庫可以使用像Maven或Ivy這樣的工具進行統(tǒng)一管理;對架構(gòu)進行調(diào)整,使一個大的代碼庫分成多個組件;每個組件有自己的持續(xù)集成體系;對多個組件做持續(xù)集成。然而,解決一個問題后,總會有另一個問題等在那里,需要你來解決。這次Joe的團隊遇到了部署問題。
星期一早上,Alice一進辦公室,就看到一臉倦意的Joe坐在椅子上,喝著咖啡。
“今天怎么來得這么早?看樣子,你沒睡好啊?”Alice問道。
“當(dāng)然啦,昨天晚上我就來了。”Joe無精打采地回答道。
“怎么啦?”
“還不是因為新版本上線出了點兒問題”,Joe說道。“看來我們要把部署這件事好好討論一下,再這樣下去,不只我要來,你們也要和我一樣啦!呵呵!”
當(dāng)天下午,Joe邀請了運維團隊的主要負責(zé)人Tom和Steven,召開了一個關(guān)于部署問題的討論會。
Joe說道:“先請運維部門的Tom介紹一下上周末的新版本上線過程和發(fā)現(xiàn)的問題吧。”
Tom描述了上線部署全過程。
不可重復(fù)且不可靠、易出錯的手工部署過程
- 當(dāng)新版本開發(fā)測試完成后,由開發(fā)團隊的成員在瀏覽器上登錄運維平臺,填寫上線申請單。申請單的內(nèi)容包括新版本的上線部署步驟。
- 測試人員為了保證能夠升級部署成功,首先要復(fù)制生產(chǎn)環(huán)境中的程序和數(shù)據(jù)到本地的測試環(huán)境中,然后根據(jù)上線申請單中所描述的上線部署步驟進行操作,對上線步驟進行驗證。
- 運維人員登錄到運維平臺,收到上線申請單后,確認“已收到”。
- 運維人員發(fā)現(xiàn)上線部署步驟有問題,生產(chǎn)環(huán)境的路徑與上線部署步驟中描述的不一致。于是與開發(fā)人員進行溝通,讓開發(fā)人員修改上線部署步驟。
- 開發(fā)人員修改后,再次通知測試人員和運維人員查看并確認。
- 確認無誤后,運維人員根據(jù)部署計劃,登錄到生產(chǎn)環(huán)境中,依照上線部署步驟,手工操作完成。
“上周末上線部署時出現(xiàn)的情況是:在本次部署之前,我們的集群中,有兩臺機器因HotFix,其程序配置被修改過,與其它機器不一致。因此,該機器上的部署失敗,導(dǎo)致部分服務(wù)不可用。運維人員查了很長時間沒有發(fā)現(xiàn)問題,星期日打電話把Joe叫來幫助我們查問題時,Joe才回憶起有那么一次HotFix,但當(dāng)時負責(zé)的運維人員已經(jīng)離職,沒人其它運維人員知道這件事情。”Tom說道,“我們對問題進行了分析,認為應(yīng)該加強我們的上線流程管理,對于那種HotFix也應(yīng)該發(fā)起一個審批流程,并且在該流程中不但要主要負責(zé)人審批,而且要對相關(guān)人發(fā)出周知通報。另外,我們的運維人員應(yīng)該對上線單進行嚴格審核,并對部署中所涉及的機器進行更詳細的驗證,對生產(chǎn)環(huán)境中的任何修改都要進行登記。即使非常緊急,也要在事后補充記錄一下。”
“這些方法固然很好,但其實我們可以采用更好的辦法來解決。”Joe接著說到,“假如我們在部署運維工作也能夠借鑒持續(xù)集成的做法,利用一些最佳實踐,那么這次部署事故根本就不會發(fā)生。比如(1)將部署操作腳本化;(2)進行持續(xù)部署驗證測試;(3)部署腳本通用化,環(huán)境變量等使用配置方式傳入;(4)讓測試環(huán)境盡可能與生產(chǎn)環(huán)境一致,至少在成本條件允許的情況下盡量保持相似;(5)對環(huán)境配置進行版本控制;(6)任何人不得直接對生產(chǎn)環(huán)境進行直接的手工操作,等等。”
將部署操作腳本化,并進行部署驗證測試
Bob說道:“嗯,其實那些上線步驟中所描述的內(nèi)容都可以進行腳本化,之前也討論過這一問題。目前上線步驟中的內(nèi)容基本都可以寫成自動化腳本,即使現(xiàn)在不行,也可以通過少量改造,使其可以自動化。但問題是... ...”Bob猶豫了一下,接著說道,“如何來驗證這些腳本是正確的呢?”
Joe 說道:“保證運維人員是如何驗證上線申請單上的上線步驟是正確的呢?同樣,我們也可以做一些部署驗證就行了。這些部署的驗證也可以通過腳本方式來進行,比如在安裝之前驗證程序所用端口沒有被占用,安裝之后驗證該端口已被該程序所使用;比如安裝之前驗證程序日志中記錄了該程序已停止運行,在安裝之后驗證程序日志中刻錄該程序已重新啟動;等等”。
Alice問道:“那我們還要調(diào)試這些部署腳本呀?沒有線上生產(chǎn)環(huán)境,我們怎么調(diào)試呢?”
各類環(huán)境盡可能相似,并使部署腳本通用化
Joe 回答道:“首先我們應(yīng)該加強基礎(chǔ)設(shè)施這方面的投入。在力所能及的情況下,讓測試環(huán)境與生產(chǎn)環(huán)境相似。比如,生產(chǎn)環(huán)境可能有100臺機器的集群,那我們至少要找兩臺機器的集群做測試環(huán)境。生產(chǎn)環(huán)境中使用Tomcat,我們的測試環(huán)境和開發(fā)環(huán)境中也應(yīng)該使用相同的Tomcat,而不用Jetty。”
Joe 停下來,喝了一口咖啡,接著說道:“這樣一來,我們的部署腳本就可以在開發(fā)環(huán)境、測試環(huán)境進行測試了。當(dāng)開發(fā)人員進行本地測試時,可以使用這個腳本進行單機的部署。當(dāng)測試人員進行集成測試時,可以使用同樣的腳本進行多機部署。與機器數(shù)量無關(guān)的配置可以統(tǒng)一放在某配置文件中。而與機器數(shù)量等相關(guān)的配置可以放在另外的配置文件中。由于在真正上線部署之前,開發(fā)人員和測試人員已經(jīng)使用同一個腳本進行多次部署,就是對該腳本進行的測試。當(dāng)我們上線部署時,只有與機器相關(guān)的配置文件會有變化,其它配置基本相同,所以上線部署時腳本出錯的幾率已經(jīng)比較小了。而且,這種自動化沒有人工干預(yù),也不會發(fā)生手工誤操作。”
Tom問道:“那這些腳本由誰來寫?由誰維護呢?”
Joe回答道:“誰最了解情況,就由誰來寫。其實,我們也應(yīng)該像對待產(chǎn)品代碼一樣,來對待這些腳本和配置文件,把它們放在我們的代碼庫里,進行版本控制。無論是運維人員還是開發(fā)人員,或者測試人員,對這些腳本的修改都應(yīng)該提交到版本控制庫中,除非他所做的修改只是為了測試他自己在本地的程序,那就不用提交了。這樣一來,‘誰在什么時候?qū)κ裁催M行了修改,為什么做修改?’這個審計問題就可以直接由版本控制系統(tǒng)來回答,也就做到了所有內(nèi)容可追蹤了。”
對環(huán)境管理進行版本控制,杜絕對生產(chǎn)環(huán)境的手工直接修改
“聽上去,對于配置文件、腳本等進行版本管理的確是解決了運維部署的很多問題。但如何對環(huán)境管理進行版本控制呢?”Tom問道。
Joe想了想,說道:“環(huán)境管理比較復(fù)雜。一般來說,環(huán)境包括幾個層次,包括硬件及網(wǎng)絡(luò)配置、操作系統(tǒng)、我們的應(yīng)用程序所依賴的軟件堆棧及其配置、以及我們的應(yīng)用程序運行時所需的數(shù)據(jù)及其配置。目前對我們來說,對于硬件及網(wǎng)絡(luò)配置、操作系統(tǒng)這兩層來說,有兩種方式進行管理。一種是利用一些專用軟件進行自動化的遠程配置,即只要給機器加電,就可以通過一些技術(shù)對一臺機器進行系統(tǒng)的安裝與配置。另一種是使用虛擬化技術(shù)來進行系統(tǒng)配置管理。對我們現(xiàn)在的游戲平臺來說, 使用后者即可。只要將基本的環(huán)境做成虛擬機鏡像文件,并將其作為環(huán)境基線進行版本管理。當(dāng)然,由于鏡像通常較大,所以最好不要使用常見的版本控制工具(如subversion,Git等)進行,而使用某種簡單的機制即可。”
Joe停了一下,看看大家沒有提問的意思,于是接著說道:“至于基于其上的軟件堆棧及堆棧中各軟件的配置管理完全可以利用類似于CfEngine,Puppet或Chef的工具進行。這些軟件環(huán)境管理工具都提供某種領(lǐng)域?qū)僬Z言來描述軟件堆棧配置,并保存在文本文件中。這些工具一般通過服務(wù)器/客戶端的工作方式運行,客戶端向服務(wù)器發(fā)送請求,驗證本機器節(jié)點的軟件配置是否與服務(wù)器中的設(shè)置相符,如果不符,就會自動更新。尤其重要的是,這些更新操作都是冪等的,即無論這些配置在該客戶機上執(zhí)行多少遍,每次的結(jié)果狀態(tài)都是相同的。另外,它們通常能與版本控制工具集成。所以,只要將我們的軟件堆棧配置管理信息放到版本控制庫中,就可以同時管理數(shù)臺機器。”
“oh, 對不起,Joe,我想打斷一下,”Tom問道:“你能畫一個圖來解釋一下你剛才所說的這種軟件環(huán)境配置管理工具嗎?”
“當(dāng)然沒問題。”Joe拿起筆在白板上畫了一個Puppet的工作示意圖,如下圖所示。
“看上去清楚多啦。”Tom笑道,“通過這種方式,我們就只需要將版本控制庫中保存的配置信息簽出到本地,進行相應(yīng)的修改,再提交到版本控制庫中,這種工具就會自動幫我們完成必要的配置更新了。是這樣的嗎?”
“對,”Joe點了點頭,說道,“如果我們的部署腳本也是通過這種方式來做的,那么我們就根本沒有必要登錄到生產(chǎn)環(huán)境的機器上,進行手工操作了。而且,Puppet還提供一種Try Run功能,可以進行配置變更的模擬,讓你能夠?qū)Ρ纫幌伦兏昂蟮牟煌帯?rdquo;
Tom說道:“你說的這些聽上去都不錯。但并不是所有人都能夠修改生產(chǎn)環(huán)境的配置信息的。所以我們還是需要一個軟件平臺來管理上線的申請審批流程。”
“在任何企業(yè)中,這種申請審批流程和生產(chǎn)環(huán)境變更的授權(quán)都是必要的,但這僅僅是審核流程的操作。而真正與軟件部署相同的具體操作都不應(yīng)該在這種審批流程當(dāng)中。”Joe回答道。
Tom接過話來,說道:“嗯,這樣的話,我們?nèi)耘f能夠做到:有權(quán)限的人才能真正修改生產(chǎn)環(huán)境的配置文件,同時達到了無人真正直接操作生產(chǎn)環(huán)境的目的,避免了手工誤操作帶來的問題。”
參加本次會議的測試人員和運維人員對這種做法產(chǎn)生了濃厚的興趣,并要求開發(fā)人員給予配合,將目前游戲平臺的部署自動化。Tom說道:“這就是我們運維工作的一個方向。讓枯燥易出錯的重復(fù)性手工操作變成受控的自動化,從而解放運維人員,讓我們可以關(guān)注于更加有價值的運行監(jiān)控等工作中。”
Alice說道:“這看上去還是有一定的工作量啊。”
“當(dāng)然,我們可能需要做一些工作,但我想這些投入是值得的。”Joe回答道。“同時,還需要各種角色之間更緊密的配合,而不是像之前那樣,通過一個代表上個世紀八十年代先進技術(shù)的辦公自動化平臺來描述部署上線步驟這類關(guān)鍵的業(yè)務(wù)操作信息。”
Tom也點了點頭,說:“嗯,應(yīng)該使用版本控制方式。但我們還是需要一個上線審批的流程,只不過,這個流程中不再保存上線步驟這類與實際部署相關(guān)的業(yè)務(wù)信息,而只是為了部署人員的資格審核與信息周知的目標(biāo)。”
經(jīng)過一番討論,開發(fā)、測試和運維團隊在這件事情上達成了一致,并按計劃開始實施了。
需要注意的是,他們似乎沒有談到數(shù)據(jù)管理。他們會遇到相關(guān)的問題嗎??
it知識庫:持續(xù)集成之“自動化部署”,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。