Jenkins已經老了 - ITNEXT
Jenkins的核心問題是它的單體巨石。一切都耦合在一起,外掛,配置,web ui,Jenkins核心,一切都在一個大型Web應用程式中。是時候我們開始將我們在自己的生產系統上學到的經驗應用到Jenkins本身,Jenkins需要是一個雲原生模組化系統。
Jenkins於2005年開始以Hudson的身份開始出現,2008年,作為Java One公爵選擇獎的獲得者,Jenkins獲得了成功。當甲骨文收購Sun時,開源社群決定推出一個新專案Jenkins,以便將其作為一個真正的開源和自由的努力。從那時起,它一直繼續存在。
在我看來,Jenkins在連續整合整合(CI)甚至在某種程度上持續部署(CD)方面確實是這個領域裡唯一的選項。然而,經過幾年的使用和Jenkins的戰鬥,我認為可能是繼續前進的時候了。像許多其他專案一樣,Jenkins已經成為自己成功的犧牲品。
我在職業生涯的大部分時間都和Jenkins在一起。首先作為Jenkins工件的消費者,當它仍然是Hudson時,現在作為Jenkins的開發管理員,在龐大的團隊中建立和配置數千個工作。
Jenkins在那些年裡已經成長和成熟。但一切都不順利。我發現自己每天都在和Jenkins打架。雖然已經取得了一些進展以解決我的一些問題,但其他問題是難以解決的問題,這些問題深入探討了Jenkins的工作方式。
構建配置
Jenkins核心是Jobs,這些構建配置告訴Jenkins什麼以及如何做事。
Web UI
起初一切都是透過UI完成的。所有專案都是透過非常易於使用的Web表單進行配置的。起初這很棒。但很快就發現這很難備份和維護。隨著對程式碼配置的不斷增長的需求,這並不適合。配置大量作業非常繁瑣且容易出錯。維護這些配置更加困難。
工作DSL
接下來是Jenkins Job DSL。這是面向配置驅動開發的可喜步驟。Jenkins Job DSL允許您使用Groovy 編寫工作程式碼。您可以建立可重用的類和方法來生成10,100,1000的作業,而作為管理員的工作很少。作為額外的好處,我們還可以控制作業配置。
def gitUrl = 'git://github.com/jenkinsci/job-dsl-plugin.git' job('PROJ-unit-tests') { scm { git(gitUrl) } triggers { scm('*/15 * * * *') } steps { maven('-e clean test') maven('-B release:prepare release:perform') shell('cleanup.sh') } } |
但一切都不順利。Job DSL有幾個關鍵缺陷。
從頭開始並不總是那麼容易,尋找Job模式難以實現。
構建指令碼的測試幾乎是不可能的。這導致系統管理員在生產中測試配置。此外,嘗試新功能非常困難。如果您希望一個分支的構建方式與其他分支不同,該怎麼辦 你可以做到這一點,但它不是很乾淨。
雖然Job DSL是集中維護的,但是SA很喜歡,但在配置工作時,它讓開發人員感覺像是二等公民。並非所有賈伯斯都陷入了完全相同的模式。這經常導致非常複雜的DSL指令碼。
Jenkins管道
最近,Jenkins Pipeline或許多人將它們稱為Jenkinsfile,因為構建是從Jenkinsfile名稱的儲存庫中的特殊檔案驅動的。Jenkinsfile將控制權交還給開發人員。構建配置與程式碼一起儲存。這允許不同分支的行為不同,具體取決於該分支中的Jenkinsfile配置。SA仍然可以維護一組核心功能,開發人員可以將這些功能匯入到指令碼中並根據需要進行自定義。
pipeline { agent any stages { stage('Build') { steps { // } } stage('Test') { steps { // } } stage('Deploy') { steps { // } } } } |
雖然這確實提供了在更加孤立的環境中進行實驗的能力,但它仍然存在一些問題。雖然Jenkinsfile在技術上很時髦,但由於安全問題嚴重,你不能做很多你通常認為可以做的事情。
通常這會顯示為奇怪的錯誤,例如無法為每個錯誤做錯在列表上。我不能告訴你我多少次在Jenkinsfile中編碼只是為了讓安全指令碼許可權看起來好看。然後,這需要有人登入Jenkins,批准呼叫,然後再次執行作業,沖洗並重復,直到希望工作完成。
除此之外,無法在外部配置和儲存白名單。
因此,當您使用庫啟動新的Jenkins例項時,您必須再次批准所有相同的指令碼。在失敗之前,您無法批准指令碼。所以,祝你好運,確保一切都得到正確批准。
Jenkinsfile分為幾個階段。這樣可以很好地隔離構建思想,例如構建,測試,釋出等。但是,Jenkins的開源版本不支援從Jenkinsfile中的階段重新啟動構建。這是全有或全無。對於簡短的小型構建,這不是什麼大問題。對於較大的構建,這是一個事務破壞者。
外掛
外掛很棒。它們允許第三方將新功能寫入Jenkins。我們將包含各種內容的頁面合併在一起。例如,我可以擁有一個顯示程式碼覆蓋率,單元測試歷史記錄,靜態程式碼分析趨勢等的構建。很棒的權利。從表面上看是的。
但外掛有一個黑暗的一面。
由於外掛和外掛版本,維護Jenkins是一場噩夢。外掛是在INTO Jenkins中部署的,作為單個Jenkins Master Web容器的一部分,這意味著它們共享一個共同的類路徑。
我怎麼知道我是否會破壞了某些東西?
很多時候升級Jenkins也會更改底層配置檔案。如果您使用Jenkins Job DSL,那麼您必須確保它與您的Jenkins版本和所有已安裝的外掛保持同步,這會強制您擁有多個Jenkins例項。但是你不能輕易地用Jenkins做傳統的金絲雀部署模式。
這最終導致新功能停滯不前並延遲升級。
檔案資料
Jenkins生成並用於渲染所有可愛構建結果頁面的所有資料都儲存為檔案。很多,很多很多檔案。這使得Jenkins的表現非常出色。
大型管道檢視花費幾秒鐘渲染並不罕見。這些大檔案也使Jenkins記憶體密集。很多時候Jenkins將這些檔案解析為整個DOM,將檔案的全部內容載入到記憶體中。Jenkins使用幾千兆位元組的堆大小並不罕見。實際上,我們的生產Jenkins例項只有一個32 GB的堆來保持執行
記憶體
說到記憶體,因為所有外掛實際上都是載入到Jenkins中的程式碼,所以看到大量記憶體洩漏是很常見的。這不是Jenkins的核心故障,但它仍然會取消伺服器。我們現在安排定期重啟Jenkins例項以減輕記憶體洩漏。
系統Groovy指令碼
如果您每個人都想使用System Groovy指令碼,請不要這樣做!你會(將)把Jenkins搞得一團糟。這是因為指令碼不是分叉程式,而是指令碼執行在Jenkins內部。這是有目的的,因為作為系統groovy指令碼,您希望訪問Jenkins本身和實際執行的類。但這意味著您還可以訪問執行Jenkins的直接JVM和程式。因此,你可以搞亂類路徑,堆,甚至把整個事情搞砸(System.exit?)
Jenkins配置
雖然Job DSL和Jenkins檔案有助於配置Jobs,但在配置Jenkins本身時卻做得很少。您需要將Jenkins配置為連線到靜態從屬或Mesos群集,或者設定安全性或配置環境變數,構建工具等。作業DSL有一些可用於執行此操作的庫,但它們很難理解且無法測試。
無法測試
我曾經說過一次,兩次,數千次。Jenkins是不可能測試的。誰會使用無法測試的程式語言?除了在生產中,沒有人!有些人可能會說你當然可以測試Jenkins。相信我,我試過了。你是如何真正測試它的?我們已經嘗試啟動Jenkins的本地例項,但是在實際執行構建時會很快崩潰。實際配置怎麼樣?您需要配置對群集的訪問許可權,模擬關鍵基礎架構,如artifactory和DTR。這真的很難。最重要的是,您希望測試不會影響實際系統。有幾次我們的“測試”由於缺乏隔離而導致生產問題。
升級
我在外掛中簡要提到了這一點,但升級是一個真正的問題。當你升級一個外掛甚至Jenkins本身的全部或全部。如果您有一個需要較舊版本外掛的作業,而另一個需要較新版本的作業則會被卡住。您將需要多個Jenkins例項。遷移到新版本並不總是可行,因為升級外掛也會導致底層XML也發生變化。因此,回滾幾乎是不可能的。
Jenkins Web UI
實際的Web UI在一個名為Jenkins Master的Web容器上執行。你只能擁有其中一個。它不支援任何型別的群集或故障轉移。因此,如果你有一個非常龐大的開發團隊,所有人都打到Jenkins,那麼一個例項需要非常強大並且不斷受到監控。
結論
詹金斯的核心問題是它是一個單體巨石,一切耦合在一起。
我理想的CI / CD系統需要:
- 支援某種單元測試工作
- 完全斷開連線
- 水平可伸縮
- 模組化
- 擴充套件
值得慶幸的是,似乎有些東西可能適合該法案。
相關文章
- Rust和JVM一起使用 - itnextRustJVM
- API優先方法的完整指南 - ITNEXTAPI
- Java 11已經發布Java
- jenkins手把手教你從入門到放棄03-安裝Jenkins時web介面出現該jenkins例項似乎已離線JenkinsWeb
- 深入研究自定義Apache Nifi處理器 - itnextApacheNifi
- Ness SES技術長:最終,Hadoop老了!Hadoop
- “一個人”老了,應該如何養老
- 智慧數字經營3.0,已經普及了嗎?
- GIL 已經被殺死了麼?
- “行星狩獵”,AI已經出手AI
- Java是不是已經飽和了?Java
- go操作redis(已經廢棄)GoRedis
- 為什麼Go不再需要Java風格的GC?- itnextGoJavaGC
- 使用Docker桌面開發環境功能開發SpringBoot - itnextDocker開發環境Spring Boot
- C# 中的 ref 已經被放開,或許你已經不認識了C#
- 修改已經有的網站怎麼修改修改已經有的網站怎麼修改網站
- 注意!DNS流量劫持已入刑!他們已經進去了...DNS
- Jenkins 節點已啟動,但是一直顯示未線上?Jenkins
- 「Jenkins+Git+Maven+Shell+Tomcat持續整合」經典教程JenkinsGitMavenTomcat
- 只知道ajax?你已經out了
- “Lunar Lobster “現已經可以下載
- 我已經深深的愛上了GoogleGo
- 已經收到滿意的 offer 了
- Wasm 原生時代已經來到ASM
- Git 忽略已經提交的檔案Git
- 統計 Jenkins 平臺上所有已部署的任務的執行情況Jenkins
- 老大難的 Java ClassLoader 再不理解就老了Java
- 世界已經無法阻擋Python入侵Python
- Redis Manager 接入已經存在的叢集Redis
- 如何debug入站已經成功的idoc
- git列出所有已經跟蹤檔案Git
- Git 如何遺棄已經 Push 的提交Git
- ES9已經來了 Are you ready?
- 通用人工智慧已經到來人工智慧
- 已經有 Prometheus 了,還需要夜鶯?Prometheus
- 驀然回首,Java 已經 24 歲了!Java
- 《深入淺出Oracle》新書已經出版Oracle新書
- golang版supervisor 已經線上上使用Golang