使用jenkins构建docker镜像

4,392 阅读2分钟

前言

之前使用jenkins-operator在kubernetes环境中搭建出来了jenkins,在整个CI/CD的流程中需要构建、推送镜像,这就需要在容器中使用docker。通过google看到了docker in docker这种解决方案。容器不用运行自己的Docker daemon而是连接宿主机的Docker daemon,这样在容器中只需要Docker CLI。

docker run -ti -v /var/run/docker.sock:/var/run/docker.sock docker

通过上面的命令,就可以在容器中使用docker。要注意的是至始至终只有一个Docker daemon在运行(运行在宿主机上)。

创建jenkins Job

创建Pipeline

制作jenkins slave镜像

代码的拉取和编译,镜像打包推送等都会在jenkins的slave pod中完成。也就是说这个镜像需要如下工具。

  • git
  • docker
  • java
  • maven

好在官方jenkins/jnlp-agent-docker镜像已经提供了git、docker、java这些基础的功能,可以使用改镜像作为基础镜像添加maven功能。

下载maven并解压到某个文件夹中,并创建Dockerfile文件

FROM jenkins/jnlp-agent-docker:latest

COPY apache-maven-3.6.3 ./maven

ENV PATH $PATH:/home/jenkins/maven/bin

执行行如下命令

docker build -t="<your docker repo>/jenkins-slave:<tag>" .
docker push

我已经将该镜像推送到阿里的镜像仓库通过如下命令就可以拉去

docker pull registry.cn-hangzhou.aliyuncs.com/cdtft/jenkins-slave:0.0.3

编写Pipeline script

pipeline {
  agent {
    kubernetes {
      yaml """
apiVersion: v1
kind: Pod
metadata:
  labels:
    some-label: some-label-value
spec:
  containers:
    - name: docker
      image: registry.cn-hangzhou.aliyuncs.com/cdtft/jenkins-slave:0.0.3
      command:
        - cat
      tty: true
      volumeMounts:
        - mountPath: /var/run/docker.sock
          name: docker-sock
  volumes:
    - name: docker-sock
      hostPath:
        path: /var/run/docker.sock
        type: FileOrCreate
"""
    }
  }

  stages {
    stage('Run docker') {
      steps {
        container('docker') {
          sh 'docker info'
        }
      }
    }
    stage('Run maven') {
      steps {
        container('docker') {
            sh 'mvn -v'
        }
      }
    }
  }
}

在上面的脚本中有一yaml描述了slave pod的信息

apiVersion: v1
kind: Pod
metadata:
  labels:
    some-label: some-label-value
spec:
  containers:
    - name: docker
      image: registry.cn-hangzhou.aliyuncs.com/cdtft/jenkins-slave:0.0.3
      command:
        - cat
      tty: true
      volumeMounts:
        - mountPath: /var/run/docker.sock
          name: docker-sock
  volumes:
    - name: docker-sock
      hostPath:
        path: /var/run/docker.sock
        type: FileOrCreate

上面的清单中将宿主机中的/var/run/docker.sock文件挂载到了容器中。

需要将kubernetes每一个node节点的/var/run/docker.sock文件权限修改为555

运行任务

在jenkins中启动创建好的pipeline任务,并在kubernetes master节点查看pod信息 可以看出slave节点在任务完成后推出。

jenkins的构建日志中也打印出了docker info和maven version的信息

总结

  • 通过docker in docker的方式在容器中操作docker,这位我们后面打包、推送镜像打下了基础
  • 自定义slave镜像,加入maven工具方便后面对java工程的编译(后期发布还需要helm,再看吧)
  • 使用Jenkins-operato让Jenkins和kubernetes结合动态伸缩足够cloud native。