Jenkins X,次世代 Jenkins,開發 Kubernetes 應用 CI/CD 流程的解決方案,此篇文章將跟大家分享研究使用過程中的心得及相關概念,希望能讓讀者對 Jenkins X 有些初步認識,也進一步說明 Jenkins X 在 CI/CD 流程中各個環節的運作。
前言
新世代的 Jenkins,Jenkins X,2018/3/20 日推出,近期創科正在研究 Kubernetes,有了一些使用心得,對 Kubernetes 有一些熟悉後,更進一步嘗試使用 Jenkins X,也跟大家分享一下研究過程中的心得,希望能讓大家對 Jenkins X 有些初步認識。
下面是網路擷取的一些基本介紹:
Jenkins X 並不是通用的 Jenkins,無法對它進行修改做任何想做的事情。它是專門針對 Kubernetes 專注於雲端部署的使用場景,因此在 JEP 400 提案中,Jenkins X 定義為
Kubernetes 的原生 Jenkins
。
也因為這樣,需要先有 Kubernetes 的環境才能安裝 Jenkins X。
CloudBees 的高級架構師 Strachan 認為 Jenkins X 開發模型代表了
開發 Kubernetes 應用的最佳實踐
。這是基於他和他的團隊開發 Fabric8 的經驗得出的結論,Fabric8 項目是具有類似使命的項目,它試圖根據 DevOps 報告的現狀 提供工具和實作相關環節的具體實現。「Jenkins X 的目標是將 Jenkins 變成一個自助服務裝置,因此任何開發人員都可以啟動一個新專案,任何 pipeline 的步驟都可被執行。 我們並不是說你的團隊就不用瞭解 Jenkins ,更重要的是我們試圖讓 CI/CD 更像是其他的雲端服務」
上文提到的最佳實踐,詳細內容如下:
與之相關聯的 Jenkins 增強提議(Jenkins Enhancement Proposal,JEP) 為 JEP 400,它提供了一些推薦
最佳實踐
的樣例,這些樣例都是通過 CI/CD 將專案部署到 Kubernetes 中,細節如下:
- 主分支應該始終是整潔的並且可以隨時發佈。不允許使用長時間的特性分支,以便於
保持精簡
;- Pull request(PR)用於處理新的變更,然後它會提交到主分支上。當 PR 變更的時候,會觸發 CI 測試。只有當所有的 CI 檢查都通過並且所需的代碼審查都滿足的時候,PR 才能合併到主分支上。
- release 版本是基於主分支產生的,它會產生不可變的發布版本(JAR、Docker image、Helm charts 等)。release 版本的建置可以是手動觸發,也可以是新 PR 合併後自動生成的,甚至還可以基於一定的間隔頻率來進行建置。
- 哪個版本的服務運行在哪個環境之中是在一個單獨的 Git repo 專案中以聲明式的方式進行管理的。將變更 push 到 Git repo 中就會觸發部署,該 repo 會進而觸發建置 pipeline。這種方式通常又被稱為
GitOps
(其靈感來源於Weaveworks
的Alexis Richardson
),它類似於人們利用Git
開發Chef recipes
和Ansible playbooks
的方式。
對 Jenkins X 有些文字上的初步了解後,接著可以我們可以從操作面來看上述相關的特性是怎麼實際運作的。
Jenkins X 的安裝,在這就不多說明,若有需要官方 github 都有詳細說明,需要注意的是,若你想安裝 Jenkins X 在已經存在的 Kubernates cluster 上,參考下面連結的安裝方式:
https://jenkins-x.io/getting-started/install-on-cluster/#installing-jenkins-x-on-premise
安裝好後,就可以開始使用,Jenkins X 已經內建了 blueocean 的介面
在這邊跟標準 jenkins 比較不同的地方,Jenkins X 提供了 jx
的指令,參考下面連結:
https://github.com/jenkins-x/jx
使用 brew 安裝
https://github.com/jenkins-x/homebrew-jx
其中 jx
指令就是上文提到的
任何開發人員都可以啟動一個新專案,任何 pipeline 的步驟都可被執行
的關鍵。
而在開始說明 jx 實際操作前,先針對 jenkins X 在 DevOps 流程中的概念進行說明
來源:https://blog.octo.com/en/jenkinsx-new-kubernetes-dream-part-1/
根據上圖,可以看到在 Git 部分主要組成為兩個部分,一部分是專案程式庫
本身,可以是多個專案,另外一個部分是 environment
環境部分,標準的情況會有 staging
及 production
,也就是說除了程式碼本身,也對叢集中的環境進行版本控制。
對 Jenkins X 而言,每個專案都有其標準的結構,其命名為 draft,參考下面連結
https://github.com/jenkins-x/draft-packs
以 nodejs 為例,參考下面連結
https://github.com/jenkins-x/draft-packs/tree/master/packs/javascript
比較重要的如下,包含
- charts: helm 環境專案程式庫,類似 npm、maven
- skaffold: 環境建置工具,類似 mvn、gradle
- Dockerfile: docker image 建置步驟
- Jenkinsfile: CI/CD 流程設置檔
.
├── Dockerfile
├── Jenkinsfile
├── charts
│ ├── node-http
│ └── preview
├── skaffold.yaml
其中建置流程步驟存在於 Jenkinsfile
,以 nodejs 專案為例內容如下
stage('Build Release') {
when {
branch 'master'
}
steps {
container('nodejs') {
// ensure we're not on a detached head
sh "git checkout master"
sh "git config --global credential.helper store"
// jx 在安裝時已有設置 api token,此指令將會把 token 載入,讓建置過程中有足夠的權限
sh "jx step git credentials"
// so we can retrieve the version in later steps
// 寫入這次 release 的版號
sh "echo \$(jx-release-version) > VERSION"
}
dir ('./charts/node-http') {
container('nodejs') {
// 更新 helm 的版號
sh "make tag"
}
}
container('nodejs') {
sh "npm install"
sh "CI=true DISPLAY=:99 npm test"
// 透過 skaffold 建置新版號的 image
sh 'export VERSION=`cat VERSION` && skaffold build -f skaffold.yaml'
// 建置前,進行 CVE 檢查,CVE 的英文全名是 「Common Vulnerabilities & Exposures」 一般資安弱點及漏洞
sh "jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:\$(cat VERSION)"
}
}
}
stage('Promote to Environments') {
when {
branch 'master'
}
steps {
dir ('./charts/node-http') {
container('nodejs') {
// 對 github 或 gitlab 發布 changelog
sh 'jx step changelog --version v\$(cat ../../VERSION)'
// release the helm chart
sh 'jx step helm release'
// promote through all 'Auto' promotion Environments
// 發布版本,到 staging env
sh 'jx promote -b --all-auto --timeout 1h --version \$(cat ../../VERSION)'
}
}
}
}
根據上面的設定檔,拆解為敘述性步驟如下,也參考下圖
來源:https://www.cloudbees.com/blog/opinionated-kubernetes-and-jenkins-x
專案建置流程
- 取出最新的程式碼
- 透過
jx step git credentials
取得在 jx 安裝時輸入的驗證資訊 - 取得新的版本號,並且更新 helm chart 版本號
- 透過
jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:\$(cat VERSION)
建置專案,檢查 CVE 並且 push 到 docker registry
CVE: 英文全名是 「Common Vulnerabilities & Exposures」 一般資安弱點及漏洞檢查
發出環境佈版要求
- 透過
jx step changelog --version v\$(cat ../../VERSION)
對 github 或 gitlab 發布 changelog,如下圖 - 透過
jx step helm release
將新的 helm 推到 chartmuseum 類似 npm 的存在。 - 透過
jx promote -b --all-auto --timeout 1h --version \$(cat ../../VERSION)
指令對 environment 發出 pull request 作為建置的 trigger,並且紀錄 environment 建置的順序,如下圖: - 等待環境建置完成後清除 workspace,專案建置 jobs 將會監控環境建置的 pull request 是否已經完成。
環境建置流程
根據專案建置的步驟所產生的 pull request 作為觸發,觸發後步驟如下
- 取出最新的 helm 環境設置
- 透過
jx step helm build
確認環境建置正常 - 透過
jx step helm apply
部署最新的環境,包含最新的專案版本
一但自動執行完上述步驟後,我們可以透過 jx get apps
來取得目前已發布的專案。
上圖可以看到一個將有兩個 link,staging 及 production,其中,staging 將會根據是否有 commit 來自動部署,而 production 部署則透過 jx promote
來手動進行,一般來說 production 環境不會進行自動部署,範例 production 部署指令如下:
jx promote --version 0.0.13 --env production --timeout 1h
根據指定的版本,Jenkins 將去尋找建置 stage 紀錄中的 0.0.13 之 git tag 進行佈版,確保先經過 staging 驗證,範例執行結果如下
完整流程與相關服務的互動, jx
指令使用時機如下圖
根據上面的流程,可以理解到 jenkins X 已經定義了一個標準的佈版流程範本。
產生內建 CI/CD 流程的基礎專案
即使是不同語言的專案,在 jx 的協助下都可以快速建立 base 在這樣的框架下的 CI/CD 流程,目前內建的程式語言可以在 https://github.com/jenkins-x-quickstarts 找到,如下:
android-quickstart
angular-io-quickstart
aspnet-app
dlang-http
golang-http
node-http
open-liberty
python-http
rails-shopping-cart
react-quickstart
rust-http
scala-akka-http-quickstart
spring-boot-http-gradle
spring-boot-rest-prometheus
spring-boot-web
vertx-rest-prometheus
也可以建立屬於你們團隊的 quickstart,參考下面連結說明
https://github.com/jenkins-x/jx-docs/blob/master/content/commands/jx_get_quickstartlocations.md
跟以往 Jenkins 的使用方式還有一點不同的地方,通常我們是要透過 Jenkins 的介面來做專案建置,而因為 Jenkins X 提供的 jx 的指令,我們有機會再不仰賴 Jenkins 的介面,透過 command line 的方式來進行建置,一些常用的指令都已內建在 jx step
底下,所以也就代表說,我們可以在 command line 下完成所有在 Jenkinsfile 底下的建置步驟,這對開發 debug 來說是非常重要的環節,希望這篇文章能帶給大家對於 Jenkins X 的運作一些初步的認識。
下一篇將說明怎麼透過 jx create devpod
的指令,來建立測試建置環境,更進一步可以將你開發中的程式碼,即時更新到 dev pod 中,直接並且即時
在 Kubernetes 環境中驗證開發中的結果,這部分也是在之前使用傳統 Jenkins 時缺少的建置測試環境環節,敬請期待。