CD而生,順便淘汰了Jenkins

Jenkins是一個了不起的軟件。作為一個執行和自動化引擎,它是你能找到的最好的引擎之一。Jenkins是無數持續集成(CI)系統的關鍵組成部分,但它本身不是一個CI系統,它只是為你運行東西。它做得非常好,有各種內置的插件和充滿活力的插件生態系統,可以幫助你明白它在何時何地運行什麼。

從根本上講,CI旨在以儘可能高的頻率和儘可能少的摩擦將多個軟件開發流的工作集成到一個連貫的整體中。Jenkins並不知道你的源代碼,也不知道如何將它們合併在一起,也不知道如何提供建設性的反饋。當然,你可以將它與其他可以執行這些活動的軟件結合在一起,這就是CI系統包含Jenkins的方式。OpenStack也是如此。

沒有測試就不行

2010年,一個名為OpenStack的開源項目社區形成。一些參與協作基礎設施的開發人員還參與了一個名為“Drizzle”的免費數據庫項目,該社區的一個關鍵理念是“沒有測試就不行”。因此,OpenStack從最開始就要求,在被批准合併到任何源代碼倉庫的主幹之前,對所有提議的更改進行審查和迴歸測試。為此,Hudson(後來分叉形成Jenkins項目)被配置為每個更改都運行測試。

一個插件用來與Gerrit代碼評審系統接口,在提出新的更改時自動觸發作業,並用評審註釋返回報告,指出它們是成功還是失敗。以今天的標準來看,這可能還不成熟,但在當時,這是開源協作的革命性進步。在CI看來,OpenStack上沒有一個開發人員是特別的,每個人的更改都必須通過測試才能合併,這叫做“項目門控”。

然而,這種門控的想法有一個新的缺陷:為了保證兩個無關的更改不會以功能上不兼容的方式改變一個軟件,在它們合併之前,必須按順序逐個測試它們。當時,OpenStack的安裝和測試很複雜,並且很快就變得流行起來。開發人員貢獻的不斷增加,再加上測試覆蓋率的不斷提高,意味著在繁忙時期,根本沒有足夠的時間測試通過評審的每一個更改。一些運行時間更長的作業需要將近一個小時才能完成,因此可以通過門限的上限大約是一天內二十幾次更改。

迎來Zuul

在2012年5月的OpenStack CI會議上,CI團隊成員之一James Blair宣佈他“一直在研究Jenkins作業的推測性執行。”推測性執行是現代微處理器管道中最常見的一種優化。與處理器硬件類似,該理論認為,通過對最近批准但尚未完成測試的更改樂觀地預測正選通結果,隨後批准的更改可以同時測試,然後有條件地合併,只要其前任也通過測試併合並。James給智能調度程序取的名字是:Zuul。

在此時間範圍內,試圖對Jenkins的XML作業配置執行更好的修訂控制帶來的挑戰,導致了基於人類可讀YAML的Jenkins Job Builder模板引擎的創建。Jenkins的JClouds插件的有限成功,以及使用作業來刷新一次性Jenkins的雲鏡像的繁瑣嘗試,都隨著Nodepool服務的創建而結束。有限的日誌存儲能力使得團隊添加了單獨的外部解決方案,用於組織、服務和索引作業日誌,並假設維護了一個廢棄的安全複製協議(SCP)插件(取代Jenkins提供的現成的不太安全的FTP選項)。OpenStack基礎設施團隊圍繞著Jenkins慢慢地構建了一系列服務和實用程序,但是開始遇到性能限制。

勝過Jenkins

到2013年年中,Nodepool一直在回收多達100臺在Jenkins註冊為slave的虛擬機,但這已經不足以跟上不斷增長的工作量。Jenkins中全局鎖的線程爭用阻止了所有超過此閾值的嘗試,無論主服務器上有多少處理器功率和內存。該項目曾提出為Jenkins slave捐贈額外的能力,以幫助緩解頻繁的工作積壓,但這將需要一個額外的Jenkins master。多個master之間的有效分工需要一個新的通信渠道來調度和協調作業。Zuul的維護人員認為Gearman作業服務器協議是一個理想的匹配,因此他們為Zuul提供了一個新的geard服務,併為Jenkins擴展了一個自定義Gearman客戶端插件。

