Jenkins X 搭配 .NET Core 進行建置

在 Kubernetes 中運行 Jenkins X 並設置特定程式語言之建置環境,以 .NET Core 為例。


距離上一篇 Jenkins X 簡介及建置流程概念介紹 經過了一段時間,在公司內透過 Jenkins X 進行了三個專案的建置,分別是 PHP、Node.js 及 .NET Core,對 Jenkins X 有近一步的認識,透過此文記錄一下,也分享給大家。

在開始此篇文章之前,假設讀者已經有 Kubernetes + Jenkins X + jx + helm 的運作環境,並且對於 kubectl 及 helm 有初步的操作經驗。

若需要上述安裝程序的話可參考下面連結:

第一步需要有足夠的 docker registry 權限才能將建置完成的 image 更新到 docker registry。

而 Jenkins X 的建置過程中,無論任何語言,都是透過 pod 作為 slave 來完成,因此我們需要讓 Jenkins X 有足夠的驗證資訊進行 image 更新。

參考下面文章:

https://github.com/jenkins-x/jx-docs/blob/master/content/architecture/docker-registry.md

透過 jx 指令的使用,在作為建置的 pod slave 引入相關的帳號密碼以完成 docker push 的動作,如文中指令:

jx create docker auth --host "foo.private.docker.registry" --user "foo" --secret "FooDockerHubToken" --email "fakeemail@gmail.com"

上述準備工作完成後,就可以進入本文的主題。

1. 建立 Jenkinx X build-dotnetcore 環境

為了讓 jenkins X 能夠建置 .NET Core 我們需要在 Jenkins X 的 base 下進行延伸,官方文件連結如下

https://github.com/jenkins-x/jx-docs/blob/master/content/architecture/pod-templates.md

其中提供了 builder-base 連結如下

https://github.com/jenkins-x/builder-base

若我們要建立 .NET Core 的環境,直接參考官方的 builder-maven

https://github.com/jenkins-x/builder-maven

會是一個比較快的開始,因此我們在製作 .NET Core 時就是用此專案作為基底調整後建立 .NET Core 建置環境。

我們調整過後,作為 Jenkins X 建置 .NET Core 環境的 repository 網址如下:

https://github.com/trunk-studio/build-dotnetcore

Jenkins X 中只要是 builder-* 的專案結構,都是可以直接在 Jenkins X 中進行建置的,也因此各基底本身都有提供 Jenkinsfile,我們可以直接從 Jenkinsfile 了解建置步驟。

針對 Jenkinsfile 需要調整的內容為,參考下面連結:

https://github.com/trunk-studio/build-dotnetcore/blob/master/Jenkinsfile#L6-L7

其內容為:

    environment {
        ORG         = 'trunksys'
        APP_NAME    = 'builder-dotnetcore'
    }

作為環境變數後,在之後的建置指令中將會替換為對應的變數值

接著我們可以透過 jx 指令將 build-dotnetcore 專案 import 到 Jenkins X,讓 Jenkins X 自行建置[.NET Core 建置環境],指令如下

jx import build-dotnetcore --no-draft=true

在使用 jx import 的時候預設會詢問是否要用 draft,因為此專案是為環境建置專案所以不需要一般 Jenkins X 專案所需相關設定檔案,一但專案匯入 Jenkins X 之後,完成建置如下畫面:

建置沒有問題的話,在 Jenkins X 的建置流程中,會進行 tag push 的動作,我們可以在 docker hub 上看到對應的更新。

至此 Jnekins X .NET Core 建置環境已經 Ready,接著我們需要告訴 Jenkins X 有新的建置環境可以作為建置使用,也可以作為 DevPod。

2. 設置 Jenkins X 新增 .NET Core 建置環境可作為建置使用

相關設置,目前已知可以設置的方式如下:

設置 helm values.yaml

若你有 k8s 環境,要安裝 Jenkins X 時,可以透過 Jenkins X 官方 Helm 安裝方式來進行,其中提供預設的 values.yaml,我們可以修改該檔案後,進行 Jenkins X 的安裝,這樣做的好處就是假設我們需要裝在不同的機器上時,初始就會有相同設置,我們不需要在做其他調整,參考下面連結的位置

https://github.com/jenkins-x/jenkins-x-platform/blob/v0.0.3045/values.yaml#L842-L893

我們以 maven 為基底,複製一份作為 dotnetcore 的專案初始,如下

