【Rancher企業容器云平臺】基于Docker的構建流程 (第一部分) - 持續集成及測試(上)

GemmaElphin 9年前發布 | 44K 次閱讀 Docker 虛擬化 Java

來自: http://dockone.io/article/1022

作者 : Usman Ismail, Bilal Sheikh (Rancher labs)

譯者:雷偉VivianLei(Cloudsoar云舒網絡)

Rancher Labs是一家容器技術基礎設施提供商,總部位于美國硅谷,Rancher是一個高效易用的企業容器云平臺。云舒網絡為Rancher labs的戰略合作伙伴 , 攜手Rancher Labs 共同實踐研究Docker容器生態圈。2016,Rancher | China 將會正式與大家見面!

在過去的一年里,我們寫了很多文章,關于如何在docker上運行不同stack(譯者注:在Rancher中,一個stack通常對應一個應用,它包含了一系列容器,及容器之間的關系描述),如:Magento, Jenkins, Prometheus等。然而,容器化部署不僅僅用于定義應用stack。在本系列文章中,我們將討論端到端的開發流程,包括在流程的各個階段如何平衡Docker和Rancher。具體涉及到:代碼構建,測試,打包,持續集成及部署,以及在生產環境中管理應用stack。您也可以同時下載本系列的電子書。

{網址: 文檔下載處 }

首先,我們從代碼構建開始。一般來說,代碼的構建/編譯不是很大的問題,因為大部分語言和編譯代碼的工具已很清楚,且有很完善的文檔說明。然后,隨著項目和團隊規模增長,模塊之間依賴關系變得復雜,如何確保代碼質量的同時,保證代碼構建的一致性和穩定性,將成為更大的挑戰。在本文中,我們將討論如何用Docker去實現CI(持續集成)和測試的最佳實踐。

一.構建系統擴展帶來的挑戰

首先,我們來看下維護構建系統所面臨的一些挑戰:

第一是依賴管理:當開發人員將庫集成到源代碼中時,需要注意的是,如何保證項目中所有模塊使用的同一個庫版本,且當庫版本升級時,如何能及時將新版本提交到項目中的所有模塊。

第二是環境依賴管理。包括IDE及IDE配置,工具版本(如maven, python版本)及相關配置,如代碼靜態分析規則,代碼格式化模版。環境依賴管理的麻煩在于,項目中的不同模塊會有依賴沖突,與代碼級沖突不同的是,模塊依賴沖突更難或是不能解決。比如,最近的一個項目里,我們用fabric進行自動化部署,用s75pxd上傳Artifacts到Amazon S3。不幸的是,fabric的最新版本需要python 2.7,但s75pxd需要python2.6。如要兼顧兩者,我們要么切換到s75pxd beta版本,要么用fabric的老版本。

最后,每個大型項目需要面臨的一個主要問題是構建時間。隨著項目規模擴大、復雜性增加,需要的語言也越來越多(我當前的項目使用Java, Groovy, Python和Protocol Buffers IDL)。測試中不同組件也會相互依賴,比如,測試時不能在同一時間運行共享數據庫中相同的數據(譯者注:同樣的系統環境,同一共享數據庫,不同人員同時測試時可能會引起數據沖突,后面實例會提到如添加同一用戶時,會導致用戶沖突)。這樣,我們需要在測試執行前確保初始狀態,測試完后再清理狀態。這將減慢開發進度。

二. 解決方案和最佳實現

為解決上述問題,一個好的構建系統需要達到如下要求:

· 可重復性

q能在不同的開發機器和自動構建服務器中,生成/創建有一致依賴關系的構建環境。

· 集中化管理

所有開發機器和構建服務器的構建環境,是來自于同一個代碼倉庫中心或服務器,且環境設置能及時更新。

· 隔離性

項目的各個子模塊相互隔離,而不是相互依賴。

· 并行性

并行構建子模塊,提高構建效率。

【可重復性】

