Docker動態構建Jenkins Slave,構建完任務自動銷燬


Docker動態構建Jenkins Slave,構建完任務自動銷燬

簡介

在CI/CD工作中我們主要使用單節點Jenkins(Master)來完成構建任務,隨著項目不斷增多,單節點無論在效率及穩定性上已經不滿足我們的需求,而Jenkins天然支持Master-Slave架構,因此我們可以通過部署Slave節點的方式來給Master減負。但是Slave節點只有在分配了任務時才執行構建,在完成分配的構建任務後處於空閒狀態,在後臺一直運行而不會自動銷燬釋放資源

那有什麼方案可以避免這種情況呢?

我們藉助Jenkins插件Docker plugin可以實現動態創建Jenkins Slave,執行完構建任務後自行銷燬

在正式講解Docker動態創建Jenkins Slave前,我們先進行下Jenkins分佈式,以便我們更能深刻的瞭解整個的實現過程。

Jenkins分佈式預熱

Jenkins是Master-Slave架構,Master節點提供Web GUI 和API來管理、分配、運行構建任務;Slave節點只是用來運行Master節點分配的構建任務;因此Slave可以有效減輕Master的工作負載,這也意味著Slave節點可以分佈在不同平臺並且無需安裝jenkins的完整包。

Master和Slave通信方式:

  • Master->Slave,最常用的方式,在網絡聯通情況下,Master通過ssh主動與agent進行通信
  • Slave->Master,在Slave不可訪問的情況下,通過Java Web Start(JNLP)由Slave訪問Master

Jenkins Master節點將基於以上兩種方式,自動完成剩下的自動部署工作,如複製Slave所需的二進制文件以及啟動/停止Slave等操作。

當然Jenkins還提供更靈活的部署方式,即基於ssh通過腳本來登錄Slave節點。過程如下:

  • 通過"http://yourserver:port/jnlpJars/agent.jar"下載Slave節點所需的最小運行包;
  • 通過“java -jar agent.jar”啟動Slave節點並配合腳本管理;

當Slave建立好後,只需在Master上根據"node label"將任務分配到指定的節點上運行

通過Jenkins分佈式預熱,我們大體上了解了其的工作方式。而以下正式內容,我們將使用

基於ssh通過腳本來登錄Slave節點的方式並啟動。

Docker plugin動態創建Jenkins Slave

一、準備

Docker plugin,Jenkins插件

jenkins/ssh-slave,提供ssh協議的Docker基礎鏡像,配合Docker plugin使用

10.10.2.33,提供docker環境的宿主機,用於運行slave節點

"Jenkins分佈式預熱"中提到的,我們需要通過ssh協議使master和slave進行通信,因此使用 jenkins/ssh-slave提供ssh協議的Docker基礎鏡像。而Docker plugin 會根據配置參數通過ssh協議創建一個jenkins slave的鏡像,用來執行master分配的任務了

Docker plugin具體處理流程如下:


Docker動態構建Jenkins Slave,構建完任務自動銷燬

從處理流程上看,Jenkins master是通過Docker plugin作為一個Docker client,調用遠程運行Slave節點的宿主機的Docker API,來拉取jenkins/ssh-slave鏡像構建容器後觸發的一系列動作。

在此我們需要要熟練掌握Docker的架構,如果你不瞭解可以參考下文:

從socket權限問題重新認識docker架構

二、具體實現

1.Slave節點宿主機配置

