Jenkins X 簡介及建置流程概念介紹

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(其靈感來源於 WeaveworksAlexis Richardson),它類似於人們利用 Git 開發 Chef recipesAnsible 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 環境部分,標準的情況會有 stagingproduction,也就是說除了程式碼本身,也對叢集中的環境進行版本控制。

對 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

專案建置流程

  1. 取出最新的程式碼
  2. 透過 jx step git credentials 取得在 jx 安裝時輸入的驗證資訊
  3. 取得新的版本號,並且更新 helm chart 版本號
  4. 透過 jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:\$(cat VERSION) 建置專案,檢查 CVE 並且 push 到 docker registry

CVE: 英文全名是 「Common Vulnerabilities & Exposures」 一般資安弱點及漏洞檢查

發出環境佈版要求

  1. 透過 jx step changelog --version v\$(cat ../../VERSION) 對 github 或 gitlab 發布 changelog,如下圖

  2. 透過 jx step helm release 將新的 helm 推到 chartmuseum 類似 npm 的存在。

  3. 透過 jx promote -b --all-auto --timeout 1h --version \$(cat ../../VERSION) 指令對 environment 發出 pull request 作為建置的 trigger,並且紀錄 environment 建置的順序,如下圖:

  4. 等待環境建置完成後清除 workspace,專案建置 jobs 將會監控環境建置的 pull request 是否已經完成。

環境建置流程

根據專案建置的步驟所產生的 pull request 作為觸發,觸發後步驟如下

  1. 取出最新的 helm 環境設置
  2. 透過 jx step helm build 確認環境建置正常
  3. 透過 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 時缺少的建置測試環境環節,敬請期待。