大多數語言和開發框架支持自動化依賴管理。如Maven用于Java,python用pip,ruby用bundler。這些工具比較類似,當你提交一個索引文件(pop.xml, requirements.txt或gemfile)到源代碼控制器中,工具會自動下載相關依賴到構建機器中。我們測試后需集中管理這些文件,并提交到源代碼控制服務器中。然而,仍需管理環境依賴,如是否安裝了maven, python, ruby的正確版本。Maven自動檢測依賴的更新,但對pip和bundler,我們必須通過腳本來觸發更新。

【集中化管理】

為了安裝依賴管理工具和腳本,大部分小團隊通過文檔來描述。當團隊擴張時,如何保持實時依賴更新將會是關鍵。另外,構建環境的OS和平臺不同,也會引起工具的安裝差異。當然,你可以用配置管理工具,如puppet或chef(譯者注:puppet和chef均為跨平臺配置管理工具)去管理安裝包的依賴和配置文件的設置;提前測試后再提交并推送到所有開發者。同時puppet和chef也有一些不足:

1. 安裝配置不簡單,且完整功能的版本都是收費的;

2. 有自己單獨的語言進行配置(譯者注:如chef基于ruby語言);

3. 配置管理工具不具備隔離功能,工具版本沖突和并行測試仍是一個問題;

【隔離性】

為保證組建隔離,減少構建時間,可以用虛擬機自動化系統,如vagrant(譯者注:vagrant是一個基于Ruby的工具,用于創建和部署虛擬化開發環境)。vagrant 能創建并運行不同組建環境的虛擬機(盒子),這樣可以保證隔離和并行測試。vagrant的配置文件提交到源代碼控制器中,且推送到所有開發人員。另外,虛擬機(盒子)能用于測試,部署到Atlas,便于開發人員下載。不足在于:

1. 將需要更高層次的配置描述去設置vagrant;

2. 虛擬機也是一個非常重量級的隔離解決方案:雖然只需要一個測試運行環境或編譯環境,但每個虛擬機運行了一個完整的OS和網絡棧,還需提前分配內存和磁盤資源;

盡管有各種問題,用依賴管理工具(maven, pip, rake),配置管理工具(puppet, chef) 和虛擬化工具(vagrant),也能建立一個穩定、集中管理的構建系統,不是所有的項目都需要所有這些工具,但是任何長時間運行的大項目都需要自動化到這個程度。

三. 利用Docker進行系統構建

無需投入大量時間和資源,Docker和其生態系統能幫助我們支持上述工具。在本節中,我們將通過如下步驟來為應用創建集中化構建環境。

1. 集中化構建環境

2. 用docke打包應用

3. 用Docker compose生成構建環境

在本文及后續的文章中,為方便描述,我們將使用go-messenger作為示例應用。

在github上下載此應用。此系統的主要數據流如下圖所示,由兩個組件構成:RESTful認證服務器,用Golang所寫;會話管理,用于接收來自客戶端的TCP長連接和客戶端之間的路由信息。本文將重點關注RESTful認證服務(go-auth)。它包含了多個無狀態的web服務器和數據庫集群,數據庫集群用于存儲用戶信息。

  1. 集中化構建系統

    首先,需要創建一個包含了構建系統所需工具的容器鏡像,此鏡像的dockerfile如下所示,也可在此處下載。因為應用是用Go所寫,所以我們是基于官方的golang鏡像,安裝了godep依賴管理工具。如果你的項目是用java語言,同樣你可以基于java基本鏡像,安裝maven來代替godep。

然后添加一個編譯腳本,包含了構建和測試代碼的過程。腳本如下所示:

1. 使用godep restore下載依賴包;

2. 用go fmt格式化源碼;

3. 用go test運行測試;

4. 用go build編譯項目;

為確保可重復性,我們用docker構建一個有版本的容器鏡像,可以從Dockerhub上下載此鏡像,或通過Dockerfile構建。至此,所有的開發人員(和構建機器)都能通過此容器,用以下命令來構建任何go工程。

