前言
原本公司內部CI/CD的流程是Gitlab => K8s ,或是 Gitlab => Docker
近期由於工作上的需要,需要更改流程為Gitlab => Jenkins => K8s
本篇主要是紀錄Gitlab串接Jenkins,最後透過Jenkins部屬到K8s集群的流程。
事前準備
此次測試需要準備一台Jenkins Server、一台Gitlab Server、K8s集群以及一個前端專案,前端專案資訊為以下:
- NodeJs 18.19.0
- Vue3 + Nuxt 3
Jenkins連結Gitlab
此處可以參考GitLab官方網站的教學
這邊就快速帶過
建立Jenkins作業
開啟Jenkins網站,選擇左側的”新增作業”
輸入作業名稱,選擇作業類型選擇Pipeline,最後點選OK
如果在上上節有設定成功
Gitlab Connection的部分應該可以選擇的到gitlab server
Build Triggers的部分只要勾”Build when a change is pushed to GitLab ….”
和”Push Events”這兩項,表示當Gitlab的前端專案有Push事件時,就會通知Jenkins做部屬
這裡的GitLab Webhook URL要記住等等設定Gitlab時會用到
p.s. 需要事先設定好Jenkins的Jenkins URL,否則Gitlab會連不上
再來點選右下角的進階,點選裡面的Generate按鈕,會產生一組Secret token,Jenkins需要透過這組token和Gitlab傳過來的webhook驗證身分,很重要!
最後Pipeline的部分目前先選擇右方的Hello World模板即可,設定完畢後點選儲存
設定Gitlab Webhook
回到Gitlab的前端專案,點選左側的Settings => Webhooks
輸入剛才的GitLab Webhook URL以及Secret token
Trigger 勾選Push events
如果Gitlab和Jenkins有HTTPS可以開啟SSL認證,最後點選Add webhook
會看到與Jenkins連結的Webhook已經建立完成了,現在可以測試webhook是否正常運行
點選Test按鈕
再點選Push events
這裡沒問題的話就會在最底下出現一個狀態為200的Push-Hook Trigger
回去確認Jenkins狀態會看到此時有建置任務在跑了
安裝K8s plugins
確認Jenkins與Gitlab連線沒問題後
下一步驟就是要將專案部屬至K8s集群上
需要安裝的Jenkins plugins為以下:
設定K8s集群憑證
安裝完成後需要先設定k8s集群的憑證
這樣才能連入k8s集群內做操作
至”管理 Jenkins” => “Manage Credentials” => global => Add Credentials
Kind選擇”Kubernetes configuration(kubeconfig)”
ID、Description依照自己習慣定義即可
Kubeconfig選擇 “Enter directly”
接著到你自己的k8s master server
複製你的kubeconfig
我的kubeconfig如下圖所示
將config檔的內容貼到jenkins上
最後選擇OK後,k8s的憑證就設定完成了
完成Pipeline
最後要回到專案的Pipeline設定
以下是更改後的Pipeline:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
pipeline {
agent any;
tools {nodejs "NodeJS 18.19.0"}
environment {
// gitlab
GITLAB_DOMAIN = {your gitlab domain}
GITLAB_CID = {your gitlab Credentials ID}
GITLAB_PROJ_PATH = {your gitlab project Path}
GITLAB_PROJ_NAME = {your gitlab project Name}
GITLAB_BRANCH = {your gitlab project branch}
// registry
HARBOR_REG_URI = {your harbor domain}
HARBOR_REG_CID = {your harbor Credentials ID}
HARBOR_REG_PROJ_NAME = {your harbor Project Name}
HARBOR_REG_DATA_PATH = "${HARBOR_REG_PROJ_NAME}/${env.GITLAB_PROJ_PATH}/${env.GITLAB_PROJ_NAME}/${env.GITLAB_BRANCH}"
// k8s
KUBE_DEPLOYMENT_NAME = "deployment-${GITLAB_PROJ_NAME}"
KUBE_DEPLOYMENT_POD_NAME = "pod-${GITLAB_PROJ_NAME}"
KUBE_NAMESPACE = "${GITLAB_PROJ_NAME}-${GITLAB_BRANCH}"
KUBE_CID = 'k8s-kubeconfig'
}
stages {
stage('NPM INSTALL && BUILD') {
steps {
git url: "https://${env.GITLAB_DOMAIN}/${env.GITLAB_PROJ_PATH}/${env.GITLAB_PROJ_NAME}.git", branch: "${env.GITLAB_BRANCH}", credentialsId: "${env.GITLAB_CID}"
sh "npm install"
sh "npm run generate"
}
}
stage('上傳image') {
environment {
IMAGE_VER = sh(returnStdout: true, script: 'git rev-parse --short HEAD')
}
steps {
echo "上傳image 版本 ${env.IMAGE_VER}"
script {
docker.withRegistry("https://${env.HARBOR_REG_URI}", "${env.HARBOR_REG_CID}"){
def BuildImage = docker.build("${HARBOR_REG_DATA_PATH}")
BuildImage.push()
BuildImage.push("${IMAGE_VER}")
}
}
}
}
stage('建置服務') {
environment {
IMAGE_VER = sh(returnStdout: true, script: 'git rev-parse --short HEAD')
}
steps {
withCredentials([kubeconfigContent(credentialsId: "${KUBE_CID}", variable: 'KUBECONFIG_CONTENT')]) {
sh 'mkdir -p ~/.kube'
sh '''echo "$KUBECONFIG_CONTENT" > ~/.kube/config'''
sh "kubectl -n ${env.KUBE_NAMESPACE} set image deployment ${env.KUBE_DEPLOYMENT_NAME} ${env.KUBE_DEPLOYMENT_POD_NAME}=${env.HARBOR_REG_URI}/${HARBOR_REG_DATA_PATH}:${env.IMAGE_VER}"
script {
env.POD_COMPLETE_NAME = sh(returnStdout: true,script: "kubectl get pods -n ${env.KUBE_NAMESPACE} |grep ${env.KUBE_DEPLOYMENT_NAME} | awk '{ print \$1 }'| tr '\n' ' '").trim()
sh "kubectl -n ${env.KUBE_NAMESPACE} delete pods ${env.POD_COMPLETE_NAME} "
}
}
}
}
}
}
environment的部分用來設定gitlab、harbor以及k8s需要的參數
舉例來說 GITLAB_DOMAIN 就是你的 Gitlab 域名
GITLAB_CID 和 HARBOR_REG_CID 就是你用來登入Gitlab或是Harbor的憑證
詳細的憑證設定可參考官網的這兩篇教學
此處就不多作介紹
KUBE_DEPLOYMENT_NAME 是你k8s專案的 deployment 名稱
KUBE_DEPLOYMENT_POD_NAME 則是pod的名稱
此處CI/CD的前提是一開始需要手動跑一次kubectl apply -f deployment.yaml
之後在執行CI/CD時,會將舊的image更換成harbor內最新的image
所以每個專案都需要維護一份自己的k8s yaml檔
建議可以存在gitlab上方便維護
這裡有三個stage
依序是專案打包 => 上傳專案Image => 在k8s集群上建置該服務
這邊只是大概說明一下這個Pipeline在做甚麼
更詳細的參數說明可以再GOOGLE
確認Pipeline沒問題後即可點選儲存
建置任務
編輯完Pipeline後,回到JOB頁面
即可點選左側的馬上建置
等個幾秒鐘應該就會開始執行
等待建置完畢後,查看k8s確認service是否有正確起動後即完成整個CI/CD流程👏
結尾
以上整個流程大致為:
Gitlab推Code => 觸發jenkins部屬流程 => 執行Pipeline的指令 => 將服務部屬至K8s集群上
該篇有許多細節沒有講到,例如Gitlab憑證要如何設定至jenkins上
以及k8s的deployment詳細該怎麼設定等等
以後如果有空再找時間補起來😫
目前先請大家自行研究一下🙏