Jenkins+Docker搭建持續集成測試環境

本文將重點討論在Jenkins管理的持續集成以及測試的環境中,我們如何通過引入Docker來優化資源的配置,提高整個環境的性能以及穩定性。

關於Jenkins

Jenkins是被廣泛應用的持續集成、自動化測試、持續部署的框架,甚至有些項目組順便將其用來做流程管理的工具。根據任務的多寡,Jenkins通常有兩種典型的部署方式。

  1. 單節點(Master)部署
    這種部署適用於大多數項目,其構建任務較輕,數量較少,單個節點就足以滿足日常開發所需。

  2. 多節點(Master-Slave)部署
    通常規模較大,代碼提交頻繁(意味着構建頻繁),自動化測試壓力較大的項目都會採取這種部署結構。在這種部署結構下,Master通常只充當管理者的角色,負責任務的調度,slave節點的管理,任務狀態的收集等工作,而具體的構建任務則會分配給slave節點。一個Master節點理論上可以管理的slave節點數是沒有上限的,但通常隨着數量的增加,其性能以及穩定性就會有不同程度的下降,具體的影響則因Master硬件性能的高低而不同。


關於Docker

Docker是一款針對程序開發人員和系統管理員來開發、部署、運行應用的一款虛擬化平臺。Docker 可以讓你像使用集裝箱一樣快速的組合成應用,並且可以像運輸標準集裝箱一樣,儘可能的屏蔽代碼層面的差異。Docker 會盡可能的縮短從代碼測試到產品部署的時間。簡單來說Docker提供了一種技術,可以讓開發人員方便地將應用代碼已經運行時的環境一併打包到一個鏡像中,然後將這個鏡像上傳至鏡像倉庫。在測試或者產品環境只需要下載這個鏡像然後將其啓動就完成了部署(就好比打開一個集裝箱那麼簡單)。關於Docker更詳細的內容請參考官網文檔。


當前Jenkins遇到的困難

隨着敏捷開發的普及,自動化測試成爲每個項目的必須。一個經過多年開發的項目,其累積的自動化測試數量是驚人的。爲了保證每次的部署都是正確的,就需要每次迴歸所有的自動化測試用例。根據項目的不同,有些需要每週跑一輪迴歸測試,而有些項目則需要每天一輪。所以我們會把所有的測試用例進行分組,同時在多臺測試機上運行,以減少一輪測試所需要的時間。而這就要求我們有足夠多的硬件資源來滿足這需求。下圖展示了一個典型的通過Jenkins來管理自動化測試的拓補結構。一臺Master主機管理多臺測試機,Master將測試任務分配給測試機。


當前Jenkins(Master-Slave)結構

這種結構存在一些缺陷:

  1. 自動化的測試通常都是通過捕捉屏幕控件來模擬用戶的行爲以達到測試的目的,這就意味着一臺測試機上只能同時運行一組測試用例,否則用例之間就會相互干擾。這就存在資源浪費,因爲測試機的配置往往可以支持多組測試用例。

  2. 維護人員得確保測試機都保持在線,當測試機器數量較多的時候,比如100臺甚至1000臺的時候,這維護的壓力就比較大。

  3. 通常回歸測試是在晚上運行(如此就能在開發組第二天上班時發現前一天提交的代碼是否正確),但這上百臺測試機不論白天晚上都在工作狀態,這是另一維度的浪費。

  4. 很重要的一點,測試機器會因爲各種原因導致測試環境被污染,導致測試不能順利進行,而此時除了維護人員手工處理外,沒有特別好的方案。

  5. 之前我們提到過,當slave數量達到一定程度的時候,作爲Master的節點就會出現性能變差,穩定性下降。

  6. 每個Slave節點在開始跑測試之前都需要從中央庫下載最新的分發包,解壓,設定運行環境。這個過程通常也佔用不少時間,想象一下,突然間上百個slave開始下載最新的庫,這對中央庫是一個極大的衝擊。


如何引入Docker來解決這些問題

很自然的一個想法就是將測試機全部替換成Docker容器(Container),而管理這些容器的工作交給更專業的工具,如Google的Kubernetes或者Docker官方提供的Swarm。所有構建的環境都打包進Docker的鏡像文件中,自動化測試是一個鏡像,編譯單元測試是一個鏡像等等。改進後的拓撲結構如下圖所示:


引入Docker以後的結構

在這個方案中唯一的技術問題是自動化測試需要桌面系統,而通常Docker容器中運行的都是無圖形界面的應用。解決的方法也非常直接,我們在容器中提供桌面系統(VNC服務)。根據不同的Linux發行版本,我們可以選擇TightVNC或者TigerVNC。不論選擇哪種VNC‎服務,他們都提供一個虛擬桌面,可以通過VNC‎的客戶端遠程連接到該桌面進行操作。

對應前文提到的6個不足,在這種結構下悉數得到了解決。

  1. 每個測試機可以同時運行多組自動化測試用例,也就是說跑原來相同數量的迴歸測試,這種方案下可以至少節省一半的測試機。

  2. 通過Kubernetes或者Swarm,我們可以實現對容器的自動化管理,從而減輕維護人員的工作。

  3. Docker容器可以根據需要動態增減,又因爲構建所需的一切環境都被封裝在Docker的鏡像中,這些測試機器可以被方便的用於其他任務的構建,而不需要進行額外的配置。只需要下載其他構建任務的鏡像,然後將其啓動。

  4. 每次測試啓動一個全新的容器,所以環境是完全乾淨的。當某個容器出現問題的時候,這個容器就會被銷燬,同時新起一個容器完成相同的測試工作。

  5. 在這種結構下Jenkins只需要管理一個slave節點,而Kubernetes和Swarm則可以管理成千上萬個容器。

  6. 在同一個Docker環境中(同一臺測試機)只需要下載一次最新的自動化測試的鏡像就能起多個容器,而在這種結構下,測試機數量已經大大減少,從而對中央庫(私有鏡像倉庫)的衝擊也明顯減輕了。


更多的思考

一個項目開發了5年,就累積了上萬迴歸測試,需要幾十臺測試機不間斷的運行8、9個小時才能完成;設想下,這個項目還要繼續運行5年甚至10年呢?我們的測試機的數量將會是多少,我們的測試反饋週期還是8、9個小時麼?根據我們的觀察,經過多年的維護,很多功能模塊已經是非常完善,基本很少有代碼的修改。那麼這些功能對應的測試用例是否有必要每次都跑呢?答案我想是否定的,但問題是怎麼來判斷當前代碼的修改是否會影響到這些功能模塊呢?按照現在的設計,我想沒有人敢百分百的肯定。我們是否有必要對現有代碼做些調整,依照微服務的思想,把我們的分發包拆分下,每次只需要發佈有更新的模塊。如此一來我們遞歸的自動化測試用例也只需要包含有改動的那些模塊。那時候,很可能我們可以在每次代碼提交就運行一次迴歸測試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章