jenkins:  
  Agent:
    PodTemplates:
      Dotnetcore:
        Name: dotnetcore
        Label: jenkins-dotnetcore
        DevPodPorts: 5000
        volumes:
        - type: Secret
          secretName: jenkins-docker-cfg
          mountPath: /home/jenkins/.docker
        EnvVars:
          JENKINS_URL: http://jenkins:8080
          GIT_COMMITTER_EMAIL: jenkins-x@googlegroups.com
          GIT_AUTHOR_EMAIL: jenkins-x@googlegroups.com
          GIT_AUTHOR_NAME: jenkins-x-bot
          GIT_COMMITTER_NAME: jenkins-x-bot
          XDG_CONFIG_HOME: /home/jenkins
          DOCKER_CONFIG: /home/jenkins/.docker/
        ServiceAccount: jenkins
        Containers:
          Jnlp:
            RequestCpu: "200m"
            RequestMemory: "128Mi"
            Args: '${computer.jnlpmac} ${computer.name}'
          Dotnetcore:
            Image: trunksys/builder-dotnetcore:0.0.6
            Privileged: true
            RequestCpu: "200m"
            RequestMemory: "256Mi"
            LimitCpu: "4000m"
            LimitMemory: "2048Mi"
            # You may want to change this to true while testing a new image
            # AlwaysPullImage: true
            Command: "/bin/sh -c"
            Args: "cat"
            Tty: true             

搭配下面指令進行安裝:

helm install jenkins-x/jenkins-x-platform --name jenkins-x -f values.yaml

若已有安裝過,可用下面指令更新設置:

helm upgrade jenkins-x jenkins-x/jenkins-x-platform -f values.yaml

修改 configmap

kubectl edit configmaps jenkins-x-pod-templates --namespace jx

此方法比較簡單,但不好修正,主要是編輯不易,有需要可以參考

透過 Jenkins 後台設置

進入 https://JENKINSX_URL/configure,搜尋 pod Template

可透過介面輸入,但細節參數不好調整

建議使用 設置 helm values.yaml 的方式,另外兩個方式最主要的缺點為修正結果無法進行版本控制,再來就是 k8s 特性會因為資源的調度重啟 pod 或是必要時要重建節點,都會造成設置檔重置,最好的作法就是在 helm 的 values.yaml 在安裝時就寫入,如此將可適用各種狀況,這邊的重點不只適用於 Jenkins X,其他使用 helm 來作 k8s App 的安裝都是同樣的原理。

驗證設置是否正常,透過建立 devpod 確認

jx create devpod

? Pick which kind of DevPod you wish to create:
  dlang
> dotnetcore
  go
  gradle
  jx-base
  maven
  maven-java11

若能正常建立 devpod 到此可以確定 dotnetcore 建置環境已經在 Jenkins X 的控制範圍,接著就是實際應用於專案上,

專案建置使用

在 Jenkins X 的 Jenkinsfile 範本中,以 Jenkins X 官方 spring-boot-web-example 為例,參考下面連結

https://github.com/jenkins-x/spring-boot-web-example/blob/master/Jenkinsfile#L2-L4

agent.label 我們可以調整為

    agent {
        label "jenkins-dotnetcore"
    }

在建置中時,我們可以指定 Container,參考下面連結

https://github.com/jenkins-x/spring-boot-web-example/blob/master/Jenkinsfile#L9

其中 container('maven') 改為 container('dotnetcore') 即表示在 block 中相關指令的執行將用之前製作的 .NET Core 建置環境進行運作。

如此一來,就可以做為後續只要是 .NET Core 的專案,我們也可以透過 Jenkins X 來進行建置,並且部署到 k8s 上進行運作。

結論

上述步驟在做第一次環境建置時,確實步驟有點繁瑣,在第一次應用時,也花了一些時間了解設置的方式,及確認建置正常運作。

但一旦走過一次後,會更了解 Jenkins X 的使用,及在應用上更深的了解,基本上只要有需要任何語言搭配 Jenkins X 來進行建置,希望透過這篇文章,可以引導如何完成相關設置。

除此之外,也讓 Jenkins X 提供的 DevPod 功能能夠在不同語言環境進行開發,如此也可以針對特定專案定義專屬的開發環境,需要時就可以透過 k8s 提供對應的線上開發環境,在 dev 階段能夠更早進行整合驗證。