現在,工作分佈在越來越多的Jenkins master上,不再有任何一個單一的儀表盤可以完整地查看工作活動和結果。為了促進新的多master,Zuul開發了自己的status API和WebUI,以及通過StatsD協議發送指標的功能。在接下來的幾年裡,Zuul穩定地吸收了更多用戶所依賴的CI特性,而Jenkins在該系統中的地位也隨之下降。

OpenStack很早就選擇對Python編程語言進行標準化——這反映在Zuul的開發中,而Jenkins及其插件是用Java實現的。Zuul的配置以與OpenStack用來模板化Jenkins作業相同的YAML序列化格式進行維護,而Jenkins則將所有內容都保存在baroque XML中。這些差異使正在進行的維護複雜化,並導致來自相關社區的新管理員的學習曲線變得不必要的陡峭(這些相關社區已經開始嘗試運行Zuuls)。

又一次革命的時候到了。

Ansible的崛起

2016年初,Zuul的維護人員開始了一項雄心勃勃的為期一年的全面檢查,以期將Jenkins從整體系統設計中剔除。這時,Jenkins只是作為一個管道,通過SSH在slave上運行主要由shell腳本組成的作業,提供作業輸出的實時流,並將生成的結果複製到長期存儲。人們發現Ansible非常適合第一個需求——它是專門為通過SSH遠程運行命令而構建的,它是用Python編寫的(就像Zuul一樣),還使用YAML來定義它的任務。它甚至還為先前作為定製Jenkins插件實現的功能提供了內置模塊。Ansible提供了真正的多節點即時支持,因此相同的palybook可用於模擬和執行復雜的生產部署。不斷擴展的第三方模塊生態系統填補了空白,就像以前Jenkins社區的插件一樣。

一個新的Zuul執行器服務填補了Jenkins master之前的角色:它對調度程序geard中的掛起的請求執行操作,通過Ansible將它們發送到Nodepool管理的臨時服務器,然後收集結果和工件以供發佈。它還公開了基於經典RFC 742 Name/Finger協議的正在進行的build輸出,從Ansibe的命令輸出模塊的擴展進行實時流式傳輸。一旦不再需要將作業限制在Jenkins的解析器可以理解的範圍內,Zuul就可以自由地增加新的功能,比如分佈式存儲庫作業定義、在具有繼承和安全處理機密的項目之間共享,以及測試為作業本身提出更改的能力。Jenkins的時代終於要結束了。

關於未來

Zuul的社區喜歡說,它通過預測性執行的新穎應用“測試未來”。曾經,你想對現有的作業進行改進,會擔心一旦應用到生產中是否會使它失去功能,現在這種令人痛心的日子一去不復返了。大型中央作業存儲庫的過載審查團隊已經成為過去。作業被視為軟件的一部分,並與其他源代碼一起提供,利用Zuul的其他功能(如跨存儲庫依賴關係),這樣,你對一個項目中作業的一部分所做的更改可以與另一個項目中的提議作業更改一起執行。它甚至會對你的作業更改進行評論,突出顯示有語法問題的特定行,就像是一個代碼審閱者給你提供建議一樣。

這些都是Zuul以前夢寐以求的功能,但這些需要從Jenkins那裡獲得自由,這樣它就可以將作業解析交給自己。這是CI的未來,Zuul的用戶可以實現這一點。

2019年初,OpenStack基金會承認Zuul是一個獨立的、公開治理的項目,擁有自己的身份和繁榮的社區。如果你對開源CI感興趣,可以考慮一下參與Zuul下一個演進的開發。

原文鏈接:

https://superuser.openstack.org/articles/introducing-zuul-for-improved-ci-cd/


分享到:


相關文章: