基于K8s的动态Jenkins Slave构建实践

前言

源于这篇文章分享的经验 基于 Kubernetes 的 Jenkins 构建集群实践,这里记录一下实践落地过程。

环境

这里Jenkins Master的安装没有采用容器镜像的方式,直接就是rpm包安装。
版本信息:
Jenkins 2.107.1
Kubernetes plugin 1.4
kubernetes集群 1.5.2

这里就不详细说明安装过程了。

配置

环境都安装好后,配置Jenkins,进入系统管理—>系统设置—>云
新增一个云Kubernetes,配置如下:
cloud
配置比较简单,这里也没有采用自定义的slave模板,默认Jenkins使用的是jenkins/jnlp-slave:alpine镜像作为动态的运行的slave。
其中Kubernetes URL也可以通过命令查看:
# kubectl cluster-info
Kubernetes master 所在的地址即可,比如:

Kubernetes master is running at https://10.1.241.82:8080/r/projects/1a7/kubernetes:6443

这里的URL就填 https://10.1.241.82:8080/r/projects/1a7/kubernetes:6443

测试

这里测试全部使用pipeline进行构建。
新建一个Pipeline流水线项目,配置Pipeline运行脚本:
pipeline-test
脚本内容:

podTemplate(label: 'mypod', cloud: 'kubernetes')
{
    node ('mypod') {
        stage('test') {
            echo "hello, world"
            sleep 60
        }
    }
}

label:Jenkins执行的节点标签,可以随意起;
cloud:就是我们上面配置云的名字标识;
node:执行构建任务的slave节点,需要跟上面的label一致

非常简单的一个测试用例,让我们来跑一下看看。
首先看一下构建执行状态:
slave-build
可以看到Jenkins自动创建了一个Slave节点在执行我们的构建任务,
我们再通过k8s看下执行的pod情况:

# kubectl get pod
NAME                        READY     STATUS    RESTARTS   AGE
jenkins-slave-5d8m2-jzxk7   1/1       Running   0          38s

# kubectl describe pod jenkins-slave-5d8m2-jzxk7
。。。
Events:
  FirstSeen     LastSeen        Count   From                    SubObjectPath           Type            Reason          Message
  ---------     --------        -----   ----                    -------------           --------        ------          -------
  46s           46s             1       {default-scheduler }                            Normal          Scheduled       Successfully assigned jenkins-slave-5d8m2-jzxk7 to master
  44s           44s             1       {kubelet master}        spec.containers{jnlp}   Normal          Pulled          Container image "jenkins/jnlp-slave:alpine" already present on machine
  44s           44s             1       {kubelet master}        spec.containers{jnlp}   Normal          Created         Created container with docker id 7cbdbd4ea859; Security:[seccomp=unconfined]
  44s           44s             1       {kubelet master}        spec.containers{jnlp}   Normal          Started         Started container with docker id 7cbdbd4ea859

通过上面的k8s的pod信息我们可以看到,pod名字就是Jenkins slave节点的名字。通过READY字段,我们也能发现pod中只有一个容器在跑,最后看下详细信息,发现k8s确实是去拉取jenkins/jnlp-slave:alpine 镜像了。

这里再贴一下Jenkins的控制台打印信息:
console

项目实践

真正的项目中实践肯定不是这么简单的,我们这里就以一个简单maven构建项目为例。
步骤如下:

  • 制作maven镜像,设置maven仓库私服mirror,添加ssh-key方便无密码拉取仓库代码
  • 编写Jenkinsfile,配置构建流程
  • 执行构建

制作maven镜像

FROM maven:latest

ADD settings.xml /root/.m2/

RUN mkdir /root/.ssh/

ADD .ssh /root/.ssh/

RUN chmod 600 /root/.ssh/id_rsa

其中settings.xml包含了maven仓库私服mirror、sonarqube等等一些maven相关的配置,
这里需要注意的是ssh的私钥权限必须是600的,这个是配置无密码从gitlab仓库拉取源码的。
通过Dockerfile来制作我们自己的maven镜像:
docker build . -t e5:8889/maven:1.0

