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

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

问题描述

我正在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

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并不是真正的 如此之多. ",而是"Docker下一个到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-卷不起作用:第1层容器中的文件已满,在第2层中为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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