前置条件:根据jenkins的官方文档,在linux服务器用docker搭建了jenkins平台,并且使用docker:dind镜像实现jenkins中的docker-in-docker。同官方文档,启动jenkins-web服务的容器名为"jenkins-blueocean",用docker:dind镜像启动的容器名为"jenkins-docker"

问题说明:业务需要在jenkins中启动docker容器并挂载宿主机即服务器上的文件目录,但是无论是挂载jenkins容器的本地路径还是挂载宿主机路径都不能正常挂载在所启动的二级docker容器中

解决方法:首先在使用docker:dind镜像启动"jenkins-docker"容器时挂载宿主机的路径,即添加"-v 服务器上需要挂载的路径:jenkins-docker容器内的路径",然后在jenkins-blueocean中启动容器时挂载jenkins-docker容器内的路径,即添加"-v jenkins-docker容器内的路径:二级docker容器中的路径",这样就在jenkins-blueocean中所启动的二级容器上挂载了宿主机的目录

附发现过程:

        查找问题时发现:虽然我不能在二级docker容器上挂载任何第一级容器的目录或宿主机目录,但使用jenkins下的某个docker镜像作为pipeline的某个stage的agent时能够正常挂载jenkins的workspace,有点啰嗦,简单来说就比如执行下面的pipeline

pipeline {

    agent none

    stages {
        stage('stage 1') {
            agent {
                docker {
                    image 'image1'
                }
            }
            steps {
                sh """
                mkdir test1
                ls
                """
            }
        }

        stage('stage 2') {
            agent {
                docker {
                    image 'image2'
                }
            }
            steps {
                sh """
                mkdir test2
                ls
                """
            }
        }

        stage('stage 3') {
            agent any
            steps {
                sh """
                mkdir test3
                ls
                """
            }
        }

    }
}

        前两个stage分别使用名为"image1"和"image2"的docker镜像环境,第三个stage使用jenkins的本地环境。

        三个ls分别输出"test1"、"test1 test2"、"test1 test2 test3",执行完后cd到对应的workspace中也可以正常看到test1 test2 test3三个文件夹,那就意味着在使用docker镜像所启动的容器环境下成功挂载了jenkins的workspace。查看这次build的Console Output,发现jenkins只不过是替你执行了容器的创建运行和挂载,如下

docker run -t -d -u 0:0 -w /var/jenkins_home/workspace/你的job名 -v /var/jenkins_home/workspace/你的job名:/var/jenkins_home/workspace/你的job名:rw,z -v /var/jenkins_home/workspace/你的job名@tmp:/var/jenkins_home/workspace/你的job名@tmp:rw,z -e ******** image1

随后jenkins在执行完对应的stage后停止并删除容器。那么问题来了,为什么jenkins中启动的docker容器可以挂载自己的workspace但不能挂载任何其他目录呢?

        回看Jenkins的官方文档发现,从"docker:dind"启动"jenkins-docker"容器时,在该容器中就挂载了jenkins的workspace所在目录,另外注意到在名为"jenkins"的桥接网络中, 该容器有个别称叫"docker",如下图,那也就是说在"jenkins-blueocean"这个容器中,执行docker实际调用的是"jenkins-docker"这个容器,是这个容器帮我们在"jenkins"桥接网络中封装了一层宿主机的docker,而调用该容器时只能看到"jenkins-docker"容器下的目录

docker desktop 和 nigix 实现了什么功能 docker-in-docker_二级

         那这样就说的通了。所有在服务器上、并希望挂载在"jenkins-blueocean"中启动的二级容器中的目录,都需要先挂载到"jenkins-docker"容器中,再从"jenkins-docker"中挂载到"jenkins-blueocean"中的容器上,即挂载顺序为:服务器(宿主机) -> "jenkins-docker" -> "jenkins-blueocean"中的容器

        所有其他docker-in-docker的应用同理