Jenkins的Master-Slave分布式架構主要是為了解決Jenkins單點構建任務多、負載較高、性能不足的場景。
Master-Slave相當于Server和Agent的概念。Master提供web接口讓用戶來管理job和Slave,job可以運行在Master本機或者被分配到Slave上運行構建。
一個Master(Jenkins服務所在機器)可以關聯(lián)多個Slave用來為不同的job或相同的job的不同配置來
實現(xiàn)Master-Slave分布式架構,重點就是管理配置Slave;Slave的配置方式有以下幾種:
-
SSH agent: 即把某個虛擬機或物理機作為agent來執(zhí)行任務 -
Docker Agent:在另外的一臺虛擬機或物理機上,安裝docker Agent,通過ssh或docker遠程協(xié)議的方式,讓agent來執(zhí)行任務
這里來詳細說說如何配置Docker Agent模式
準備
| 說明 | Description |
|---|---|
| 10.3.23.191 | Jenkins Master,需提前安裝好Jenkins |
| 10.3.23.207 | Slave,需提前安裝好Docker環(huán)境 |
| Docker版本 | 20.10.9 |
配置Slave
由于Master要通過docker 遠程協(xié)議進行通信,所以需要把slave上docker的遠程協(xié)議打開。
登錄Slave機器
# 查詢docker服務文件
systemctl status docker|grep Loaded|grep -Po '(?<=Loaded: loaded \()[^;]*'
/usr/lib/systemd/system/docker.service
# 查找啟動參數(shù)
cat $(systemctl status docker|grep Loaded|grep -Po '(?<=Loaded: loaded \()[^;]*')|grep dockerd
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
# 先備份docker.service
SERVICE_FILE=$(systemctl status docker|grep Loaded|grep -Po '(?<=Loaded: loaded \()[^;]*') \
&& sudo cp ${SERVICE_FILE} ${SERVICE_FILE}.bak
# 刪除dockerd的 -H參數(shù)
SERVICE_FILE=$(systemctl status docker|grep Loaded|grep -Po '(?<=Loaded: loaded \()[^;]*') \
&& sudo sed -i -e 's/ -H fd:\/\/ / /g' ${SERVICE_FILE}
# 再次查看驗證
cat $(systemctl status docker|grep Loaded|grep -Po '(?<=Loaded: loaded \()[^;]*')|grep dockerd
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
vi /etc/docker/daemon.json (如果文件不存在,直接創(chuàng)建)
在文件內(nèi)增加以下配置
"hosts":[
"fd://",
"tcp://0.0.0.0:2375"
]
我的配置后內(nèi)容如下:
{
"exec-opts": ["native.cgroupdriver=systemd"],
"hosts":[
"fd://",
"tcp://0.0.0.0:2375"
]
}
然后重啟docker
systemctl daemon-reload && systemctl restart docker && systemctl status docker
為驗證結果是否正確,我們可以在另外一起機器上進行執(zhí)行以下命令進行測試
# docker -H tcp://10.3.23.207:2375 version
Client: Docker Engine - Community
Version: 20.10.21
API version: 1.41
Go version: go1.18.7
Git commit: baeda1f
Built: Tue Oct 25 18:04:24 2022
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.9
API version: 1.41 (minimum version 1.12)
Go version: go1.16.8
Git commit: 79ea9d3
Built: Mon Oct 4 16:06:37 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.9
GitCommit: 1c90a442489720eec95342e1789ee8a5e1b9536f
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0
能正確顯示Server的版本,說明Slave的Docker遠程鏈接已打開
配置Master
登錄Jenkins
-
安裝Docker插件
進入 系統(tǒng)管理-系統(tǒng)配置-插件管理-可選插件 ,搜索“云提供商”,找到Docker插件,如下圖
image.png
點擊install without restart安裝插件 配置節(jié)點
進入 系統(tǒng)管理-系統(tǒng)配置-節(jié)點管理-可選插件



-
Docker Host URI為slave地址,2375是docker默認端口 - 點擊
Test Connection按鈕,測試能否聯(lián)通slave docker

-
Docker Image是指運行在slave上、作為agent的docker鏡像;這里選擇Jenkins官方的jenkins/agent:latest -
Remote File System Root是指Docker Image運行后,容器內(nèi)的系統(tǒng)路徑。注意:這是容器內(nèi)的路徑,并不是slave上的路徑;針對容器jenkins/agent:latest,這里要填寫/home/jenkins/agent,千萬不要填寫/home/jenkins,否則可能會在slave容器內(nèi)執(zhí)行shell命令時,報錯:process apparently never started in /home/jenkins/

-
Connect method:注意下,這里選擇Attach Docker container,這個跟上面的Docker Image有關系。

按以上步驟配置完即可。
測試
我們新建一個pipeline來測試這個docker agent是否可用

編寫pipeline
pipeline {
agent {
label 'docker-slave'
}
stages {
stage('Hello') {
steps {
echo 'Hello World'
sh 'pwd'
sh 'sleep 20'
echo 'Finish'
}
}
}
}
- 這里注意下, 要指定agent.label文件docker-slave,這個名字是上面配置master時的
Docker Agent templates一致 - 這里sleep了20s,就是為了到slave上看看任務是否啟動
構建之前,建議先去slave上把jenkins/agent:latest鏡像拉取下來
docker pull jenkins/agent:latest
開始構建后,先到slave上看看
[root@K8STest0001 ~]# docker ps | grep jenkins
7cc2da5531c2 jenkins/agent:latest "/bin/sh" 2 seconds ago Up 2 seconds blissful_euclid
可用看到,slave上已經(jīng)運行了 jenkins/agent
查看jenkins執(zhí)行日志:

從日志上看,說明此次執(zhí)行是在docker agent上執(zhí)行的!
