专栏首页云原生生态圈jenkins动态slave在k8s上的实践

jenkins动态slave在k8s上的实践

https://www.qikqiak.com/k8s-book/docs/36.Jenkins%20Slave.html 阳明老师的博客:www.qikqiak.com

Jenkins 安装完成了,接下来我们不用急着就去使用,我们要了解下在 Kubernetes 环境下面使用 Jenkins 有什么好处

我们知道持续构建与发布是我们日常工作中必不可少的一个步骤,目前大多公司都采用 Jenkins 集群来搭建符合需求的 CI/CD 流程,然而传统的 Jenkins Slave 一主多从方式会存在一些痛点,比如:

  • 主 Master 发生单点故障时,整个流程都不可用了
  • 每个 Slave 的配置环境不一样,来完成不同语言的编译打包等操作,但是这些差异化的配置导致管理起来非常不方便,维护起来也是比较费劲
  • 资源分配不均衡,有的 Slave 要运行的 job 出现排队等待,而有的 Slave 处于空闲状态
  • 资源有浪费,每台 Slave 可能是物理机或者虚拟机,当 Slave 处于空闲状态时,也不会完全释放掉资源。

正因为上面的这些种种痛点,我们渴望一种更高效更可靠的方式来完成这个 CI/CD 流程,而 Docker 虚拟化容器技术能很好的解决这个痛点,又特别是在 Kubernetes 集群环境下面能够更好来解决上面的问题,下图是基于 Kubernetes 搭建 Jenkins 集群的简单示意图:

从图上可以看到 Jenkins Master 和 Jenkins Slave 以 Pod 形式运行在 Kubernetes 集群的 Node 上,Master 运行在其中一个节点,并且将其配置数据存储到一个 Volume 上去,Slave 运行在各个节点上,并且它不是一直处于运行状态,它会按照需求动态的创建自动删除

这种方式的工作流程大致为:当 Jenkins Master 接受到 Build 请求时,会根据配置的 Label 动态创建一个运行在 Pod 中的 Jenkins Slave 并注册到 Master 上,当运行完 Job 后,这个 Slave 会被注销并且这个 Pod 也会自动删除,恢复到最初状态。

那么动态的创建Jenkins Slave这种方式带来了哪些好处呢?

  • 服务高可用,当 Jenkins Master 出现故障时,Kubernetes 会自动创建一个新的 Jenkins Master 容器,并且将 Volume 分配给新创建的容器,保证数据不丢失,从而达到集群服务高可用(这是k8s带来的资源控制器带来的优势)
  • 动态伸缩,合理使用资源,每次运行 Job 时,会自动创建一个 Jenkins Slave,Job 完成后,Slave 自动注销并删除容器,资源自动释放,而且 Kubernetes 会根据每个资源的使用情况,动态分配 Slave 到空闲的节点上创建,降低出现因某节点资源利用率高,还排队等待在该节点的情况。
  • 扩展性好,当 Kubernetes 集群的资源严重不足而导致 Job 排队等待时,可以很容易的添加一个 Kubernetes Node 到集群中,从而实现扩展。

是不是以前我们面临的种种问题在 Kubernetes 集群环境下面是不是都没有了啊?看上去非常完美。生活总是在慢慢的进步...

安装配置Jenkins slave

接下来我们就需要来配置 Jenkins,让他能够动态的生成 Slave 的 Pod。

第1步 安装kubernetes插件

我们需要安装kubernetes plugin, 点击 Manage Jenkins -> Manage Plugins -> Available -> Kubernetes plugin 勾选安装即可。如果你在Jenkins上下载插件慢或者安装不成功,那么我建议你到http://mirror.serverion.com/jenkins/plugins/去下载对应版本的插件,你可以参考我以前写的jenkins部署文章,下载插件

第2步 Jenkins上配置kubernetes Cloud

安装完毕后,点击 Manage Jenkins —> Configure System —> (拖到最下方)Add a new cloud —> 选择 Kubernetes,然后填写 Kubernetes 和 Jenkins 配置信息。

注意 namespace,我们这里填 kube-ops,然后点击Test Connection,如果出现 Connection test successful 的提示信息证明 Jenkins 已经可以和 Kubernetes 系统正常通信了,然后下方的 Jenkins URL 地址:http://jenkins2.kube-ops.svc.cluster.local:8080,这里的格式为:服务名.namespace.svc.cluster.local:8080根据上面创建的jenkins 的服务名填写,我这里是之前创建的名为jenkins,如果是用上面我们创建的就应该是jenkins2

另外需要注意,如果这里 Test Connection 失败的话,很有可能是权限问题,这里就需要把我们创建的 jenkins 的 serviceAccount 对应的 secret 添加到这里的 Credentials 里面。

第3步 配置Pod Template

配置 Pod Template,其实就是配置 Jenkins Slave 运行的 Pod 模板,命名空间我们同样是用 kube-ops,Labels 这里也非常重要,对于后面执行 Job 的时候需要用到该值,然后我们这里使用的是 cnych/jenkins:jnlp 这个镜像,这个镜像是在官方的 jnlp 镜像基础上定制的,加入了 kubectl 等一些实用的工具。

注意:由于新版本的 Kubernetes 插件变化较多,如果你使用的 Jenkins 版本在 2.176.x 版本以上,注意将上面的镜像替换成 cnych/jenkins:jnlp6,否则使用会报错,配置如下图所示:

