使用Jenkins的Swarm插件动态扩展CI环境
作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/ 或 http://andyyoung01.16mb.com/
在将CI环境容器化以后,可以使整套环境更加容易从一个主机迁移到另一台主机上。然而随着项目的扩展,CI服务器的容量渐渐达到极限,所以可以动态增加CI服务器的容量是十分必要的。如果持续集成环境使用的是Jenkins的话,可以通过其Swarm插件来增加slave节点的数量。
对于中小型项目,使用一个Jenkins Server作为持续集成环境完全可以满足需要。只是随着项目的扩展,开发人员逐渐增多,Jenkins的工作负载逐渐增大,此台服务器的容量也渐渐达到极限。如下图所示:
一个很好的解决方案是,随着开发人员的加入,同时增加Jenkins slave节点的数量,每加入一个开发人员的同时,都增加一个worker node,如下图:
上面这种方式使用了Jenkins Swarm的插件,它允许安装了Jenkins Swarm Server插件的master可以连接到slave节点上,并且运行任务。下面来看一下整套环境的构建过程。
构建Jenkins Server
我们将使用Jenkins的官方镜像作为基础镜像,加入了一个Plugin ID为swarm的插件,赋予了运行该镜像后的容器可以访问其所在主机的Docker socker的能力。
使用命令docker build -t jenkins_server_swarm .
进行构建。
构建完成后得到了一个名为jenkins_server_swarm的镜像。该镜像中的jenkins用户由于加入了docker用户组,并且该用户组的docker组id与主机上的docker组ID相同,因此该镜像可以通过将主机上的docker.sock挂载进入容器中的docker.sock而具有访问权限,从而可以通过此容器化的Jenkins服务器构建Docker镜像。
注意:如果计划在Jenkins Docker容器内部运行docker的话,容器中的docker组id必须和容器所在主机的组id相同。如果这样做,这会带来潜在的迁移性的问题(因为各个不同主机上的docker组id也许会不同)。
另外一个解决方案:给jenkins用户分配免密码的sudo权限(通过echo “jenkins ALL=NOPASSWD: ALL” >> /etc/sudoers实现),然后容器中的所有命令前加sudo命令。这样便解决了镜像的移植性的问题。
使用如下命令运行容器:
上面代码需要注意的是,确保主机上的$HOME/jenkins目录可以由容器中的jenkins用户访问(jenkins用户的uid是1000)。如果在主机上用户的uid也是1000的话,这就没有问题。
访问http://host-ip:8080,第一次访问需要初始密码,按照页面的提示找到初始密码后登陆,进行一些初始配置。然后进入插件管理页面,可以看到Swarm插件已经安装:
{% asset_img 3.png “Jenkins Server with swarm plugin”%}
构建Jenkins Slave
下面的Dockerfile创建了一个安装了Jenkins Swarm client plugin的镜像:
上面代码的第11行下载了swarm-client的插件;第12行将一个启动脚本添加进镜像。
JENKINS/Swarm插件的官方地址:https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin
下面是启动脚本的代码:
脚本2-13行判断是否从Docker命令行设置了环境变量JENKINS_SERVER,JENKINS_USERNAME,JENKINS_PASSWORD的值,这三个变量分别指定Jenkins master服务器的IP地址,登陆Jenkins服务器的用户名及密码,如果没有设置程序立即退出;14-16行允许通过docker命令行设置另外的环境变量,如果命令行没有指定则使用默认值;18-21行显示一些debug的信息;22行是将执行的命令都显示出来;23行是使用swarm-client命令行工具连接到Jenkins master上;最后一行确保容器一直运行。
使用命令docker build -t jenkins_swarm_slave .
进行镜像构建。使用下面的命令启动容器:
现在你已经在这台机器上设置了Jenkins slave,可以在其上运行任务了。当设置Jenkins job时,可以指定lable为swarm,这会将任务的执行位置限制在有swarm的lable的节点上。当然可以设置不同的lable来进一步控制任务的执行位置。