放棄"Jenkins"的種種理由,期待更好賦能研發(fā)的"持續(xù)交付平臺"

Jenkins 很酷,但是不完美,有歷史局限性造成的問題。本文僅從“如何更好給研發(fā)團隊賦能的角度”,剖析Jenkins, 探討理想的持續(xù)交付平臺, 不帶貨無廣告~

不完美的Jenkins

  • Jenkins的前身是Hudson, Hudson是SUN公司時期就有的CI工具,后來因為ORACLE收購SUN之后的商標之爭,創(chuàng)始人KK搞了新的分支叫Jenkins 。今天的Hudson還在由ORACLE持續(xù)維護,但風頭已經(jīng)遠不如社區(qū)以及CloudBees驅(qū)動的Jenkins.
  • Hudson 被 Jenkins 取代后,不再維護,并于 2017 年 2 月宣布已過時。Hudson 網(wǎng)站 hudson-ci.org 于 2020 年 1 月 31 日關閉
  • 關于Hudson 和Jenkins的恩怨,有興趣可查閱 www.oschina.net/news/63453/…

提到DevOps/持續(xù)集成這些話題,由于開源免費,歷史悠久,插件API豐富,群眾基礎好(可借鑒模仿案例實踐資料多)等原因,Jenkins永遠是那個最亮的“仔”,也是眾多相關領域廠商或者企業(yè)繞不開的“工具”。
不過,依然有很多“不完美”,僅僅是個沒有“DevOps靈魂”的CI工具(理由如下),但不得不承認它又是“免費”又有“用戶量”的CI工具。下面我通過以下幾個方面詳細做些剖析

歷史遺留問題

首先 Jenkins 是一個巨石系統(tǒng),它是一個單體的結(jié)構(gòu)。為什么到現(xiàn)在為止大家好像沒有看過特別成熟的 Jenkins 集群級的方案,或者很少看到高可用的方案,大部分情況下大家看到的是給不同的團隊或者是不同的部門分配多個 Master ,而不是共用一個大的 Master ,其實這個主要取決于 Jenkins 內(nèi)部的實現(xiàn)原理和機制。

傳統(tǒng)意義上來講一個服務會有兩層,一層是你的服務層,一層是你的數(shù)據(jù)層。但是 Jenkins 因為歷史的一些原因,導致所有的存儲都是以文件的方式存儲在磁盤上,存儲在磁盤上就會一個比較大的性能問題。在 Jenkins home 里有一個 jobs ,里面存儲的就是大家構(gòu)建的每一個任務,還會存構(gòu)建任務的配置等等。一系列的東西都以文件的方式,以特定的目錄結(jié)構(gòu)存儲在磁盤上。

當 Jenkins 第一個步驟,比如你重啟 Jenkins 的時候,它會做什么?先把磁盤上 jobs 目錄都掃一遍,加載到自己的內(nèi)存里里,再去做后續(xù)的東西。比如剛才說的高可用的方案,假如用共享存儲,現(xiàn)在在一臺 Jenkins Master 上寫了一個job,其實另一臺 Jenkins 是沒有感知的,因為沒有加載這個job。

學習成本

Jenkins 的插件那么多,到底該選哪一個?而且出現(xiàn)很多問題是1+1小于2,有時候必須安裝第二個插件來滿足,兩個插件組合的時候又可能達不到很好的合力,這導致很多業(yè)務場景不得不去裝很多額外的插件來滿足自己的需求。開發(fā)者對 Jenkins 熟識的程度大部分在于自己插件的使用經(jīng)驗。

可維護性

當jenkins支持的場景越復雜,你會發(fā)現(xiàn)你要管理很多插件,這是你構(gòu)建Jenkins和復制Jenkins面對最大的問題;同時,插件由于是個人貢獻維護,很多插件會有年久失修情況。

安全性

Jenkins的插件包括Jenkins本身,它是有一些漏洞的,當你去用一些插件的時候,你要不停的更新它。

性能

不知道有沒有人在一個Jenkins中配200個人,你肯定碰到到第80個人的時候,整個用戶配置界面會卡。

