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 時缺少的建置測試環境環節,敬請期待。