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 才能合併到主分支上。
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
比較重要的如下,包含
. ├── 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 step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:/$(cat VERSION)
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 作為觸發,觸發後步驟如下
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 已經定義了一個標準的佈版流程範本。
即使是不同語言的專案,在 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 時缺少的建置測試環境環節,敬請期待。