Jenkins Pipeline — Scripted Pipeline with Scalable Architecture (I)

Ensky Lin
Ensky Lin
Sep 6 · 5 min read

Target Audience

本系列文寫給 ”使用過 Jenkins Pipeline 且希望了解如何更進一步的將其寫的更有規模” 的人

Intro

最近因為工作上的需要,寫了好一段時間的 Jenkins Pipeline,剛好可以分享一些心得、以及踩過的雷,最後是我們推薦的 Architecture。

Jenkins pipeline 是 Jenkins 在 2016 年推出的 Plugin。在此之前,大家使用 Jenkins 的方式幾乎都是 Freestyle project,也就是用 UI 操作一些執行的設定 (在哪個 Node 執行、執行前、中、後要幹麻,等等),而大家很快的就發現整個專案包含設定檔都有進行版本控制的必要性。因此 Jenkins 的開發團隊就開發了 Jenkins Pipeline 來完成這件事情。有了 Jenkins Pipeline 之後整個流程都可以用 Groovy 語言和 Jenkins 的 DSL(Domain Specific Language) 來完成,從此 Jenkins Owner 就可以用更 Organize 的方式去控制 Jenkins。

Declarative Pipeline and Scripted Pipeline

Jenkins pipeline 有分 Declarative Pipeline 和 Scripted Pipeline,前者透過類似 definition 的方式去 “define” 你的 pipeline,後者是用程式化的方式去 “execute” 你的 pipeline,兩種各有愛用者,我自己偏好用後者去寫,我們這次介紹的架構也是用 Scripted Pipeline 去撰寫。

Common Problems About Jenkins Pipelines

接下來介紹一下一系列在我改成目前架構之前常常遇到的 Jenkins Pipeline 問題,而這些問題我後來通通有找到方法解決。

ScriptApproval hell

Jenkins 的 Script 都 run 在 sandbox 裡面,而他們的權限機制下,若你的 script 中有用到一些「Jenkins 不預期的」 Object 或 method,通通都會在執行期間遇到 RejectedAccessException,這時你就只能到 global setting 裡面把剛剛被擋下的那個 rule 開起來。

Non-Testable

隨著 Pipeline 日益複雜,如果沒有完整的測試(Unit test + Integration test),「改 pipeline」這個動作本身就是一件非常恐怖的事情,我們的服務是提供很多 developer 一個共用的 CI / CD Pipeline service,這些 pipeline 壞掉的話很多 team 都會無法執行他們要的測試,會造成直接的影響,因此完整的測試相當重要。

但若使用最基礎的 pipeline 寫法不管是 scripted pipeline 或 Declarative 幾乎都可以說是無法測試,非常恐怖。

Always repeat myself

Don’t Repeat Yourself (DRY) 是一個 OO 程式的基本準則,而這準則在 Jenkins Pipeline 似乎不太適用,寫著寫著就不斷的 copy-paste,而若某個 common flow 調整了則你就會需要曠日費時的進行跟動。

IDE supports

就像各種程式語言開發一樣,若打算開發具有規模的 Jenkins Pipeline 程式,沒有好的 IDE 是不行的,至少要可以幫你完成 Syntax highlight、Auto Complete,如果有 Refactor、Testing 整合就更好了。

Hard to maintain job metadata and the pipeline code

Jenkins 的 Job 和 Pipeline 是分開的,此時若 Pipeline 有調整,你會需要手動調整你的 Job,這在有版本控制的情況下更是困難,常常會因為 Pipeline Code Commit 之後還需要手動調整 Job 的參數等等,遭遇到 Inconsistency 的問題。

Hard to Debug

Pipeline 在 Jenkins 就是一個 Job,而你要 Debug Pipeline 多半就是要執行你的 Job,而當你有 Production 環境的時候,要用同樣的 job 去執行你的 developing 的 pipeline 的話很顯然的會影響到 Production job 的 resource、log 等等。

但若你針對每個 production 的 job 都建立對應的 debugging job 第一個會遇到參數連動的問題(要一直調整 job 的參數去對齊 code,同上一點),接著你又會需要不斷根據 PR 的 feature branch 去調整 debugging job 的 pipeline git branch,實在很麻煩。

So…?

欲知這些問題如何解決,請見下回分曉XD

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store