<code>#在宿主機上安裝docker環境,在此不做介紹
#拉取提供ssh協議的基礎鏡像
docker pull jenkins/ssh-slave
#進入鏡像生成ssh 秘鑰
docker run -it jenkins/ssh-slave /bin/bash 
#生成秘鑰
ssh-keygen
#開放22端口,提供訪問docker plugin訪問
root@4adf0e68a94b:/home/jenkins# cd /root/.ssh
root@4adf0e68a94b:~/.ssh# ls
id_rsa  id_rsa.pub
root@4adf0e68a94b:~/.ssh# cat id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCdxQWjtdxsekQDB+h1cJ+IHWuNi5xoAtWhrlIWOR37SgfbHyIFhOc+M1OxgBd+i/OWNPcQKsVTyijSMpTWjn6j0CAI4NG+k30TRZ3iocQ/1B0Ivemil3u2vxeXn0sP0hPjThQuNlOG/2tsCJxY82LskmxJ7xXA5lnmfqhvrWZW7Vn5WSbLinyEPxlkMkwOwlnjphtqQbCEYVqTs3CmFGF/TPLIZ9vTzyc6kDaeUmGXMTIbBdcb1kWQNvmdt+bnXiHMRmec5fMOwnxfgs+7MwwVbYpIhFdgJgkWhpUPrAmm6assLDTf8y0psOvXmn/UMvWrJkPTcJpD3259u+VlkK7 root@4adf0e68a94b
#啟動鏡像
#啟動格式如下:
#docker run jenkins/ssh-slave ""
docker run -d -p 22:22 --name jenkins-slave jenkins/ssh-slave "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCdxQWjtd3xsekQDB+h1cJ+IHWuNi5xoAtWhrlIWOR37SgfbHyIFhOc+M1OxgBd+i/OWNPcQKsVTyijSMpTWjn6j0CAI4NG+k30TRZ3iocQ/1B0Ivemil3u2vxeXn0sP0hPjThQuNlOG/2tsCJxY82LskmxJ7xXA5lnmfqhvrWZW7Vn5WSbLinyEPxlkMkwOwlnjphtqQbCEYVqTs3CmFGF/TPLIZ9vTzyc6kDaeUmGXMTIbBdcb1kWQNvmdt+bnXiHMRmec5fMOwnxfgs+7MwwVbYpIhFdgJgkWhpUPrAmm6assLDTf8y0psOvXmn/UMvWrJkPTcJpD3259u+VlkK7 root@4adf0e68a94b"/<code>

此步主要是為Slave節點準備ssh環境,以便Master能通過ssh登陸到Slave節點進行部署。

注意:Slave節點宿主機要開啟遠程TCP訪問,以便Master節點的Docker plugin能夠遠程訪問。

<code>#啟動方式添加tcp socket
dockerd -H tcp://0.0.0.0:2375/<code>

2.Jenkins Master配置

  1. 安裝Docker plugin插件
  2. 配置插件

新增Cloud,設置Manage Jenkins”-“Configure System”-“Cloud”

Docker動態構建Jenkins Slave,構建完任務自動銷燬

  1. 配置docker cloud

"Docker Host URI" 是slave宿主機的tcp socket,master的docker plugin通過這個tcp連接對宿主的 docker環境進行操作。

Docker動態構建Jenkins Slave,構建完任務自動銷燬

  1. Docker Agent template配置
Docker動態構建Jenkins Slave,構建完任務自動銷燬

其中:

Lables 是master綁定某個slave的標籤;
Name 是新建容器的名稱;
Docker Image是容器運行的鏡像;
Volumes 是外部掛載,默認情況下都是使用容器內部提供的工具,我們需要根據實際情況使用掛載外部資源;

Docker動態構建Jenkins Slave,構建完任務自動銷燬

其中:

/home/jenkins是jenkins slave的運行目錄,我們通過Volumes已經掛載外部資源;
JavaPath是容器內自帶的java,我們可以通過下面步驟進行修改為項目中使用的工具;


Docker動態構建Jenkins Slave,構建完任務自動銷燬

其中:

Docker Agent tempaltes的環境變量用於定義ssh登錄的秘鑰;
Tool Locations 是根據Volumes掛載,修改為我們項目中使用的工具;

三、測試

1.新建mvn項目配置

  1. 通過lable expression綁定至對應Lable 標籤的jenkins docker slave 節點。
Docker動態構建Jenkins Slave,構建完任務自動銷燬

  1. maven 構建
Docker動態構建Jenkins Slave,構建完任務自動銷燬

通過maven自動構建鏡像、Tag、push的到遠程倉庫。

關於maven自動部署Spring Boot項目可以參考你想要的Docker自動部署Spring Boot就在這

  1. 構建過程
Docker動態構建Jenkins Slave,構建完任務自動銷燬


注意:由於spring boot 環境需要打包、構建、上傳私有庫,因此需要Jenkins Slave節點對宿主機的docker engine有操作權限,因此在docker 設置時通過"/var/run/docker.sock:/var/run/docker.sock"及容器屬主的進行映射。

總結

通過以上步驟完成了Jenkins Slave的動態構建並實現Spring Boot+Docker的一個持續交付過程。其中涉及的細節性知識點還需要我們在實踐中不斷去總結。

思考:

雖然我們通過Jenkins Slave在一定程度上可以為master減負,在實際項目中可能出現slave的資源分配不均,是否支持負載均衡等問題,是我們在後續項目不斷增多的情況下考慮提高交付效率需要考慮的。


分享到:


相關文章: