Docker 中的 Docker - 卷不工作:第一级容器中的文件已满,第二层为空 [英] Docker in Docker - volumes not working: Full of files in 1st level container, empty in 2nd tier

查看:19
本文介绍了Docker 中的 Docker - 卷不工作:第一级容器中的文件已满,第二层为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Docker 中运行 Docker(特别是运行 Jenkins,然后运行 ​​Docker 构建器容器来构建项目映像,然后运行这些容器,然后运行测试容器).

I am running Docker in Docker (specifically to run Jenkins which then runs Docker builder containers to build a project images and then runs these and then the test containers).

jenkins 镜像是这样构建和启动的:

This is how the jenkins image is built and started:

docker build --tag bb/ci-jenkins .
mkdir $PWD/volumes/
docker run -d --network=host  
  -v /var/run/docker.sock:/var/run/docker.sock 
  -v /usr/bin/docker:/usr/bin/docker 
  -v $PWD/volumes/jenkins_home:/var/jenkins_home 
  --name ci-jenkins bb/ci-jenkins

詹金斯工作正常.但是有一个基于 Jenkinsfile 的作业,它运行这个:

Jenkins works fine. But then there is a Jenkinsfile based job, which runs this:

docker run -i --rm -v /var/jenkins_home/workspace/forkMV_jenkins-VOLTRON-3057-KQXKVJNXOU4DGSUG3P27IR3QEDHJ6K7HPDEZYN7W6HCOTCH3QO3Q:/tmp/build collab/collab-services-api-mvn-builder:2a074614 mvn -B -T 2C install

这会导致错误:

您指定的目标需要执行项目,但此目录 (/tmp/build) 中没有 POM.

The goal you specified requires a project to execute but there is no POM in this directory (/tmp/build).

当我对容器执行 docker exec -it sh 时,/tmp/build 为空.但是当我在 Jenkins 容器中时,路径 /var/jenkins_home/...QO3Q/ 存在,它包含所有已签出并准备好的文件的工作区.

When I do docker exec -it sh to the container, the /tmp/build is empty. But when I am in the Jenkins container, the path /var/jenkins_home/...QO3Q/ exists and it contains the workspace with all the files checked out and prepared.

所以我想知道 - Docker 怎样才能愉快地挂载卷然后它是空的?*

更令人困惑的是,此设置适用于我在 Mac 上的同事.我在 Linux、Ubuntu 17.10、Docker 最新版本上.

What's even more confusing, this setup works for my colleague on Mac. I am on Linux, Ubuntu 17.10, Docker latest.

推荐答案

经过一番研究,静下心来思考,才发现Docker-in-Docker并不是真的那么-in-"",因为它是Docker-next-to-Docker".

After some research, calming down and thinking, I realized that Docker-in-Docker is not really so much "-in-", as it is rather "Docker-next-to-Docker".

使容器能够运行另一个容器的技巧是通过卷共享 /var/run/docker.sock:-v/var/run/docker.sock:/var/run/docker.sock

The trick to make a container able to run another container is sharing /var/run/docker.sock through a volume: -v /var/run/docker.sock:/var/run/docker.sock

然后容器中的docker客户端实际调用宿主机上的Docker.

And then the docker client in the container actually calls Docker on the host.

卷源路径(:左侧)不是指中间容器,而是指宿主文件系统!

The volume source path (left of :) does not refer to the middle container, but to the host filesystem!

意识到这一点后,修复方法是使宿主文件系统和 Jenkins(中间)容器中 Jenkins workspace 目录的路径相同:

After realizing that, the fix is to make the paths to the Jenkins workspace directory the same in the host filesystem and the Jenkins (middle) container:

docker run -d --network=host  
   ...
   -v /var/jenkins_home:/var/jenkins_home

瞧!有用.(我创建了一个符号链接而不是移动它,似乎也可以.)

And voilá! It works. (I created a symlink instead of moving it, seems to work too.)

如果您正在查看同事的 Mac,这会有点复杂,因为 Docker 的实现方式有些不同 - 它在基于 Alpine Linux 的 VM 中运行,但假装没有.(不是 100% 确定这一点.)在 Windows 上,我读到路径有另一层抽象 - 从 C:/somewhere/... 映射到类似 Linux 的路径.

It is a bit complicated if you're looking at colleague's Mac, because Docker is implemented a bit differently there - it is running in an Alpine Linux based VM but pretending not to. (Not 100 % sure about that.) On Windows, I read that the paths have another layer of abstraction - mapping from C:/somewhere/... to a Linux-like path.

我希望我能节省一些时间来弄清楚:)

I hope I'll save someone hours of figuring out :)

这篇关于Docker 中的 Docker - 卷不工作:第一级容器中的文件已满,第二层为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