侧边栏壁纸
  • 累计撰写 208 篇文章
  • 累计创建 16 个标签
  • 累计收到 5 条评论

目 录CONTENT

文章目录

在Kubernetes环境下配置Jenkins的Slave pod

Wake
2024-03-28 / 0 评论 / 1 点赞 / 1,512 阅读 / 1,588 字

前言:

Jenkins已经安装在EKS上,先了解下在 Kubernetes 环境下面使用 Jenkins 有什么好处。
我们知道持续构建与发布是我们日常工作中必不可少的一个步骤,目前大多公司都采用 Jenkins 集群来搭建符合需求的 CI/CD 流程,然而传统的 Jenkins Slave 一主多从方式会存在一些痛点,比如:

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

正因为上面的这些种种痛点,我们渴望一种更高效更可靠的方式来完成这个 CI/CD 流程,而 Docker 虚拟化容器技术能很好的解决这个痛点,又特别是在 Kubernetes 集群环境下面能够更好来解决上面的问题,下图是基于 Kubernetes 搭建 Jenkins 集群的简单示意图:
image-1711621498515
从图上可以看到 Jenkins Master 和 Jenkins Slave 以 Pod 形式运行在 Kubernetes 集群的 Node 上,Master 运行在其中一个节点,并且将其配置数据存储到一个 Volume 上去,Slave 运行在各个节点上,并且它不是一直处于运行状态,它会按照需求动态的创建并自动删除。

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

那么我们使用这种方式带来了哪些好处呢?

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

配置

接下来就需要来配置 Jenkins,让他能够动态的生成 Slave 的 Pod。
这里用的Jenkins 版本是 2.440.2
第 1 步. 我们需要安装Kubernetes plugin 插件, 点击 Manage Jenkins -> Manage Plugins -> Available -> Kubernetes plugin 勾选安装即可。
image-1711621785715
第 2 步. 安装完毕后,点击 Manage Jenkins —> Clouds —> (拖到最下方)Add a new cloud —> 选择 Kubernetes,然后填写 Kubernetes 和 Jenkins 配置信息。
image-1711621891672
image-1711622327826
注意 namespace,我们这里填 devops,然后 点击Test Connection,如果出现 Connection test successful 的提示信息证明 Jenkins 已经可以和 Kubernetes 系统正常通信了,然后下方的 Jenkins URL 地址:http://jenkins.devops:8080,这里的格式为:服务名.namespace.svc.cluster.local:8080

注意:
另外需要注意,如果这里 Test Connection 失败的话,很有可能是权限问题,这里就需要把我们创建的 jenkins 的 serviceAccount 对应的 secret 添加到这里的 Credentials 里面。但是如果按照我的部署文档部署Jenkins则不会出现这个问题。Jenkins 在K8S集群的部署

image-1711622118572

第 3 步. 配置 Pod Template,其实就是配置 Jenkins Slave 运行的 Pod 模板,命名空间我们同样是 用 devops,Labels 这里也非常重要,对于后面执行 Job 的时候 需要用到该值,然后我们这里使用的是jenkins/inbound-agent 这个镜像
image-1711629103611
image-1711629129628
image-1711629251241
image-1711629305075
注意:
如果使用jenkins/jnlp-slave:4.13.3-1-jdk11这个镜像,可能因为官方太久没有维护了。如果不手动使用命令启动jenkins-agent,则jenkins-agent服务是不会自己启动的,pod会一直拉不起来,一直重复销毁拉起。所以直接使用jenkins/inbound-agent这个镜像就可以了

第4步.验证。
在 Jenkins 首页点击 new item,创建一个测试的任务 wake-jenkins_slave-demo,然后我们选择 Freestyle project 类型
注意在下面的 Label Expression 这里要填入wake-jnlp,就是前面我们配置的 Slave Pod 中的 Label,这两个地方必须保持一致
image-1711627030912
然后往下拉,在Build 区域选择Execute shell,并添加我们的测试命令

echo "测试 Kubernetes 动态生成 jenkins slave"
echo "==============docker in docker==========="
java -version

image-1711627143811
保存退出并点击Build Now,然后观察 Kubernetes 集群中 Pod 的变化
image-1711627478518
image-1711628870436
现在slave pod正在执行,点击查看执行日志
image-1711629925394

通过pipeline部署动态slave

2.编写pipeline
主要是格式,具体salve 镜像需要怎么配置可以通过yaml内容去调整

pipeline{
    agent{
        kubernetes{
            label "test01"   
            cloud '*******'  #这里填jenkins上定义的k8s集群名称
            yaml '''
---
kind: Pod
apiVersion: v1
metadata:
  labels:
    k8s-app: jenkinsagent
  name: jenkinsagent
  namespace: devops
spec:
containers:
  - name: jenkinsagent
    image: jenkins/inbound-agent
    imagePullPolicy: IfNotPresent
    resources:
      limits:
        cpu: 1000m
        memory: 2Gi
      requests:
        cpu: 500m
        memory: 512Mi
'''
        }
    }

    stages{
        stage("test"){
          steps{
            script{
              sh "java -version & sleep 30"
            }
          }
        }
    }
}

验证
image-1711627713449
image-1711630108412
image-1711627850108
因为有sleep 30s 的缘故,所以部署时间是在30多秒完成的。
slave pod的两种使用方法就都完成测试使用了,后面会带给一些项目的实战案例。

1

评论区