上传到我们私服仓库:
docker push e5:8889/maven:1.0

编写Jenkinsfile

Jenkinsfile是jenkins pipeline构建的一种脚本,其中定义了构建流程。

podTemplate(label: 'mypod', cloud: 'kubernetes', containers: [
   containerTemplate(
         name: 'maven',
         image: 'e5:8889/maven:1.0',
         ttyEnabled: true,
         command: 'cat'
     )
])
{
    node ('mypod') {
     container('maven') {
         git url: '[email protected]:maven/springboot-archetype.git', 
                credentialsId: '6033483b-5125-4ce1-941d-83b23ae64ba6'

         stage('create-archetype') {

            sh 'mvn archetype:create-from-project'

        }

        stage('update-local-catalog') {
            sh 'cd target/generated-sources/archetype'
            sh 'mvn clean install'
            sh 'mvn archetype:update-local-catalog'
        }

        stage('deploy') {
            sh 'mvn deploy'
        }

        stage('build-tag') {
            build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
            echo build_tag
        }

     }
 }
}

我们通过containers.containerTemplate指定了我们代码是在哪个容器内进行构建的,其他的就都是一些简单的构建流程,这里就不细说了。

执行构建

我们最后再执行一次构建,看下Jenkins和k8s一些运行情况。
Jenkins Console控制台打印:
git-jenkins

K8s的pod信息:

# kubectl get pod
NAME                        READY     STATUS    RESTARTS   AGE
jenkins-slave-wm980-2v01l   2/2       Running   0          5s

通过READY字段,发现这时pod运行的就有2个容器了,我们可以猜测一个是slave容器,一个是我们自定义的maven容器。
再来看下pod创建的详细信息:

# kubectl describe pod jenkins-slave-wm980-2v01l
Events:
  FirstSeen     LastSeen        Count   From                    SubObjectPath           Type            Reason          Message
  ---------     --------        -----   ----                    -------------           --------        ------          -------
  17s           17s             1       {default-scheduler }                            Normal          Scheduled       Successfully assigned jenkins-slave-wm980-2v01l to master
  15s           15s             1       {kubelet master}        spec.containers{maven}  Normal          Pulled          Container image "e5:8889/maven:1.0" already present on machine
  15s           15s             1       {kubelet master}        spec.containers{maven}  Normal          Created         Created container with docker id 85c8547aa047; Security:[seccomp=unconfined]
  15s           15s             1       {kubelet master}        spec.containers{maven}  Normal          Started         Started container with docker id 85c8547aa047
  15s           15s             1       {kubelet master}        spec.containers{jnlp}   Normal          Pulled          Container image "jenkins/jnlp-slave:alpine" already present on machine
  15s           15s             1       {kubelet master}        spec.containers{jnlp}   Normal          Created         Created container with docker id c10cc2694b05; Security:[seccomp=unconfined]
  14s           14s             1       {kubelet master}        spec.containers{jnlp}   Normal          Started         Started container with docker id c10cc2694b05

通过这行信息:"e5:8889/maven:1.0" already present on machine
我们发现果然有使用到自己的maven镜像了。

结语

其实真正实践起来还是会发现很多坑的,之前网上搜到很多教程都还需要自定义slave镜像亦或者将Jenkins Master节点也作为容器放入k8s中,但是感觉一来麻烦,二来也没太大必要就没弄了。其实后面更关键是在应用的部署上面,这里只是将构建工具链都准备好,提供一个应用干净的构建环境。

写完之后还发现有许多可以优化的地方,比如maven本地缓存仓库的挂载等等。。

Kubernetes plugin的文档:https://jenkins.io/doc/pipeline/steps/kubernetes/
https://github.com/jenkinsci/kubernetes-plugin/blob/master/README.md

猜你喜欢

转载自blog.csdn.net/lusyoe/article/details/79684318
今日推荐