Jenkins 是由 java 撰寫的 CI/CD 工具,可以透過網頁 UI 來設定編譯、佈署的參數,並觸發整個 CI/CD 流程。除了透過手動觸發外還提供了 Cron-Style 排程、透過 git push 時觸發、透過 webhook 觸發。
按照官方教學,先安裝 openjdk-17-jre,然後從 jenkins 的 PPA 下載 jenkins,它會自動透過 systemd 執行在 localhost:8080。首次進入時選擇安裝官方推薦的 plugins,裡面包含 git、pipelines 插件。
首先要把 jenkins 使用者加入 docker 群組並重新啟動,否則它將無法執行 docker 指令:
新增一個 free-style 專案,隨意命名該專案。
然後設定用 https://github.com/shekhargulati/python-flask-docker-hello-world 來拉取原始碼。
接著在 Build Step 中新增 執行 shell
輸入以下指令:
最後回到專案頁面,按下 馬上建置
即可佈署一個簡單的 flask container,在終端機中用以下指令測試:
在 Lab 1 的專案中找到 參數化建置
新增一個 PORT
字串參數,代表 flask app 的需要被導向的連接埠。
然後將執行 shell
的指令改為:
接著就可以在 帶參數建置
中指定想要使用的連接埠,而不是固定使用 5000。
首先新增一個 Pipline 專案,然後按照 Lab 2 新增一個 PORT
參數。
接下來會有一個 Pipeline 區塊取代原本 free-style 專案中的 Build Step 區塊,這邊需要透過 Groovy 語法來定義 Pipeline 中的步驟。如果對 Groovy 語法不熟,可以點擊 Pipeline Syntax 來自動將一些常用功能轉換為 Groovy 腳本。
在 Pipeline 區塊填入以下腳本:
儲存好專案後,按下帶參數建置,就會根據 stages 產生以下表格:
透過 Git 管理 Jenkinsfile 有許多好處:首先 Jenkinsfile 由 git 存放,所以當 Jenkins Server 壞掉時不怕 Pipeline 的腳本也一起搞丟。再者,可以透過版控系統維護 Pipeline,在新版本 Pipline 上線之前可以透過 git branch 來區別不同的版本進行測試。
這次我 fork 先前 Lab 中所使用的 Repo,並且在專案的根目錄新增了一個 Jenkinsfile 在 https://github.com/blueskyson/python-flask-docker-hello-world.git
Jenkinsfile 的內容如下,可以注意到比起 Lab 3 的腳本多一個 parameter 區塊:
新增一個 Multibranch Pipeline,在 Branch Sources
中選擇 GitHub,貼上上方給的 repo 連結。這個 repo 是公開的,所以 Credential 的部分留空不用填。其他設定也都用預設值就行了。
接下來 Jenkins 會自動掃瞄 Repo 的所有 branch,或是手動按下 Scan Repository Now
手動掃描。之後就如下圖有兩個 branch,我們可以進到 branch 中帶參數建置。
如果 Repo 是不公開的,在 Jenkins 中就要給他一些資訊讓 Jenkins 登入 Repo,再拉取 Jenkinsfile。這裡以 Azure DevOp 為例,首先在 Azure DevOps 的 Repo 中新增一個 Personal Access Token,給予讀取程式碼的權限:
然後在 Jenkins 的 Branch Sources
->Credentials
->Add
新增基於 Username 和 Password 的 Credential,這邊 Username 填入 Azure DevOps 的使用者名稱,Password 填入剛剛在 Azure DevOps 拿到的 Personal Access Token:
這樣就能讓 Jenkins 透過 https 存取 Private Repo 了。
隨著越來越多的專案採用 Pipeline,每個 Jenkinsfile 裡會出現大量且重複的邏輯,此時可以透過 Shared Library 將部分 Groovy 語法寫成獨立的函式,然後讓 Jenkinsfile 來呼叫函式。Shared Library 必須要寫在一個 vars
的子目錄中,必且 Groovy 檔的檔名即為函式的名稱,詳見官方文件:https://www.jenkins.io/doc/book/pipeline/shared-libraries/ 。
一般來說 Library 的 Repo 會直接定義在 資訊主頁
>管理 Jenkins
>設定系統
中的 Global Pipeline Libraries,因為所有專案都共同引用 Global Libraries 在維護上會比較方便。如果真的有需求為每個 Pipline 引入 Local Libraries,也是可以在個別 Pipeline 中指定要去哪個 Repo 中下載 Library。見下圖。
設定好 Library 後,在 Lab 4 的同一個 Repo,的 use-jenkins-library
即可藉由 Shared Library 來執行。
當小組規模變得龐大,一台 Jenkins Server 無法同時乘載所有人的 CI/CD 工作量,或是不同專案必須佈署在不同機器上時,我們就需要透過 Agent 來完成這些需求。
首先在管理 Jenkins
>管理節點和雲端
>新增節點
選擇 Permanent Agent,然後填入類似以下資訊:
設定完成後回到 Agent 的狀態頁,會有一個 Jenkins 自動產生的透過 curl
執行 Agent 的整令,將它複製起來:
在你要佈署這個 agent 的機器中新增這個 Agent 的工作目錄 (以上圖為例就是 /home/lin/jenkins_agent
),然後打開終端機執行前面複製的這個指令就可以啟動 agent 了。
接下來,檢視在 Lab 5 的同一個 Repo,的 use-custom-agent
的 Jenkinsfile 會發現 agent any
被替換成:
最後,在執行這個 branch 的 Pipeline 時你可以觀察 Jenkins 網頁的左下角,將會由 my-agent 來執行。
https://blog.amis.com/精通-jenkins-pipeline-part1-e8ef48d3543e
https://www.jenkins.io/doc/book/pipeline/getting-started/#global-variable-reference