GoCD 很好,但說說 Jenkins 吧

前言

近些年來 Docker、 Kubernetes、 Helm、 雲原生如火如荼,Jenkins 憑藉開源社區的貢獻以及類似 CloudBees 團隊的加持。緊跟技術發展趨勢,產出了集成於 Docker、 Kubernetes、 Helm、AWS 等各種工具插件,還有 Jenkins X,原來配置頁的 Manage Nodes 也 "悄悄地" 變成了 Manage Nodes and Clouds。另一方面,自研能力不錯的企業,也紛紛基於 Jenkins API 開發一套 Devops CICD 平臺,給 Jenkins 那個 "老頭" 套上了一層年輕的外衣,效果也十分理想。

Jenkins 開源的特性,還有浩瀚如海的插件,學習門檻低等等,都讓其成爲一個不錯的選擇。至少可以在有限資源的條件下,針對項目中需要搭建少數的幾個流水線這樣的需求而言,Jenkins 再合適不過了。

縱使作爲一個新技術的愛好者,當你用其他新的 CI 工具時,也不妨回過頭來看一看這個 “老頭”,其中包含的一些通用法則、思想會讓你明白如何才能搭建使用於某個項目易用、易擴展、易維護的流水線。

**提高代碼複用性之 Shared Library **

如果你爲一個項目裏的多個 Code Repo 寫多個 jenkinsfile,你八成會遇到多個不同流水線中有大量重複代碼的情況,尤其在服務衆多的微服務的項目當中。很多時候爲了方便省事我們都是直接複製粘貼類似的邏輯代碼到不同的 jenkinsfile 中去,但如果某一天你需要更改一個小小的命令,那你就要受點小罪了。

而 Shared Library 便是解決代碼重複的方法之一,只需根據流水線段落的合理劃分,將流水線邏輯重複或共通的部分進行抽象和封裝,便可在所有的流水線中簡單地引用這些共享庫下面的代碼,並可大大縮短 jenkinsfile 中的代碼行數,也顯得更加易讀、易維護。

而後期之秀中的 Azure Pipelines, Github Actions 似乎深知複用功能函數的好處,並將其常用的 Tasks/Actions 放置到了公共的 Marketplace 中。開發者即可直接使用,也可以自行開發後上傳到 Marketplace 中供更多人使用。使用者更是免於維護一個單獨的類似於 Jenkins Shared Libray 的代碼倉庫,一舉多得。另外,雲原生工具中的 Tekton, 其中的 Task 也有類似的實踐。

共享庫越來越大,調用關係越來越複雜時,不得不考慮代碼質量的問題。那就需要測試代碼來保證質量,如何對 Shared Library 進行測試?當然可以編寫 Jenkinsfile 放到 Jenkins 中創建 Job 去運行,跑一跑便知代碼是否有問題。但無疑這種方法不太優雅,推薦使用 JenkinsPipelineUnit(一個共享庫單元測試的框架)。

模板化之 JTE

正如一套開發框架一樣,目的是爲了快速地搭建起一個標準化的許多項目,模板提供的功能也是如此:對於同一類型的流水線而言,大多數的構建過程均是一樣的,甚至連運行的命令也是一模一樣,這樣的流水線 配置文件相似度自然也是非常的高。那麼 Jenkins Templating Engine 就是針對這樣的場景的一個非常好的解決方案。

例如,在微服務的大型項目中,往往一個系統是由數十個小的微服務組成的,而這數十個微服務均需要各自的 CICD 的流水線,來完成打包、部署的過程,彼此之間又是同一套開發框架,所需要的構建環境、工具、測試流程、發佈策略等等均是一個模子刻出來的。

"人" 如其名, Jenkins Templating Engine 就是用來做流水線模板化的工具,簡稱 JTE。從 JTE 主頁可看到誕生時間是 2019 年 5 月份,相當年輕。針對不同類型的項目,比如 Maven、 Gradle 來做一些模板化的規定,簡單而言就是用來統一內部流水線的 Stage、Steps 中的邏輯、參數等。

在完成上述代碼,以及安裝 JTE 插件、正確配置 Jenkins 的前提下,在具體業務代碼中添加默認文件pipeline_config.groovy之後,新建流水線時針對 build configuration 選項去選擇Jenkins Templating Engine,即可完成流水線的搭建,只需要簡簡單單的 2、3 行。

而反觀 JTE 的優勢,便是以下三點:

(來源於 https://www.jenkins.io/blog/2019/05/09/templating-engine/)

而去其他 CICD 工具中尋找一下,也可見到類似實踐的身影。例如 Gocd 的 Pipeline Templates, Azure Pipelines 的 templates

集中管理之 Job DSL

如果你正在經歷一個微服務項目,Code Repo 數量衆多,而每個 Repo 都需要通過一個 Jenkinsfile 定義一個流水線。當你面對幾十上百個 Repo,分散地管理維護它們便些許繁瑣。Job DSL Plugin 允許使用 DSL 以編程方式創建項目,將作業創建的操作通過腳本實現,使你能夠自動化和標準化 Jenkins 配置。

這款插件不單單能夠創建各種類型的 Job(Maven jobs、Freestyle jobs、流水線 jobs...),還能創建 Folder、 Dashboard View、 List View 等等。形象生動的效果如下圖,“埋下一顆種子,收穫幾顆大樹”。

在代碼庫的目錄層級上,首先建議按照 Project 劃分,給每個 Project 定義單獨的 Seed Job;其次將 Job 等的定義與邏輯實現隔離,這樣能確保 xxx.jenkinsfile 裏的內容的獨立性,且在採納 Job DSL 插件後,針對原先的 jenkinsfile 無需做很大幅度的修改,拿過來便可使用。

該工具無疑將 Pipeline As Code 的理念又進化了一步,將流水線的創建過程也代碼化了。然後在 Jenkins 實踐中,如果想追求更多的配置代碼化,不妨看看 Jenkins Configuration as Code,簡稱 JCasC。這個工具能完全將大部分的 Jenkins 的資源、配置代碼化,安裝插件、配置 Github Server、管理憑證、新建任務等等都可通過文件完成,不需要在 UI 界面上做任何的操作。

後記

以上幾種思想在本文中都提供了對應的一種實現方式,但遠遠不止於所提及的方法,當然還有或多或少類似的方法,但萬變不離其宗。縱使今後有更多的 CICD 新工具的出現,或許在一些小的地方上可以另闢蹊徑,但大體的解決方案也繞不開已有的這些解決問題的思想。例如在 Azure Pipelines 中, Templates 的功能能提供類似 Shared Library 和 JTE 的功能,只是實現形式不同,核心思想卻還是一致的。

具體使用還需要結合項目屬性、分支策略、發佈策略、權限管理、服務器環境情況等多個方面綜合考慮,另外也有很多類似於 Nightly Build 這種構建策略值得我們借鑑。“條條道路通羅馬”,怎麼省時、省力的達成我們最終的目標,以及達成之後如何維護好流水線,都值得好好思考與設計。


本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/F8mJqMhoBkDEoh6GzqUz8Q