上面這條命令,我們運行了一個docker,鏡像為usman/go-builder,版本1.4。且通過-v 將源代碼mount到容器中,通過-e 配置了環境變量SOURCE_PATH。在此示例工程中,為測試go-builder,你可用以下命令來產生一個名為 go-auth的可執行文件,存放于go-auth工程的root目錄下:

隔離構建工具帶來的另一個好處是,可以很容易更換構建工具和其配置。如在上面的例子里,我們用的是golang1.4,用以上命令將go-build:1.4更改為go-build:1.5,可以很快測試本工程中是否能使用golang1.5。

為集中管理鏡像,我們可以將此構建容器的最新版本設置為固定版本,這樣所有開發者可直接使用go-builder:latest 來構建源代碼。如果工程中用到構建工具的不同版本,使用不同的容器構建即可,不用擔心在一個構建環境管理多個版本的問題。比如,用支持多版本的官方python鏡像,可以解決前面的python問題(譯者注:上文所描述的fabric和s75pxd對python不同版本的依賴問題:“fabric的最新版本需要python 2.7,但s75pxd需要python 2.6”)。

  1. 用Docker打包應用

    如果你想將二進制打包到容器,添加如下內容的 Dockerfile,運行“docker build -t go-auth”即可。在dockerfie中,將二進制輸出到一個新的容器;暴露9000端口來接入連接;配置運行二進制的入口參數。因為Go二進制是自包含的,我們用現有ubuntu鏡像即可。如你的項目需要一些依賴包,也可一同打包進容器。如生產一個war文件時就用tomcat容器。

  1. 用Docker compose創建build環境

    到現在為止,我們已經完成項目構建、實現可重復性、集中管理且隔離各種組件。我們還可以將構建流程擴展到集成測試中,這也突出了docker并行化加速構建的能力。

    測試不能并行的一個主要原因在于共享數據庫。在本示例項目中,用MySQL存儲用戶信息,也存在著類似的問題。測試新用戶注冊時,第一次測試注冊新用戶,當運行第二次測試時,由于注冊相同的用戶而導致用戶沖突錯誤。這就只能在完成一次測試后,清空注冊用戶再開始新一輪測試。

為設置隔離的并行構建,我們可以定義docker compose模版(docker-compose.yml),如下所示。其中定義了一個數據庫服務,使用MySQL官方鏡像并配置了一些環境變量。然后產生了一個GoAuth服務,用已將應用打包的容器,并將數據庫容器連接到此容器中。

通過運行docker-compose up,先將應用環境跑起來,然后通過運行如下curl命令來模擬集成測試,第一次運行會返回200表示成功,第二次將返回409表示沖突。最后,運行docker-compose rm來清理應用環境。

為了運行應用多個相互獨立的版本,需要更新docker compose模版,添加相同配置的服務database1和Goauth1,Goauth1唯一需要更改的是端口從9000:9000到9001:9000,保證應用暴露的端口不相沖突。完整的模版可在此下載。當再運行docker-compose up時,就能并行的運行兩個集成測試了。同樣的,當工程有多個獨立的子模塊時,此并行化的方式也可用于加速構建系統中,如多模塊的maven工程。

(未完待續)

====================================

【溫馨提示】

Rancher | China 推出" 【Rancher | 實戰群】 ",群內匯集了Rancher中國最強技術精英團隊及業內技術派高人,宗旨是為了大家實時與Rancher創始團隊面對面,交流Rancher實戰技術!同時歡迎各位分享自己的經驗、疑難問題,我們將定期邀請分享嘉賓做各類話題分享及回顧,共同實踐研究Docker容器生態圈。

對Rancher和Docker技術感興趣、或對本文中細節需繼續探討的朋友,歡迎加入本群參與討論,歡迎大家加入!

*加群方法:

關注【云舒網絡】公眾號

留言”我要加群“

</div>

 本文由用戶 GemmaElphin 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!