要想 Jenkins 用得好,插件不能少。但是 Jenkins 的插件會帶來一些性能問題,每一個插件都是在項目啟動的時候就會加載到內(nèi)存里,當插件越大的時候,對性能的損耗越大。要選擇自己合適的插件去構(gòu)建自己的 Jenkins 。

  • 第一個是插件,要選擇一些合適數(shù)量的插件,滿足需求的插件,盡量少的插件會比較好;
  • 第二個是job,在 Jenkins 官方的文檔上講,當你的job超過1000個以上的時候, Jenkins 就會有一些性能問題。手動創(chuàng)建 user 80個以上就會有卡頓,job那個地方是第一次都加載進來的,而 user 是每次都會去掃盤,然后去加載XML;
  • 第三個是slaves;
  • 第四個是每一個節(jié)點上的 executor

其他問題

  • 對于不熟悉DevOps的工程師,學習成本其實不低,或者說離最佳實踐差的太遠
  • 沒有“DevOps最佳實踐”規(guī)范約束Jenkinsfile
  • 項目隔離/權(quán)限分配方案的缺陷
  • 集成配置比較“散亂”
  • Jenkins的能力來源于插件,需要額外配置,部分插件過于老舊/兼容性
  • UI丑陋,無法滿足復雜UI交互

現(xiàn)實中持續(xù)交付對平臺的要求

拋開Jenkins上面的缺點不談,回到現(xiàn)實場景中,我們需要從更大的視角(即持續(xù)交付)來理解一個“持續(xù)交付平臺”需要扮演的角色。

從上圖中可以看出,從開發(fā)人員寫下代碼到服務最終用戶是一個漫長過程,整體可以分成三個階段:

  1. 從代碼(Code)到制品庫(Artifact):這個階段主要對開發(fā)人員的代碼做持續(xù)構(gòu)建并把構(gòu)建產(chǎn)生的制品集中管理,是為部署系統(tǒng)準備輸入內(nèi)容的階段。
  2. 從制品到可運行服務:這個階段主要完成制品部署到指定環(huán)境,是部署系統(tǒng)的最基本工作內(nèi)容。
  3. 從開發(fā)環(huán)境到最終生產(chǎn)環(huán)境:這個階段主要完成一次變更在不同環(huán)境的遷移,是部署系統(tǒng)上線最終服務的核心能力。

如果從持續(xù)交付角度看,其最核心訴求就是要讓上圖三個階段能夠無縫連接并自動化運行起來,從而達到持續(xù)交付的兩個核心目標:提高交付頻率(部署次數(shù))和降低部署延時(從代碼提交到上線的時間差)。
參照如上持續(xù)交付的流程,可以發(fā)現(xiàn)持續(xù)交付對于一個部署系統(tǒng)的要求絕對不僅僅是一個自動化的部署過程,這也是在有了Jenkins和其相關部署插件后仍然需要搭建獨立部署系統(tǒng)的原因所在。具體來說,我們可以從下面幾點分析:

解耦構(gòu)建和部署過程

盡管持續(xù)交付希望自動化完成從代碼到部署上線的整個流程。但是整個持續(xù)交付過程有多個不同角色的人參與其中(開發(fā)、測試、運維甚至還經(jīng)理及市場人員)。其中有些角色(如開發(fā)/測試)需要關心構(gòu)建過程,而更多的角色(如運維等)絕大時候都是從制品開始部署工作。這也就要求構(gòu)建和部署過程相互解耦,能夠獨立操作。

構(gòu)建和部署這兩個過程通過制品(Artifact,又稱為部署包)連接(制品是構(gòu)建過程的產(chǎn)出,同時是部署過程的輸入)。如果它們相互解耦,自然就需要有統(tǒng)一的地方管理存儲和管理這些制品,即統(tǒng)一制品庫。
有了統(tǒng)一制品庫后,構(gòu)建過程自動提交產(chǎn)生的制品到此,而部署過程則主動到制品庫拉取需要的制品進行部署,從而實現(xiàn)構(gòu)建和部署的完整解耦。

管理復雜的部署環(huán)境

服務上線需要涉及到很多不同目的環(huán)境(開發(fā)、測試、預發(fā)、生產(chǎn)、演示等)。在云化基礎設施中,環(huán)境內(nèi)部的資源會頻繁變化(例如,Auto-Scaling時刻都有可能添加或者減少你的云主機)。
這時候需要對部署流程隔離部署環(huán)境差異以及環(huán)境內(nèi)頻繁變化的基礎設施。當需要執(zhí)行一個部署時,操作人員只需要指定部署到哪個環(huán)境(即環(huán)境名稱或者ID號),而不需要關心環(huán)境內(nèi)部的任何信息,只需把部署請求分發(fā)到指定環(huán)境內(nèi)的每臺主機并自動執(zhí)行。

