Jenkis分布式预热
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"将任务分配到指定的节点上运行。
动态创建Docker slave
通常情况下Slave在完成分配的构建任务后处于空闲状态,在后台一直运行而不会自动销毁释放资源。在docker项目中,我们借助Docker plugin实现动态创建Docker slave,执行完构建任务后自行销毁。
准备
组件 | 功能 |
Docker plugin | jenkins插件 |
jenkins/ssh-slave | 提供ssh协议的基础镜像,配合Docker plugin使用 |
10.10.2.33 | 提供docker环境的宿主机,用于运行slave节点 |
正如文章开头部分"Jenkins分布式预热"中提到的,我们需要通过ssh协议使master和slave进行通信,因此使用 jenkins/ssh-slave提供ssh协议的基础镜像。而Docker plugin 会根据配置参数通过ssh协议创建一个jenkins slave的镜像,用来执行master分配的任务了。
Docker plugin具体处理流程如下:
具体实现
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/.ssh
root@4adf0e68a94b:~/.ssh# ls
id_rsa id_rsa.pub
root@4adf0e68a94b:~/.ssh# cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCdxQWjtd3uskQDB+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 AAAAB3NzaC1yc2EAAAADAQABAAABAQDCdxQWjtd3uskQDB+h1cJ+IHWuNi5xoAtWhrlIWOR37SgfbHyIFhOc+M1OxgBd+i/OWNPcQKsVTyijSMpTWjn6j0CAI4NG+k30TRZ3iocQ/1B0Ivemil3u2vxeXn0sP0hPjThQuNlOG/2tsCJxY82LskmxJ7xXA5lnmfqhvrWZW7Vn5WSbLinyEPxlkMkwOwlnjphtqQbCEYVqTs3CmFGF/TPLIZ9vTzyc6kDaeUmGXMTIbBdcb1kWQNvmdt+bnXiHMRmec5fMOwnxfgs+7MwwVbYpIhFdgJgkWhpUPrAmm6assLDTf8y0psOvXmn/UMvWrJkPTcJpD3259u+VlkK7 root@4adf0e68a94b"
jenkins配置
1.安装Docker plugin插件
2.配置插件
“Manage Jenkins”-“Configure System”-“Cloud”
3.配置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挂载,修改为我们项目中使用的工具;
测试
新建mvn项目配置
1.通过lable expression绑定至对应Lable 标签的jenkins docker slave 节点。
2.mvn 构建
3.构建过程
通过jenkins master/slave实现spring boot+docker的一个持续交付过程。
注意:由于spring boot 环境需要打包、构建、上传私有库,因此需要jenkins slave节点对宿主机的docker engine有操作权限,因此在docker 设置时通过"/var/run/docker.sock:/var/run/docker.sock"及容器属主的进行映射。
权限问题可参考:从socket权限问题重新认识docker架构
总结
虽然我们通过jenkins docker slave在一定程度上可以为master减负,在实际项目中可能出现slave的资源分配不均,是否支持负载均衡等问题,是我们在后续项目不断增多的情况下考虑提高交付效率可能需要考虑的。
参考:
Jenkins Distributed buildsDocker plugin