打造你的CI/CD管道:在Kubernetes上快速建立Jenkins

更新於 2024/01/29閱讀時間約 21 分鐘

將基礎的Kubernetes cluster建置之後,最多的用法就是建置CI/CD管道(pipeline),完整的將開發與部署的整個流程串連起來。

raw-image

本篇將說明如何建立一個基本的Jenkins,並且在架構上,將Jenkins Agent以動態的方式在有需要的方式進行產生,執行結束後又會自動將Agent Pod刪除,不會造成系統內有一大堆沒有作用的Pod耗用有限的資源。

最後也在Jenkins Web UI上建立一個最基本的Pipeline,簡單驗證本篇建立出來的Jenkins engine是可以正常運行。

照慣例,本篇章節如下:

  1. 架構說明
  2. 部署
  3. 安裝Plugins
  4. Jenkins Master設定
  5. 測試:執行單一Job
  6. 測試:執行Pipeline
  7. 結論

1.架構說明

傳統的Jenkins 一對多的架構會有以下問題:

  1. 如果Master出現問題,整個流程就無法運作
  2. 每個Slave的環境設定不同,當要完全不同語言的打包動作時,不同的環境配置對管理就相對不方便
  3. 資源分配不均,有些Slave JOB必須要排隊等待,但有的是空閒狀態,最後導致資源浪費

所以透過運行Jenkins master/slave在k8s cluster之內,可以很好的處理上述問題。

做法:Master 將設定資料存儲到volume內,Slave運行在各個節點上,且不是一直運行,是有需要才動態產生,結束時自動刪除。

這種方式解決了:

  1. 如果Jenkins master故障時,由k8s自動再重新建立一個Jenkins master,並且將volume分配給新建的master,資料不會丟失。
  2. 每運行一個Job才會建立一個slave,完成後就會自動刪除容器,自動釋放資源。同時由K8S自動分配資源到適合空閒的節點,避免過度集中在某些節上運行的排隊情況。
  3. 如果整個資源都不夠了,K8S直接再加入一個節點就可以解決。

2.部署

實際部署的方式有二種:

  • 全部都在K8S內運行 (本篇使用)
  • Master在K8S外部運行,所有執行的Slave在K8S內產生
#---------------------------------------------------
# S2-1. create namespace
#---------------------------------------------------
[master]# kubectl create ns jenkinspoc
#---------------------------------------------------
# S2-2. create service account
#---------------------------------------------------
[master]# vim jenkinspoc-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-admin
namespace: jenkinspoc
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jenkins
namespace: jenkinspoc
labels:
"app.kubernetes.io/name": 'jenkins'
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jenkins-role-binding
namespace: jenkinspoc
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins-admin
namespace: jenkinspoc

[master]# kubectl create -f jennkinspoc-sa.yaml -n jenkinspoc
serviceaccount/jenkins-admin created
role.rbac.authorization.k8s.io/jenkins created
rolebinding.rbac.authorization.k8s.io/jenkins-role-binding created

[master]# kubectl get sa -n jenkinspoc
#---------------------------------------------------
# S2-3. 建立給master存放資料的volume
#---------------------------------------------------
[master]# vim jenkinspoc-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pv-claim
spec:
storageClassName: managed-nfs-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

[master]# kubectl create -f jenkinspoc-pvc.yaml -n jenkinspoc
[master]# kubectl get pvc -n jenkinspoc
raw-image
#---------------------------------------------------
# S2-4. 部署Jenkins master
#---------------------------------------------------
[master]# vim jenkinspoc-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins-deployment
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
serviceAccountName: jenkins-admin
securityContext:
fsGroup: 1000
runAsUser: 1000
containers:
- name: jenkins
image: jenkins/jenkins:lts
resources:
limits:
memory: "2Gi"
cpu: "1000m"
requests:
memory: "500Mi"
cpu: "500m"
ports:
- name: httpport
containerPort: 8080
- name: jnlpport
containerPort: 50000
livenessProbe:
httpGet:
path: "/login"
port: 8080
initialDelaySeconds: 90
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 5
readinessProbe:
httpGet:
path: "/login"
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
volumeMounts:
- name: jenkins-data
mountPath: /var/jenkins_home
volumes:
- name: jenkins-data
persistentVolumeClaim:
claimName: jenkins-pv-claim

[master]# kubectl create -f jenkinspoc-deploy.yaml -n jenkinspoc
[master]# kubectl get pod -n jenkinspoc
#---------------------------------------------------
# S2-5. create svc
#---------------------------------------------------
[master]# vim jenkinspoc-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: jenkins-service
annotations:
prometheus.io/scrape: 'true'
prometheus.io/path: /
prometheus.io/port: '8080'
spec:
selector:
app: jenkins
type: NodePort
ports:
- name: httpport
port: 8080
targetPort: 8080
nodePort: 32003
- name: jnlpport
port: 50000
targetPort: 50000

