目錄
1、概述
2、同集群
3、跨集群
3.1 埠有什麼
3.2 網絡策略打通
3.3 證書的生成和配置
3.4 配置連接外部的 k8s 集群
4、測試驗證
4.1 配置 pod template
4.2 自由風格構建測試
4.3 流水線構建測試
本文分享的是基於k8s環境與jenkins實現CI/CD其中的一個配置具體實現
即:不同環境下 jenkins 與 k8s 集群連接的問題
為什麼會有不同的環境?我總結的原因如下:
a、在實際生產環境中,由於某些歷史原因我們或許不能完美的實現所謂的一切皆「雲原生」,例如有傳統的jenkins和執行專有任務的slave節點
b、存在多集群共一個jenkins服務端的情況,例如k8s中集群A用作基礎設施集群(包含日誌、存儲、devops平臺),集群B、C、D用作不同業務線集群
因此,我們可以將不同環境定義為如下兩種情況:
同集群:指k8s集群內部的jenkins連接本集群
跨集群:指外部的jenkins連接k8s集群,或者是jenkins連接外部的k8s集群
2、同集群同集群下,k8s集群內部的jenkins連接所在的k8s集群。這是原生的方式:我們的環境都是全新的,全新的機器、全新安裝的集群、全新的jenkins,總之一切都是新的,沒有任何歷史問題
由於在k8s集群內部部署jenkins時,已經對jenkins做了以下相關的角色授權綁定
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
namespace: kube-system
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: jenkins
namespace: kube-system
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/v1beta1
kind: RoleBinding
metadata:
name: jenkins
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
namespace: kube-system因此只需要在jenkins中配置相應的連接地址就可以了
在jenkins中安裝好k8s插件後,打開jenkins——>系統管理——>系統配置——>新增一個kubernetes雲
配置名稱,即這個雲的別名
Kubernetes地址,即在集群內部暴露的k8s service名稱
Kubernetes命名空間,這個配置就填寫jenkins所屬的namespace
Jenkins地址,填寫jenkins svc的名稱
配置完成後點擊測試連接成功
後面配置pod template這裡不做介紹,這裡配置的pod template是默認情況下jenkins slave的pod模板,當然也可以在每個流水線中單獨指定
配置完成後的動態創建jenkins slave pod測試在本文後面一併給出
3、跨集群一個實際場景:jenkins部署在A集群或部署在傳統VM的環境下,想通過jenkins連接B集群,動態創建pod用以執行構建任務
3.1 埠有什麼既然是跨集群,那麼首先需要考慮的就是網絡問題,網絡是否可達?需要開通哪些埠的安全組策略?
在這之前,就需要先了解一下jenkins的運行機制及埠有哪些?
http 埠:默認8080,如果在jenkins前面做了反向代理並配置了域名,那麼可能是常見的80/443埠,我這裡通過域名+https的方式訪問jenkins
Agent Port:基於JNLP的Jenkins代理通過TCP默認埠50000與Jenkins進行通信
SSH port:jenkins作為ssh伺服器,這個一般不會使用,具體使用可參考我之前的文章Jenkins workflowLibs 庫的使(妙)用
3.2 網絡策略打通由上面知道了有哪些埠之後,因此需要打通的網絡策略包括
B 集群節點連接jenkins暴露的http port和Agent portA 集群節點(即jenkins server)連接B集群kube-apiserver暴露的埠除網絡策略之外,如果jenkins UI的地址,例如通過ingress設置了白名單限制訪問,還需要將B集群的相關源ip設置為白名單
3.3 證書的生成和配置3.3.1 kubeconfig 文件由於這裡A集群中的jenkins並沒有對B集群的操作權限,因此需要配置授權,即發起對B集群的kube apiserver的請求,和kubectl一樣利用config文件用作請求的鑑權,默認在~/.kube/config下,當然我們也可以單獨嚴格指定權限細節,生成一個jenkins專用的config文件,這裡就不再延伸了,kubeconfig文件的組成如下
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: xxx
server: https://<master-ip>:6443
name: cluster1
contexts:
- context:
cluster: cluster1
user: admin
name: context-cluster1-admin
current-context: context-cluster1-admin
kind: Config
preferences: {}
users:
- name: admin
user:
client-certificate-data: xxx
client-key-data: xxx其中包含了3段證書相關的內容,也就是我們常見的證書組成格式:ca.crt、client.crt、client.key
3.3.2 生成證書在jenkins中能夠識別的證書文件為PKCS#12 certificate,因此需要先將kubeconfig文件中的證書轉換生成PKCS#12格式的pfx證書文件
首先,使用yq命令行工具來解析yaml並通過base 64解碼生成各個證書文件
服務端證書:
certificate-authority-data——>base 64解碼——>ca.crt
yq e '.clusters[0].cluster.certificate-authority-data' .kube/config | base64 -d > ca.crt客戶端證書
client-certificate-data——>base 64解碼——>client.crt
yq e '.users[0].user.client-certificate-data' .kube/config | base64 -d > client.crtclient-key-data——>base 64解碼——>client.key
yq e '.users[0].user.client-key-data' .kube/config | base64 -d > client.key然後,通過openssl進行證書格式的轉換,生成Client P12認證文件cert.pfx
openssl pkcs12 -export -out cert.pfx -inkey client.key -in client.crt -certfile ca.crt
Enter Export Password: # 輸入密碼加密
Verifying - Enter Export Password:通過踩坑證明,這裡必須輸入密碼,不然在後面添加jenkins相關配置後驗證會報錯
3.3.3 導入證書生成文件後,打開jenkins的web界面
添加全局憑據,憑據的類型選擇Certificate,選擇Upload PKCS#12 certificate
上傳剛才生成的cert.pfx證書文件
輸入通過openssl生成證書文件時輸入的密碼
檢查上傳的證書文件,此時可以查看到,jenkins已經成功加載了證書文件並讀取了證書文件的相關信息
3.4 配置連接外部的 k8s 集群在jenkins中新增kubernetes雲配置
同樣的,打開jenkins——>系統管理——>系統配置——>新增一個kubernetes雲
配置名稱,即這個雲的別名,為外部的 k8s 集群起一個別名
Kubernetes地址,這裡需要填寫的是外部集群的kube-apiserver地址,即https://<master ip>:6443
Kubernetes服務證書key,填寫上面服務端證書base64解碼後的內容
Kubernetes命名空間,填寫jenkins所屬的namespace
憑據選擇上面導入的證書文件作為憑據
Jenkins地址,填寫A集群現有jenkins UI域名(訪問地址和埠)
配置完成後點擊測試連接成功,到這裡跨集群的jenkins連接k8s就成功了
4、測試驗證4.1 配置 pod template這裡以跨集群的環境下進行測試驗證A集群的jenkins執行構建任務,在B集群中動態創建slave的預期結果
在jenkins系統配置中,除了配置關聯外部集群外,這裡再配置一下相應的pod template,以便於在B集群中創建默認的slave pod,如圖
4.2 自由風格構建測試在自由風格中限制項目的運行節點,標籤為上面配置的pod template標籤即k8s-test-cluster,執行shell命令進行測試,查看控制臺輸出
4.3 流水線構建測試編寫測試的pipeline流水線,同樣指定標籤為上面配置的pod template標籤即k8s-test-cluster
pipeline{
agent{
node {
label 'k8s-test-cluster-jnlp-slave'
}
}
stages{
stage('Deploy to Kubernetes'){
steps{
script{
sh """
kubectl version
kubectl get cs
"""
}
}
}
}
}構建後查看控制臺輸出
到這裡,基於不同基礎環境下jenkins與k8s連接配置的相關操作就分享完啦
See you ~