当前位置: 首页 > article >正文

k8s jenkins 2.421动态创建slave

k8s jenkins 动态创建slave

  • 简述
    • 使用jenkins动态slave的优势:
    • 制作jenkins-slave从节点jenkins-slave-latest:v1
    • 配置jenkins动态slave
      • 配置 Pod Template
      • 配置容器模板
      • 挂载卷
    • 测试

简述

持续构建与发布是我们日常工作中必不可少的一个步骤,目前大多公司都采用 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 分配给新创建的容器,保证数据不丢失,从而达到集群服务高可用。
  • 动态伸缩,合理使用资源,每次运行 Job 时,会自动创建一个 Jenkins Slave,Job 完成后,Slave 自动注销并删除容器,资源自动释放,而且 Kubernetes 会根据每个资源的使用情况,动态分配 Slave 到空闲的节点上创建,降低出现因某节点资源利用率高,还排队等待在该节点的情况。
  • 扩展性好,当 Kubernetes 集群的资源严重不足而导致 Job 排队等待时,可以很容易的添加一个 Kubernetes Node 到集群中,从而实现扩展。

制作jenkins-slave从节点jenkins-slave-latest:v1

jenkins/jenkins:2.421是安装jenkins pod的
jenkins-slave 是从节点pod。在大型或复杂的 Jenkins 系统中,jenkins主服务器通常不执行构建工作,而是把构建任务分发给从服务器来执行。
备注:jenkins-slave-latest.tar.gz这个里面封装的镜像是jenkins-slave-latest:v1,这个jenkins-slave-latest:v1镜像制作方法如下:

cd /root/slave
docker pull jenkins/jnlp-slave:latest
cat dockerfile
FROM jenkins/jnlp-slave:latest
USER root
# 安装Docker
RUN apt-get update && apt-get install -y \
    docker.io
# 将当前用户加入docker用户组
RUN usermod -aG docker jenkins
RUN curl -LO https://dl.k8s.io/release/stable.txt
RUN curl -LO https://dl.k8s.io/release/$(cat stable.txt)/bin/linux/amd64/kubectl
RUN chmod +x kubectl
RUN mv kubectl /usr/local/bin/
ENV DOCKER_HOST unix:///var/run/docker.sock
docker build -t=jenkins-slave-latest:v1 .
docker save -o jenkins-slave-latest.tar.gz  jenkins-slave-latest:v1

复制jenkins-slave-latest.tar.gz至k8snode1

docker load -i jenkins-slave-latest.tar.gz
ctr -n=k8s.io images import jenkins-slave-latest.tar.gz

配置jenkins动态slave

填写 Kubernetes 和 Jenkins 配置信息。
在这里插入图片描述

kubernetes
https://192.168.40.120:6443
namespace:jenkins-k8s
Jenkins 地址: http://jenkins-service.jenkins-k8s.svc.cluster.local:8080

在这里插入图片描述
在这里插入图片描述

配置 Pod Template

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

名称:slave
命名空间:jenkins-k8s
标签列表:test1

在这里插入图片描述

配置容器模板

容器模板
名称:jnlp
容器镜像:cnych/jenkins:jnlp6

在这里插入图片描述

挂载卷

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

在这里插入图片描述

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

在这里插入图片描述

Jenkins Slave Pod 中没有配置权限,所以需要配置上 ServiceAccount,在 Slave Pod 配置的地方点击下面的高级,添加上对应的 ServiceAccount 即可:
这个sa就是我们最开始安装jenkins时的sa

jenkins-k8s-sa

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

测试

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

echo "测试 Kubernetes 动态生成 jenkins slave"
echo "==============docker in docker==========="
docker info

echo "=============kubectl============="
kubectl get pods

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


http://www.kler.cn/a/354998.html

相关文章:

  • 小白考研历程:跌跌撞撞,起起伏伏,五个月备战历程!!!
  • Java字符串的|分隔符转List实现方案
  • leetcode之hot100---240搜索二维矩阵II(C++)
  • 【Qt】显示类控件:QLabel、QLCDNumber、QProgressBar、QCalendarWidget
  • 项目中如何排查JVM问题?
  • Obfuscator使用心得
  • linux 内核如何读取你配置好的.config文件
  • 【CentOS】Shell脚本案例:归档文件
  • C++从入门到起飞之——红黑树 全方位剖析!
  • 【Flutter 面试题】 Flutter如何使用路由、全局错误捕获和自定义组件统一管理错误页面?
  • SpringBoot3响应式编程全套-R2DBC
  • 模板方法设计模式
  • hdfs API操作 hadoop3.3.5
  • java项目技术架构图-样例
  • mysql--表的约束
  • 【Ubuntu】虚拟机共享文件夹启用
  • NFTScan | 10.07~10.13 NFT 市场热点汇总
  • vmware ubuntu根分区扩容
  • 纯前端如何实现批量下载功能呢?
  • ChatGPT免费使用:人工智能在现代社会中的作用
  • Day31 || 122.买卖股票的最佳时机 II、55. 跳跃游戏、 45.跳跃游戏II 、1005.K次取反后最大化的数组和
  • LangGraph - Hierarchical Agent Teams
  • 京东背调有病吧......
  • 开源节流-2024年10月17日
  • 【秋招笔试】10.13拼多多(已改编)秋招-三语言题解
  • LLM大模型的评测维度有哪些?