基于Jenkins的Master/Slave模式实现CI/CD

Jenkins在Kubernetes中动态创建代理

一、前言

就类似于我们公司 目前每天的jenkins构建测试基本上平稳在2300+左右,也就是可能同时并发的构建我见过一次120+,只是这一个jenkins节点是不可以完成这么大的任务量的!所以jenkins-slave的接入就很大程度上提高了性能!

mark
mark

Master/Slave相当于Server/agent。Master提供web接口让用户来管理job和slave,job可以运行在master本机或者被分配到slave上运行。一个master可以关联多个slave用来为不同的job或相同的job的不同配置来服务。

如何添加jenkins-slave节点?

“Manage Jenkins” ==> “Manage Nodes” ==> “New Node”

二、如何实现?

2.1、Kubernetes插件: Jenkins在Kubernetes集群中运行动态代理

插件介绍: https://github.com/jenkinsci/kubernetes-plugin

在jenkins的组件中搜索并安装:“kubernetes”

“Manage Jenkins” ==> “Configure System” ==> “Cloud” ==> “add kubernetes”

因为我们的jenkins已经在K8S集群中以pod的形式去运行,所以Kubernetes的地址就可以直接填写servicename:https://kubernetes.default

mark

当然如果jenkins服务是单独部署在K8S集群外部,我们就需要填写可以联调的地址、证书及证书;

2.2、自定义构建Jenkins Slave镜像

当然我虽然已经在K8S上部署了master节点,但是所以的编译都在slave节点运行的,我们需要考虑到: - 编译所涉及的开发语言(java,go,node,python等); - 额外底层环境(docker<推镜像>,helm<打包发布>)

参考: https://github.com/jenkinsci/docker-jnlp-slave

我这边以java语言为例:

FROM centos:7
LABEL maintainer zhdya
RUN yum install -y java-1.8.0-openjdk maven curl git libtool-ltdl-devel && \
yum clean all && \
rm -rf /var/cache/yum/* && \
mkdir -p /usr/share/jenkins
COPY slave.jar /usr/share/jenkins/slave.jar
COPY jenkins-slave /usr/bin/jenkins-slave
COPY settings.xml /etc/maven/settings.xml
RUN chmod +x /usr/bin/jenkins-slave
COPY helm kubectl /usr/bin/
ENTRYPOINT ["jenkins-slave"]
我突然想到一个事情,如上底层的事情已经考虑的差不多了,但是这个镜像如何能作为slave存在呢?

熟悉jenkins的应该不难回答,Jenkins_Master的所有交互都是与Slave的agent(slave.jar)通信,通过agent执行一系列的动作!

安装包下载地址:

链接:https://pan.baidu.com/s/1ktc8HzDvXaJeYf0xWBaI_A 
提取码:pxrc

[root@k8s-master1 ~]# unzip jenkins-slave.zip
Archive:  jenkins-slave.zip
   creating: jenkins-slave/
  inflating: jenkins-slave/jenkins-slave
  inflating: jenkins-slave/settings.xml
  inflating: jenkins-slave/slave.jar
  inflating: jenkins-slave/kubectl
  inflating: jenkins-slave/Dockerfile
  inflating: jenkins-slave/helm
  
helm和kubectl均是可执行文件,放到可执行目录下即可,kubectl需要考虑到鉴权!关于docker,只需要挂载数据卷即可!

# docker build -t jenkins-slave:jdk-1.8 .
# docker tag jenkins-slave:jdk-1.8 192.168.171.10/library/jenkins-slave:jdk-1.8
# docker push 192.168.171.10/library/jenkins-slave:jdk-1.8

然后我们配置下刚刚创建的任务:

参考:https://plugins.jenkins.io/kubernetes

pipeline {
    agent {
    kubernetes {
	  label 'jenkins-slave'
      yaml """
apiVersion: v1
kind: Pod
metadata:
  name: jenkins-slave
spec:
  containers:
  - name: jnlp
    image: 192.168.171.10/library/jenkins-slave:jdk-1.8
"""
    }
  }
   parameters {
  choice choices: ['192.168.171.10:9999/root/a.git', '192.168.171.10:9999/root/b.git', '192.168.171.10:9999/root/c.git'], description: '【请选择所需要发布项目的Git地址】', name: 'Git'
  choice choices: ['192.168.171.11', '192.168.171.12', '192.168.171.13'], description: '【请选择所需要发布项目的RS后端负载】', name: 'RS'
   }
   stages {
      stage('1、相关信息') {
         steps {
		 echo "Git分支是:${Git}"
		 echo "后端负载是:${RS}"
         }
         }
	  stage('2、编译') {
	     steps {
		echo "编译~"
	 }
	 }
	  stage('1、发布') {
	     steps {
		echo "发布~"
	 }
	 }
	}
}

查看是否创建了jenkins-slave节点:

[root@k8s-master1 jenkins-slave]# kubectl get po
NAME                                     READY   STATUS              RESTARTS   AGE
client1                                  1/1     Running             24         30d
jenkins-7c989dfd84-fgjbk                 1/1     Running             1          3d16h
jenkins-slave-swj7c-bqjd0                0/1     ContainerCreating   0          3s

注意观察你会发现,当我们启动一个slave的pod去执行这个job,一旦job完成,pod节点就会马上销毁!