放棄"Jenkins"的種種理由,期待更好賦能研發的持續交付平臺

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

不完美的Jenkins

  • Jenkins的前身是Hudson, Hudson是SUN公司時期就有的CI工具,後來因爲ORACLE收購SUN之後的商標之爭,創始人KK搞了新的分支叫Jenkins 。今天的Hudson還在由ORACLE持續維護,但風頭已經遠不如社區以及CloudBees驅動的Jenkins.
  • Hudson 被 Jenkins 取代後,不再維護,並於 2017 年 2 月宣佈已過時。Hudson 網站 hudson-ci.org 於 2020 年 1 月 31 日關閉
  • 關於Hudson 和Jenkins的恩怨,有興趣可查閱 https://www.oschina.net/news/63453/hudson-and-jenkins-grievances

提到DevOps/持續集成這些話題,由於開源免費,歷史悠久,插件API豐富,羣衆基礎好(可借鑑模仿案例實踐資料多)等原因,Jenkins永遠是那個最亮的“仔”,也是衆多相關領域廠商或者企業**繞不開的“工具”。

不過,依然有很多“不完美”,僅僅是個沒有“DevOps靈魂”的CI工具(理由如下),但不得不承認它又是“免費”又有“用戶量”的CI工具。下面我通過以下幾個方面詳細做些剖析**

歷史遺留問題

首先 Jenkins 是一個巨石系統,它是一個單體的結構。爲什麼到現在爲止大家好像沒有看過特別成熟的 Jenkins 集羣級的方案,或者很少看到高可用的方案,大部分情況下大家看到的是給不同的團隊或者是不同的部門分配多個 Master ,而不是共用一個大的 Master ,其實這個主要取決於 Jenkins 內部的實現原理和機制。

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

當 Jenkins 第一個步驟,比如你重啓 Jenkins 的時候,它會做什麼?先把磁盤上 jobs 目錄都掃一遍,加載到自己的內存裏裏,再去做後續的東西。比如剛纔說的高可用的方案,假如用共享存儲,現在在一臺 Jenkins Master 上寫了一個job,其實另一臺 Jenkins 是沒有感知的,因爲沒有加載這個job。

學習成本

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

可維護性

當jenkins支持的場景越複雜,你會發現你要管理很多插件,這是你構建Jenkins和複製Jenkins面對最大的問題;同時,插件由於是個人貢獻維護,很多插件會有年久失修情況。

image.png

安全性

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

性能

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

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

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

其他問題

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

現實中持續交付對平臺的要求

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

image.png

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

  1. 從代碼(Code)到製品庫(Artifact):這個階段主要對開發人員的代碼做持續構建並把構建產生的製品集中管理,是爲部署系統準備輸入內容的階段。
  2. 從製品到可運行服務:這個階段主要完成製品部署到指定環境,是部署系統的最基本工作內容。
  3. 從開發環境到最終生產環境:這個階段主要完成一次變更在不同環境的遷移,是部署系統上線最終服務的核心能力。

如果從持續交付角度看,其最核心訴求就是要讓上圖三個階段能夠無縫連接並自動化運行起來,從而達到持續交付的兩個核心目標:提高交付頻率(部署次數)和降低部署延時(從代碼提交到上線的時間差)。

參照如上持續交付的流程,可以發現持續交付對於一個部署系統的要求絕對不僅僅是一個自動化的部署過程,這也是在有了Jenkins和其相關部署插件後仍然需要搭建獨立部署系統的原因所在。具體來說,我們可以從下面幾點分析:

解耦構建和部署過程

儘管持續交付希望自動化完成從代碼到部署上線的整個流程。但是整個持續交付過程有多個不同角色的人蔘與其中(開發、測試、運維甚至還經理及市場人員)。其中有些角色(如開發/測試)需要關心構建過程,而更多的角色(如運維等)絕大時候都是從製品開始部署工作。這也就要求構建和部署過程相互解耦,能夠獨立操作。
構建和部署這兩個過程通過製品(Artifact,又稱爲部署包)連接(製品是構建過程的產出,同時是部署過程的輸入)。如果它們相互解耦,自然就需要有統一的地方管理存儲和管理這些製品,即統一製品庫。
有了統一製品庫後,構建過程自動提交產生的製品到此,而部署過程則主動到製品庫拉取需要的製品進行部署,從而實現構建和部署的完整解耦。

管理複雜的部署環境

服務上線需要涉及到很多不同目的環境(開發、測試、預發、生產、演示等)。在雲化基礎設施中,環境內部的資源會頻繁變化(例如,Auto-Scaling時刻都有可能添加或者減少你的雲主機)。

這時候需要對部署流程隔離部署環境差異以及環境內頻繁變化的基礎設施。當需要執行一個部署時,操作人員只需要指定部署到哪個環境(即環境名稱或者ID號),而不需要關心環境內部的任何信息,只需把部署請求分發到指定環境內的每臺主機並自動執行。

如果基於Jenkins來直接部署,則必然把環境管理的很多複雜度引入到部署流程內部。

支持多種部署策略

爲保障服務的高可用,落實部署和發佈的解耦以及其他業務需要,用戶常需要支持如灰度發佈、A/B測試發佈等部署需求。一個獨立的部署系統在此可以提供多種部署策略,並結合環境管理等其他功能滿足業務上對部署和發佈的各種需求。同樣,Jenkins及其部署插件並沒有提供這樣的能力

落實部署流程規範

在一個公司內部經常有不同的項目,使用不同的編程語言,而部署流程也五花八門。從控制風險,減少重複操作,降低部署自動化難度等多重考量,公司都傾向制定一套標準的部署流程。

這時候,獨立的部署系統就可以幫助用把這些規範落實下去並在日常的部署過程中時刻校驗(在軟件工程領域,幾乎所有的規範落實都得靠工具來助一臂之力,否則基本都會變成紙面上的規範而已)。

如果基於Jenkins來直接部署,如何落實這些部署規範仍然是一個很困難的事情,因爲Jenkins及其部署插件並未對此提供任何實質性的支持

獲取研發過程數據

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

讓部署操作服務化

如之前提到,部署不僅僅開發和測試人員需要,要努力讓部署服務化,從而讓團隊內任何一個人都可以隨時觸發一次部署。Jenkins的操作界面對於開發或者測試人員可能還比較方便,但是對於其他人員來說則過於複雜。

當然,除了上面列出的這些原因外,你還要解決部署版本的管理等,這裏就不一一列舉。

持續交付平臺的特質

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

如下圖所示,持續交付系統需要連接項目中涉及的人、代碼,製品庫,以及環境等,Jenkins僅僅起到了簡單的連接作用。
image.png

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

image.png

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

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

期待更好的持續交付平臺

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

image.png

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

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


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