[master]# kubectl create -f jenkinspoc-svc.yaml -n jenkinspoc
[master]# kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/jenkins-service NodePort 10.109.168.87 <none> 8080:32003/TCP,50000:30779/TCP 3sf
#---------------------------------------------------
# S2-6. Obtain admin passowrd
#---------------------------------------------------
[master]# kubectl get pod -n jenkinspoc
[master]# kubectl exec jenkins-deployment-bdf778654-br6mv -n jenkinspoc -- cat /var/jenkins_home/secrets/initialAdminPassword
b1a8117e9a364353855ebfe03b3308be

http://worker01.test.example.poc:32003
admin/P@ssw0rd

3.安裝Plugins

#---------------------------------------------
# S3-1. Install Suggestion plugin
#---------------------------------------------
raw-image
#---------------------------------------------
# S3-2. Install kubernetes plugin
#---------------------------------------------
Manage Jenkins > Plugins > Available plugins > "Kubernetes" > Install
raw-image

4.Jenkins Master設定

#---------------------------------------------
# S4-1. create cloud
#---------------------------------------------
Manage Jenkins > Clouds > New cloud > Name: K8s-pipeline (勾選Kubernetes) > Create
#---------------------------------------------
# S4-2. create credentials
# 因為全部都部署在同一座k8s,透過ServiceAccount的授權
#---------------------------------------------
Kubernetes URL : 免填
Certification key: 免填
Kubernetes namespace: jenkinspoc
=> test connection
raw-image
#---------------------------------------------
# S4-3. Jenkins URL
#---------------------------------------------
[syntax] http://<service-name>.<namespace>.svc.cluster.local:8080
Jenkins URL: http://jenkins-service.jenknspoc.svc.cluster.local:8080

=> SAVE
#---------------------------------------------
# S4-4. Pod template
#---------------------------------------------
Name: jenkins-agent
namespace: jenkinspoc
Labels: jenkinsagent <== Job會套用這個Label來找到要用那個Pod配置來建立
Containers:
(如果可以連到DockerHub,可以使用預設的jenkins/inbound-agent)
(以下使用自訂的jnlp,並且覆蓋預設值)
(1) Name: jnlp
(2) Image: jenkins/inbound-agent:latest
(3) 移除"Sleep" , "99999" <== 不然會改寫預設的Entrypoint
(4) Service Account : jenkins-admin

5.測試:執行單一Job

#---------------------------------------------
# S5-1. 建立Job
#---------------------------------------------
Dashboard > New item > name: jenkins-job-1 (free style project) > OK
Label express: jenkinsagent
Build Step > Excute Shell > echo "Test Jenkins JOB Successfully." > SAVE

> Build Now
raw-image
raw-image
raw-image
raw-image

6.測試:執行Pipeline

#---------------------------------------------
# S6-1. 建立Pipeline
#---------------------------------------------
Dashboard > New item > pipeline (name: pipeline-test) > OK
raw-image
#---------------------------------------------
# S6-2. Pipeline script
#---------------------------------------------
node('jenkinsagent') {
stage('Clone') {
echo "1.Clone Stage"
}
stage('Test') {
echo "2.Test Stage"
}
stage('Build') {
echo "3.Build Stage"
}
stage('Deploy') {
echo "4. Deploy Stage"
}
}

> SAVE > Build Now
raw-image
raw-image
raw-image

7.結論

基本上許多使用K8S架構的組織,都會配合CI/CD的各種工具來實際運作,本篇所說的Jenkins便是其中一個廣泛使用的工具之一,並且許多工作的技能需求也要求K8S工程師也要負責維護CI/CD Pipeline的順利運作,所以建議學習K8S平台的各位,至少也要掌握一個Pipeline的工具建置、操作、維護的技能。

本篇只演示了CI/CD中的其中一個階段,有興趣的話,可以先了解整個CI/CD完整的循環有那些階段與相關的工具。例如先前提到的Harbor registry就是循環內的另一個階段。

那今天就先到此為止,下篇再見囉 !!


References:

