查看原文
其他

Docker动态构建Jenkins Slave

木讷大叔爱运维 木讷大叔爱运维 2022-07-13


简介

在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具体处理流程如下:

从处理流程上看,Jenkins master是通过Docker plugin作为一个Docker client,调用远程运行Slave节点的宿主机的Docker API,来拉取jenkins/ssh-slave镜像构建容器后触发的一系列动作。

在此我们需要要熟练掌握Docker的架构,如果你不了解可以参考下文:

从socket权限问题重新认识docker架构

二、具体实现

1.Slave节点宿主机配置

#在宿主机上安装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/.sshroot@4adf0e68a94b:~/.ssh# lsid_rsa id_rsa.pubroot@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 "<public key>"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

此步主要是为Slave节点准备ssh环境,以便Master能通过ssh登陆到Slave节点进行部署。

注意:Slave节点宿主机要开启远程TCP访问,以便Master节点的Docker plugin能够远程访问。

#启动方式添加tcp socketdockerd -H tcp://0.0.0.0:2375

2.Jenkins Master配置

  1. 安装Docker plugin插件

  2. 配置插件

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

  1. 配置docker cloud

"Docker Host URI" 是slave宿主机的tcp socket,master的docker plugin通过这个tcp连接对宿主的 docker环境进行操作。

4.Docker Agent template配置

其中:

Lables 是master绑定某个slave的标签;
Name 是新建容器的名称;
Docker Image是容器运行的镜像;
Volumes 是外部挂载,默认情况下都是使用容器内部提供的工具,我们需要根据实际情况使用挂载外部资源;

其中:

/home/jenkins是jenkins slave的运行目录,我们通过Volumes已经挂载外部资源;
JavaPath是容器内自带的java,我们可以通过下面步骤进行修改为项目中使用的工具;

其中:

Docker Agent tempaltes的环境变量用于定义ssh登录的秘钥;
Tool Locations 是根据Volumes挂载,修改为我们项目中使用的工具;

三、测试

1.新建mvn项目配置

  1. 通过lable expression绑定至对应Lable 标签的jenkins docker slave 节点。

2.maven 构建


通过maven自动构建镜像、Tag、push的到远程仓库。

关于maven自动部署Spring Boot项目可以参考你想要的Docker自动部署Spring Boot就在这

  1. 构建过程

注意:由于spring boot 环境需要打包、构建、上传私有库,因此需要Jenkins Slave节点对宿主机的docker engine有操作权限,因此在docker 设置时通过"/var/run/docker.sock:/var/run/docker.sock"及容器属主的进行映射。

总结

通过以上步骤完成了Jenkins Slave的动态构建并实现Spring Boot+Docker的一个持续交付过程。其中涉及的细节性知识点还需要我们实践中不断去总结。

思考:

虽然我们通过Jenkins Slave在一定程度上可以为master减负,在实际项目中可能出现slave的资源分配不均,是否支持负载均衡等问题,是我们在后续项目不断增多的情况下考虑提高交付效率需要考虑的。








您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存