Jenkins对接kubernetes实现slave动态创建

概述:

单个Jenkins很难满足生产环境中多个项目同时编译的需求,容易造成队列阻塞,所以这个时候需要通过Jenkins-slave的方式将编译分担到slave上,但传统的直接通过几台服务器专门做slave,浪费资源,还容易造成编译环境的不一致导致编译失败。后面有Jenkins有推出过基于docker的Jenkins-slave,虽然可以解决上述问题,但所以在这里我们可以充分利用kubernetes的功能,将Jenkins-slave以pod的方式运行在kubernetes集群内,将任务分发给这些Jenkins-slave pod,然后执行任务,任务执行完以后,在自动释放掉这些pod,能够很好的利用资源。

版本:
os:ubuntu16.04
kubernetes:1.10.5
Jenkins:2.89.4 (通过deb包方式安装)

配置方法

Jenkins安装kubernetes插件
系统管理—>管理插件—>搜索Kubernetes plugin安装


配置
系统管理—>系统设置—>新增一个云

配置Jenkins URL,这里我们没有配置api-server地址和证书key,连接kubernetes,所以默认会去读取放在JENKINS_HOME的.kube/目录的kubeconfig文件,用于连接集群。我这里是通过安装包的方式安装的Jenkins HOME在/var/lib/jenkins/目录,如果是通过容器方式启动,将kubeconfig文件直接放~/.kube/目录。


配置pod template

名字可以随便写,注意这个namespace和labels,需要规划好namespace默认不写就是default labels是用于后面编译的项目调用这个kubernetes pod template时用的。

配置container template

注意这个pod的名字叫jnlp,用来覆盖默认容器,如果改成其他名字的话,那这个pod会启动两个container,都去连接master
配置Arguments to pass to the command的用处是定义多个Jenkins-agent container时通过${computer.jnlpmac} ${computer.name},做为jnlp的启动参数,用来区分不同container。
配置cpu、memory资源request,因为可使用资源太低的节点上运行jnlp容易出错。

保存配置
打开Jenkins-slave连接master的端口,这里定义为50000
系统管理—>全局安全配置—>agents

验证
创建个freestyle

特别需要注意这个label Expression,要根我们刚刚定义的kubernetes-template配置的一样,这样做的意义是什么,因为在实际使用环境中,不同的项目由不同的开发语言构成,也需要不同的编译环境,所以会配置多种语言环境的jnlp镜像,通过label去调用合适的kubernetes-template

这里我们配置一个最简单的shell,输出一串字符。
点击立刻构建
在kubernetes集群内就看见这个jnlp-slave已经被创建出来了。

查看本次编译结果,编译成功

pipline用法

1
2
3
4
5
6
7
podTemplate(label: 'jnlp-slave', cloud: 'kubernetes') {
node('jnlp-slave') {
stage('Run shell') {
sh 'echo hello world'
}
}
}

总结:
通过jenkins-kubernetes-plugin能实现对Jenkins slave的弹性部署和回收,能非常有效的利用资源,在实际使用的过程中,我们会根据不同的编程去构建一个对应的jnlp,或在一个jnlp镜像内包含全部编程语言。

参考链接
https://github.com/jenkinsci/docker-jnlp-slave
https://github.com/jenkinsci/kubernetes-plugin/blob/master/README.md