另外需要注意我们这里需要在下面挂载两个主机目录,一个是 /var/run/docker.sock,该文件是用于 Pod 中的容器能够共享宿主机的 Docker,这就是大家说的 docker in docker 的方式,Docker 二进制文件我们已经打包到上面的镜像中了,另外一个目录下 /root/.kube目录,我们将这个目录挂载到容器的 /root/.kube目录下面这是为了让我们能够在 Pod 的容器中能够使用 kubectl 工具来访问我们的 Kubernetes 集群,方便我们后面在 Slave Pod 部署 Kubernetes 应用。

另外还有几个参数需要注意,如下图中的Time in minutes to retain slave when idle,这个参数表示的意思是当处于空闲状态的时候保留 Slave Pod 多长时间,这个参数最好我们保存默认就行了,如果你设置过大的话,Job 任务执行完成后,对应的 Slave Pod 就不会立即被销毁删除。

另外一些同学在配置了后运行 Slave Pod 的时候出现了权限问题,因为 Jenkins Slave Pod 中没有配置权限,所以需要配置上 ServiceAccount,在 Slave Pod 配置的地方点击下面的高级,添加上对应的 ServiceAccount 即可:

还有一些同学在配置完成后发现启动 Jenkins Slave Pod 的时候,出现 Slave Pod 连接不上,然后尝试100次连接之后销毁 Pod,然后会再创建一个 Slave Pod 继续尝试连接,无限循环,类似于下面的信息:

如果出现这种情况的话就需要将 Slave Pod 中的运行命令和参数两个值给清空掉

到这里我们的 Kubernetes Plugin 插件就算配置完成了。

测试

Kubernetes 插件的配置工作完成了,接下来我们就来添加一个 Job 任务,看是否能够在 Slave Pod 中执行,任务执行完成后看 Pod 是否会被销毁。

在 Jenkins 首页点击create new jobs,创建一个测试的任务,输入任务名称,然后我们选择 Freestyle project 类型的任务:

注意在下面的 Label Expression 这里要填入kubejnlp,就是前面我们配置的 Slave Pod 中的 Label,这两个地方必须保持一致

然后往下拉,在 Build 区域选择Execute shell

然后输入我们测试命令

echo "关注《云原生生态圈》,持久获取更多实战文章!"
echo "==============docker in docker==========="
docker info

echo "关注《云原生生态圈》,持久获取更多实战文章!"
kubectl get pods -o wide

现在我们直接在页面点击做成的 Build now 触发构建即可,然后观察 Kubernetes 集群中 Pod 的变化

$ kubectl get pods -n kube-ops
NAME                       READY     STATUS              RESTARTS   AGE
jenkins2-7c85b6f4bd-rfqgv   1/1       Running             3          1d
jnlp-266w0                 0/1       ContainerCreating   0          7s

我们可以看到在我们点击立刻构建的时候可以看到一个新的 Pod:jnlp-266w0 被创建了,这就是我们的 Jenkins Slave。任务执行完成后我们可以看到任务信息,比如我们这里是 花费了 21s 时间在 这个 Slave上面

同样也可以查看到对应的控制台信息:

到这里证明我们的任务已经构建完成,然后这个时候我们再去集群查看我们的 Pod 列表,发现 kube-ops 这个 namespace 下面已经没有之前的 Slave 这个 Pod 了。

$ kubectl get pods -n kube-ops
NAME                       READY     STATUS    RESTARTS   AGE
jenkins2-7c85b6f4bd-rfqgv   1/1       Running   3          1d

到这里我们就完成了使用 Kubernetes 动态生成 Jenkins Slave 的方法

本文分享自微信公众号 - 云原生生态圈(CloudNativeEcoSystem),作者:Marionxue

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • kubernetes炼气期之k8s平台快速搭建

    云原生生态圈
  • 自定义Build History中显示构建信息

    有时候会遇到一个代码仓库下面会有多个不同的分支,而这写分支表示着不同的开发者在开发新的需求,但是这样就会出现一个问题,在Jenkins上进行多分支构建的时候,很...

    云原生生态圈
  • 打造 Mac 下高颜值好用的终端环境

    最近有很多朋友看了我的文章之后,问我你终端是怎么设置的,为什么如此炫酷,这这这...让我怎么说,难道我的文章不干吗?还是特干看不下去了?好吧,今天趁着周末给大家...

    云原生生态圈
  • 爬取百度问答目的分析网页总结

    由于最近再开发问答系统,数据获取是一个问题,所以想通过爬虫爬取百度知道里面的问题和最优答案。

    DC童生
  • Python OpenGL基本配置

    pip install PyOpenGL PyOpenGL_accelerate

    py3study
  • 关于SourceForge不能使用的问题

    sourceforge SourceForge.net,又称SF.net,是开源软件开发者进行开发管理的集中式场所,也是全球最大开源软件开发平台和仓库。 Sou...

    cloudskyme
  • 开发工程师小明的一天

    描述了一个5年开发工程师的一天,他叫小明(配图与内容无关,仅供参考)。 7:30AM 小明是北漂一族,工作5年来京4年,买不起房,租住在离公司4,5站地的西四...

    春哥大魔王
  • 看!清华网红自行车成精了:拥有“类人脑芯片”,可无人驾驶!

    这款芯片既有人类大脑的思考能力,也有计算机的计算能力,这是全球人工智能领域重量级的一次全新突破。

    数据派THU
  • Scala学习笔记

    3、方法的声明格式 def(x:Int,y:Int) : Int ={} 最后一个冒号后面是返回类型,不加则没有返回值

    用户3003813
  • ROS文件系统(工程结构)

    介绍catkin的编译系统,catkin工作空间的创建和结构,package软件包的创建和结构,介绍CMakeLists.txt文件,package.xml以及...

    小飞侠xp

扫码关注云+社区

领取腾讯云代金券