avatar-img
15會員
40內容數
記錄IT社畜的自我學習筆記,如同專題名稱,主要是怕自已忘記自已做過什麼、學到什麼。索性就分享我自已在學習Kubernetes這條路上的各種測試、學習心得。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
超健忘閒人的沙龍 的其他內容
本篇說明如何利用Kubernetes特色,將PostgreSQL DB以HA的架構來提供服務,並說明相關的實作流程與說明。
當您在K8S Cluster中使用Harbor作為容器鏡像的儲存庫時,隨著應用服務鏡像的增加,如何透過內建機制將一臺Harbor的內容同步到另一個Harbor就變得愈來愈重要。本文將介紹如何透過內建機制同步Harbor的內容以及支援Harbor同步到其他相容的Image Registry的方式。
本篇將分享關於nginx ingress controller的基本操作,包括預先準備、流程、實際操作、將domain name 映射到Ingress LB IP、部署Demo App 驗證以及結論。
本文將演示在安裝完 Kubernetes Cluster 後的基本元件安裝,包括 Calico/Calicoctl、Metric Server 和 Dashboard UI 的安裝方法以及相關問題與解決方式。
這篇文章教你如何搭建Kubernetes Cluster,包括節點安裝前設定、軟體套件安裝、Control-Plane部署和加入運算節點等步驟。在建置之後,作者會分享一些基礎服務的安裝。希望這篇文章對你有所幫助。
本文章將說明如果您想要從頭建置一組具有Loadbalancer HA架構的Kubernetes Cluster時,你可能會需要做的事前準備工作。
本篇說明如何利用Kubernetes特色,將PostgreSQL DB以HA的架構來提供服務,並說明相關的實作流程與說明。
當您在K8S Cluster中使用Harbor作為容器鏡像的儲存庫時,隨著應用服務鏡像的增加,如何透過內建機制將一臺Harbor的內容同步到另一個Harbor就變得愈來愈重要。本文將介紹如何透過內建機制同步Harbor的內容以及支援Harbor同步到其他相容的Image Registry的方式。
本篇將分享關於nginx ingress controller的基本操作,包括預先準備、流程、實際操作、將domain name 映射到Ingress LB IP、部署Demo App 驗證以及結論。
本文將演示在安裝完 Kubernetes Cluster 後的基本元件安裝,包括 Calico/Calicoctl、Metric Server 和 Dashboard UI 的安裝方法以及相關問題與解決方式。
這篇文章教你如何搭建Kubernetes Cluster,包括節點安裝前設定、軟體套件安裝、Control-Plane部署和加入運算節點等步驟。在建置之後,作者會分享一些基礎服務的安裝。希望這篇文章對你有所幫助。
本文章將說明如果您想要從頭建置一組具有Loadbalancer HA架構的Kubernetes Cluster時,你可能會需要做的事前準備工作。
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
在前面幾篇文章中,我們曾不斷強調流量紅利的美好時代已逐漸消退,如今企業面臨的最大挑戰是,怎麼打造一個好的「流量池系統」,從增量策略進化到存量策略,其中,我認為最關鍵也或許是CP值最高的部分,就是如何將「流失使用者(Churned Users)」轉變成「復活使用者(Resurrected Users)
Thumbnail
試想一個情境,早上你起床泡了一杯咖啡,拿起手機看到IG跳出了個新通知,原來是自己的好朋友Tina假日去了一間新開的網美餐酒館,上傳一段有bartender秀出調酒炫技的限時動態影音,精采的畫面令你嘆為觀止,接著,你馬上對此視頻給予按讚回應,沒多久之後,Tina看到並回覆你私訊,還跟你聊了那天的餐點多
Thumbnail
有鑑於此,上述的情況就可能造成公司,必須不斷擴展漏斗頂部的口,投入資源、金錢、時間更大,讓新訪客越來越多,才有辦法使產品不斷成長達標,只是,我們不禁思考著,產品步入到殘酷的市場軍備競賽輪迴中,是唯一的道路嗎? 忠誠度循環(Loyalty Loop) 適用於數位產品的忠誠度循環 設計產品的互動接觸點
Thumbnail
流量的困境 由此可知,曾經的流量紅利時代,已逐漸走入消逝,想要單純依靠獲取新客流量達成商業目標,只會越來越困難,因此,怎麼從「增量」的概念轉移到如何經營「存量」,就變得相當重要了! 互動(Engagement)、黏著(Stickiness)、留存(Retention)及增長(Growth) 小結
Thumbnail
先問一個問題,投資與理財一樣嗎?  就像起厝一樣,打地基要最久時間,地下室穩了,上面的樓層才有越蓋越高的條件,這道理反映在投資理財也是一樣的。  所以回答一開始的問題,「理財」就跟打地基一樣,讓你「守下限」;而「投資」如同蓋大樓一樣,用來「衝上限」。  投資和理財這兩件事截然不同。  古埃及人蓋金字
Thumbnail
為什麼學習要輸出?「即時的正向反饋」對於強化你的學習動機很重要,只有當你實際動手把學到的東西整理起來輸出,才能更有效地了解自己的學習成果,獲得鼓勵與成就感,作為驅動你持續輸入的動力。只有當你有了表達與輸出的動機了之後,才會更有意識去注意一些平時忽略的細節,更加主動去
Thumbnail
艾兒莎的「打造知識體系」這個系列主題,會有連續幾篇文章,跟大家分享從知識的「輸入」、「統整」到「輸出」!上篇跟大家分享了知識的「輸入」,包含被動轉為主動的資訊挖掘、選書的十種方式、怎麼從資訊管道擴增概念庫、如何讀懂一本書等等,這篇將跟大家分享關於「統整」的部分,如何「拆解與統整知識的邏輯」!
Thumbnail
艾兒莎的「打造知識體系」這個系列主題,會有連續幾篇文章,跟大家分享從知識的「輸入」、「統整」到「輸出」!上篇跟大家分享了知識的「輸入」,包含被動轉為主動的資訊挖掘、選書的十種方式等。這篇會分享怎麼「從資訊管道擴增概念庫」以及如何「讀懂一本書」!
Thumbnail
在這個時代,我們可以取得的學習資源非常非常多,跟以前相比可說是唾手可得!不管是實體課或是線上課,許多人因為焦慮而去學了很多東西、上了很多課程,卻好像沒有明顯的進步。為什麼呢?關鍵其實是因為,只有「輸入」,沒有「消化」和「吸收」。雖然一直拼命上課,但卻沒有真的消化與吸收進去這些你所學的東西。
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
在前面幾篇文章中,我們曾不斷強調流量紅利的美好時代已逐漸消退,如今企業面臨的最大挑戰是,怎麼打造一個好的「流量池系統」,從增量策略進化到存量策略,其中,我認為最關鍵也或許是CP值最高的部分,就是如何將「流失使用者(Churned Users)」轉變成「復活使用者(Resurrected Users)
Thumbnail
試想一個情境,早上你起床泡了一杯咖啡,拿起手機看到IG跳出了個新通知,原來是自己的好朋友Tina假日去了一間新開的網美餐酒館,上傳一段有bartender秀出調酒炫技的限時動態影音,精采的畫面令你嘆為觀止,接著,你馬上對此視頻給予按讚回應,沒多久之後,Tina看到並回覆你私訊,還跟你聊了那天的餐點多
Thumbnail
有鑑於此,上述的情況就可能造成公司,必須不斷擴展漏斗頂部的口,投入資源、金錢、時間更大,讓新訪客越來越多,才有辦法使產品不斷成長達標,只是,我們不禁思考著,產品步入到殘酷的市場軍備競賽輪迴中,是唯一的道路嗎? 忠誠度循環(Loyalty Loop) 適用於數位產品的忠誠度循環 設計產品的互動接觸點
Thumbnail
流量的困境 由此可知,曾經的流量紅利時代,已逐漸走入消逝,想要單純依靠獲取新客流量達成商業目標,只會越來越困難,因此,怎麼從「增量」的概念轉移到如何經營「存量」,就變得相當重要了! 互動(Engagement)、黏著(Stickiness)、留存(Retention)及增長(Growth) 小結
Thumbnail
先問一個問題,投資與理財一樣嗎?  就像起厝一樣,打地基要最久時間,地下室穩了,上面的樓層才有越蓋越高的條件,這道理反映在投資理財也是一樣的。  所以回答一開始的問題,「理財」就跟打地基一樣,讓你「守下限」;而「投資」如同蓋大樓一樣,用來「衝上限」。  投資和理財這兩件事截然不同。  古埃及人蓋金字
Thumbnail
為什麼學習要輸出?「即時的正向反饋」對於強化你的學習動機很重要,只有當你實際動手把學到的東西整理起來輸出,才能更有效地了解自己的學習成果,獲得鼓勵與成就感,作為驅動你持續輸入的動力。只有當你有了表達與輸出的動機了之後,才會更有意識去注意一些平時忽略的細節,更加主動去
Thumbnail
艾兒莎的「打造知識體系」這個系列主題,會有連續幾篇文章,跟大家分享從知識的「輸入」、「統整」到「輸出」!上篇跟大家分享了知識的「輸入」,包含被動轉為主動的資訊挖掘、選書的十種方式、怎麼從資訊管道擴增概念庫、如何讀懂一本書等等,這篇將跟大家分享關於「統整」的部分,如何「拆解與統整知識的邏輯」!
Thumbnail
艾兒莎的「打造知識體系」這個系列主題,會有連續幾篇文章,跟大家分享從知識的「輸入」、「統整」到「輸出」!上篇跟大家分享了知識的「輸入」,包含被動轉為主動的資訊挖掘、選書的十種方式等。這篇會分享怎麼「從資訊管道擴增概念庫」以及如何「讀懂一本書」!
Thumbnail
在這個時代,我們可以取得的學習資源非常非常多,跟以前相比可說是唾手可得!不管是實體課或是線上課,許多人因為焦慮而去學了很多東西、上了很多課程,卻好像沒有明顯的進步。為什麼呢?關鍵其實是因為,只有「輸入」,沒有「消化」和「吸收」。雖然一直拼命上課,但卻沒有真的消化與吸收進去這些你所學的東西。