如果基于Jenkins來直接部署,則必然把環(huán)境管理的很多復雜度引入到部署流程內(nèi)部。

支持多種部署策略

為保障服務的高可用,落實部署和發(fā)布的解耦以及其他業(yè)務需要,用戶常需要支持如灰度發(fā)布、A/B測試發(fā)布等部署需求。一個獨立的部署系統(tǒng)在此可以提供多種部署策略,并結(jié)合環(huán)境管理等其他功能滿足業(yè)務上對部署和發(fā)布的各種需求。

同樣,Jenkins及其部署插件并沒有提供這樣的能力。

落實部署流程規(guī)范

在一個公司內(nèi)部經(jīng)常有不同的項目,使用不同的編程語言,而部署流程也五花八門。從控制風險,減少重復操作,降低部署自動化難度等多重考量,公司都傾向制定一套標準的部署流程。
這時候,獨立的部署系統(tǒng)就可以幫助用把這些規(guī)范落實下去并在日常的部署過程中時刻校驗(在軟件工程領域,幾乎所有的規(guī)范落實都得靠工具來助一臂之力,否則基本都會變成紙面上的規(guī)范而已)。

如果基于Jenkins來直接部署,如何落實這些部署規(guī)范仍然是一個很困難的事情,因為Jenkins及其部署插件并未對此提供任何實質(zhì)性的支持。

獲取研發(fā)過程數(shù)據(jù)

部署是一個團隊從代碼到服務的關鍵路徑,這上面的所有操作數(shù)據(jù)都值得記錄并用于各種運營支持(包括安全審計、部署記錄查詢、部署頻率和失敗率分析等等)?;贘enkins直接部署當然也可以獲取這些數(shù)據(jù),但是把它做在獨立的系統(tǒng)內(nèi)會更靈活和方便。

讓部署操作服務化

如之前提到,部署不僅僅開發(fā)和測試人員需要,要努力讓部署服務化,從而讓團隊內(nèi)任何一個人都可以隨時觸發(fā)一次部署。Jenkins的操作界面對于開發(fā)或者測試人員可能還比較方便,但是對于其他人員來說則過于復雜。
當然,除了上面列出的這些原因外,你還要解決部署版本的管理等,這里就不一一列舉。

持續(xù)交付平臺的特質(zhì)

如前所述,一個理想的持續(xù)交付系統(tǒng)需要包括的內(nèi)容是非常豐富的,特別是要面臨各種復雜場景,不同技術(shù)棧的團隊,異構(gòu)的各種內(nèi)部系統(tǒng)(絕對不僅僅是Jenkins插件要做的那些事情)。

如下圖所示,持續(xù)交付系統(tǒng)需要連接項目中涉及的人、代碼,制品庫,以及環(huán)境等,Jenkins僅僅起到了簡單的連接作用。

  • 對于簡單的場景,或者較小團隊來說,通過Jenkins各種插件來完成持續(xù)交付活動,是足夠的。
  • 對于更大的團隊,或更高要求的組織,它最終希望的目標是打通從代碼(甚至需求)到最終服務的整個流程(如下圖)。

所以,能夠給研發(fā)過程賦能的“持續(xù)交付平臺”需要具備如下特點

  • 能夠管控好“代碼”,“制品”,和“環(huán)境”,整個過程都是圍繞這些做文章的
  • 隱藏底層的細節(jié),對不同角色要友好,提供自助式的服務
  • 控制好和外部系統(tǒng)的集成,少侵入,多融合
  • 控制好過程的“輸入”和“輸出”,聚焦體系化流程框架
  • 正向引導用戶做正確的事,賦能組織,而不是“讓用戶困擾”

期待更好的持續(xù)交付平臺

DevOps持續(xù)交付涉及的工具如同各類不同形狀的積木,你的目標是建造一個房子,可能你現(xiàn)在手中只有很少的積木,或者你有很多重復的積木,但是唯獨缺少三角形完成屋頂部分。

  • 想清楚房子要多大?多豪華?
  • 自己手里有什么,缺什么?
  • 工具搭配是否合適?是否漂亮?
  • 誰是主角,誰是配角?
  • 誰是從別人那里借來的,未來可能要還的
  • 一個房子也能玩,多個房子玩的更好,先搭建哪個?

想清楚不迷路,不同的人搭建方法不同,只要最后搭建合理漂亮實用,恰到好處就可以,期待更好賦能研發(fā)過程的持續(xù)交付平臺~

本文使用 文章同步助手 同步

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容