devops-4:Jenkins基於k8s cloud和docker cloud動態增減節點
Jenkins管理動態節點
上文介紹Jenkins增加靜態agent的步驟,除了靜態增加外,還有動態管理的功能,兩者最大的差異在於動態可以在有job運行時,臨時加入一個agent到jenkins master,然後等job執行完畢之後,所加入的agent再自動刪除掉,達到一個動態的增刪節點效果,使所有的job都在遠端的某個集群中執行。
目前執行動態擴縮節點的方式有docker cloud和k8s cloud。
docker cloud配置
-
首先需要安裝docker插件,系統管理—>插件管理—>可選插件—>搜索docker,主要的有Docker 、docker pipeline插件,其他插件可以酌情下載。
-
配置docker守護進程,使其可以通過主機ip+埠的形式訪問:
vi /etc/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:8376
添加此配置後,重新啟動docker,主機便會暴露8376埠,供客戶端訪問,需要注意安全問題,可以通過防火牆等安全設備對埠進行限制,也可以為此埠指定證書,必須有此埠證書和私鑰才可以訪問成功。
-
在Jenkins端配置docker cloud,系統管理—>節點管理—>Configure Clouds—>Add a new cloud—>Docker
-
配置Docker Cloud details,主要是配置地址+埠,如果有證書則也配置上證書。
配置完成後,點擊後邊的Test Connection,顯示出docker version 和 Api version後,表示連接成功。
-
配置Docker Agent templates,要修改的主要配置為以下幾點:
- Labels:agent的label,用於指定匹配該cloud
- Name:用於加入Jenkins slave的名字前綴
- Docker Image:用於創建臨時節點的鏡像,相當於有job要執行時,會docker run此鏡像,然後以slave節點的方式加入到Jenkins Master,並將job在此slave節點執行,執行完畢後,會直接docker rm掉
- Remote File System Root:臨時節點的家目錄
- Connect method:節點的加入方式,一般選用Attach Docker container即可,jenkins master會直接將slave所需的程式碼複製到此節點中,並用容器內的java啟動,所以使用此方式要滿足兩條硬條件:必須有java環境和container的CMD必須是/bin/bash或者為空
其他一些不是特別重要的參數,例如:Pull timeout拉取超時時間、Pull strategy拉取策略等可以進行相應的調整。
測試使用docker cloud運行一個Pipeline
以上步驟全部完成之後,docker cloud就可以正常使用,下邊創建一個測試流水線:
pipeline {
agent {
label 'java-maven-app'
}
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
}
tools {
maven 'apache-maven-3.8.6'
}
stages {
stage('mvn version') {
steps {
sh 'mvn -v'
}
}
stage('java version') {
steps {
sh 'java -version'
}
post {
always {
sh 'echo "test complete"'
}
}
}
}
}
開始執行流水線:
可見此流水線在名稱為 java-maven-app-001ocj3t66f69 的節點中運行,再去查看節點列表,發現多了一個叫這個名字的節點:
再查看docker容器,發現剛剛運行了一個jenkins/agent的容器:
Pipeline執行完畢後,容器被摧毀,節點也被剔除,實現了動態的docker cloud管理。
Kubernetes Cloud配置
-
系統管理->插件管理->可選插件,搜索kubernetes直接安裝
-
k8s插件安裝完畢後,開始添加雲節點:系統管理—>節點管理—>Configure Clouds—>Add a new cloud—>Kubernetes
-
配置Kubernetes Cloud details,主要配置名稱、k8s apiserver地址、jenkins地址、k8s服務證書以及加密成.pfx類型的證書key:
apiserver地址和jenkins地址不用強調,都知道怎麼填,重點需要強調兩個證書:
- Kubernetes 服務證書 key:這個實際就是你k8s集群的ca.crt證書,一般在/etc/kubernetes/pki/ca.crt,直接copy過來即可
- 第二個主要是因為k8s apiserver是https的通訊方式,所以要將其集群證書的公私鑰打包成.pfx類型,然後提供給jenkins來訪問
這裡需要手動生成第二個.pfx類型的證書:
(1)首先需要安裝證書生成工具:
# curl -s -L -o /usr/local/bin/cfssl //pkg.cfssl.org/R1.2/cfssl_linux-amd64 # curl -s -L -o /usr/local/bin/cfssljson //pkg.cfssl.org/R1.2/cfssljson_linux-amd64 # curl -s -L -o /usr/local/bin/cfssl-certinfo //pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 # chmod +x /usr/local/bin/cfssl*
(2)然後準備證書籤名請求
vi jenkins-csr.json
{ "CN": "admin", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "XS", "O": "system:masters", "OU": "System" } ] }
證書請求中的O 指定該證書的 Group 為 system:masters,而 RBAC 預定義的 ClusterRoleBinding 將 Group system:masters 與 ClusterRole cluster-admin 綁定,這就賦予了該證書具有所有集群許可權 。
(3)創建admin證書和私鑰
# cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key --profile=kubernetes jenkins-csr.json | cfssljson -bare admin # ls admin-key.pem admin.pem jenkins-csr.json
生成證書與key
(4)生成.pfx類型證書
# openssl pkcs12 -export -out ./jenkins-admin.pfx -inkey ./admin-key.pem -in ./admin.pem -passout pass:jenkins # ls jenkins-admin.pfx
指定admin的公鑰私鑰生成jenkins-admin.pfx,並設置密碼為jenkins
(5)將證書添加至jenkins憑證中
(6)最終再應用到k8s cloud中
測試連接出現版本號即連接成功
-
配置Pod Templates
主要配置標籤和用法以及pod的出事YAML,其他像volume、network或secret等都可以再yaml中提前編寫
有kubernetes-agent標籤的job會匹配到此agent
定義的一個基礎YAML模板,可以在裡邊定義更多的配置
再就是要定義一下workspace採取什麼形式,分別有這幾種:
根據自己需求,需不需要持久化來決定使用哪種方式
-
至此基本配置已經完成,還有一點需要注意,當有job要執行時,生成的pod中會有自己定義的一個容器和jenkins用於提供agent連接的容器,共兩個,默認情況jenkins agent生成的容器會拉取
jenkins/inbound-agent:4.11-1-jdk11
這個鏡像,可以提前下載下來,或者重新指定一個鏡像:
編輯流水線測試使用Kubernetes cloud
新建任務—>pipeline—>拉到最下邊選擇Pipeline script form SCM—>SCM選擇Git—>填寫項目的URL及認證
—>指定分支—>指定腳本的路徑
這個就表示會直接從你指定的程式碼倉庫中去拉取程式碼,並根據倉庫中指定的Jenkinsfile進行構建,程式碼倉庫結構如下:
指定的Jenkinsfile文件內容如下:
pipeline {
agent {
kubernetes {
cloud 'kubernetes-internal' //指定k8s cloud的名稱
label 'kubernetes-agent' //指定label
defaultContainer 'example.com:5000/jenkins/agent:latest' //可以指定運行的鏡像,不指定會默認使用配置k8s cloud時的默認鏡像
inheritFrom 'jenkins-agent' //指定所用的podTemplate,其實是多餘的,因為就算不指定,也會用配置k8s cloud時,配置的pod Template
namespace 'default'
}
tools {
maven 'apache-maven-3.8.6'
}
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
}
stages {
stage('Build') {
steps {
sh 'mvn -B -DskipTests clean package'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
stage('Deliver') {
steps {
sh './jenkins/scripts/deliver.sh'
}
}
}
}
執行結果:
以k8s pod為agent的臨時節點已經加入:
k8s中pod也已經啟動,Pipeline執行結束後,自動摧毀。