在 Kubernetes 中運行 Jenkins X 並設置特定程式語言之建置環境,以 .NET Core 為例。
距離上一篇 Jenkins X 簡介及建置流程概念介紹 經過了一段時間,在公司內透過 Jenkins X 進行了三個專案的建置,分別是 PHP、Node.js 及 .NET Core,對 Jenkins X 有近一步的認識,透過此文記錄一下,也分享給大家。
在開始此篇文章之前,假設讀者已經有 Kubernetes + Jenkins X + jx + helm 的運作環境,並且對於 kubectl 及 helm 有初步的操作經驗。
若需要上述安裝程序的話可參考下面連結:
- Jenkins X install: https://github.com/jenkins-x/jx-docs/blob/master/content/getting-started/install-on-cluster.md
- jx install: https://github.com/jenkins-x/homebrew-jx
- helm install: https://github.com/helm/helm/blob/master/docs/install.md
第一步需要有足夠的 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 階段能夠更早進行整合驗證。