Jenkins連接k8s的多種姿勢


1、概述

本文分享的是基於k8s環境與jenkins實現CI/CD其中的一個配置具體實現

即:不同環境下jenkins與k8s集群連接的問題

為什么會有不同的環境?我總結的原因如下:

a、在實際生產環境中,由於某些歷史原因我們或許不能完美的實現所謂的一切皆“雲原生”,例如有傳統的jenkins和執行專有任務的slave節點

b、存在多集群共一個jenkins服務端的情況,例如k8s中集群A用作基礎設施集群(包含日志、存儲、devops平台),集群BCD用作不同業務線集群

因此,我們可以將不同環境定義為如下兩種情況:

  • 同集群:指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 slavepod模板,當然也可以在每個流水線中單獨指定

配置完成后的動態創建jenkins slave pod測試在本文后面一並給出

3、跨集群

一個實際場景:jenkins部署在A集群或部署在傳統VM的環境下,想通過jenkins連接B集群,動態創建pod用以執行構建任務

3.1 端口有什么

既然是跨集群,那么首先需要考慮的就是網絡問題,網絡是否可達?需要開通哪些端口的安全組策略?

在這之前,就需要先了解一下jenkins的運行機制及端口有哪些?

  • http端口:默認8080,如果在jenkins前面做了反向代理並配置了域名,那么可能是常見的80/443端口,我這里通過域名+https的方式訪問jenkins

  • Agent Port:基於JNLPJenkins代理通過TCP默認端口50000Jenkins進行通信

  • SSH port:jenkins作為ssh服務器,這個一般不會使用,具體使用可參考我之前的文章Jenkins workflowLibs庫的使(妙)用

3.2 網絡策略打通

由上面知道了有哪些端口之后,因此需要打通的網絡策略包括

  • B集群節點連接jenkins暴露的http portAgent port
  • A集群節點(即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.crtclient.crtclient.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.crt

client-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 導入證書

生成文件后,打開jenkinsweb界面

添加全局憑據,憑據的類型選擇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
                  """
                }
            }
        }
    }
}

構建后查看控制台輸出

到這里,基於不同基礎環境下jenkinsk8s連接配置的相關操作就分享完啦

See you ~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM