2015-07-13 110 views
14

我正在运行一个Jenkins集群,其中主节点和从节点都在作为Docker容器运行。Docker中的Docker无法安装卷

主机是在MacOS上运行的最新的boot2docker VM。

为了让詹金斯能够执行使用泊坞部署,我已经安装在主机docker.sock和泊坞窗客户端向詹金斯容器是这样的: -

docker run -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker -v $HOST_JENKINS_DATA_DIRECTORY/jenkins_data:/var/jenkins_home -v $HOST_SSH_KEYS_DIRECTORY/.ssh/:/var/jenkins_home/.ssh/ -p 8080:8080 jenkins 

我面临的问题,同时安装向在Jenkins容器内运行的Docker容器添加一个卷。例如,如果我需要运行詹金斯容器内的另一个容器中,我执行以下操作: -

sudo docker run -v $JENKINS_CONTAINER/deploy.json:/root/deploy.json $CONTAINER_REPO/$CONTAINER_IMAGE 

上面运行的容器,但文件“deploy.json”未安装的文件,但而是作为“目录”。即使我将目录挂载为卷,我也无法查看生成的容器中的文件。

这是一个问题,因为在Docker案例中由于Docker的文件权限?

任何指针都会很有用!

谢谢!

回答

27

Docker容器中的Docker容器使用父HOST的Docker守护进程,因此,在“docker-in-docker”情况下挂载的任何卷仍从HOST引用,而不是从容器引用。

因此,从Jenkins容器安装的实际路径在HOST中“不存在”。由于这个原因,在空的“docker-in-docker”容器中创建了一个新的目录。将目录装载到Container中的新Docker容器时,同样适用。

非常基本和明显的东西,我错过了,但很快我意识到输入问题就意识到了。

+0

谢谢。巨大的帮助。肯定没有意识到它会表现得那样。 –

+0

很高兴知道这有帮助。谢谢! – ZephyrPLUSPLUS

+7

那么解决方案是什么?因为docker文档引用了https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/,它说这样使用docker。但是这种方式无法将容器从一个码头容器挂载到另一个容器。数据量? –

2

另一种解决方法是使用命名卷或数据卷容器。这样,容器内部不需要知道主机的任何信息,Jenkins容器和构建容器都以相同的方式引用数据量。

我试过做类似于你正在做的事情,除了代理人而不是使用Jenkins主人。问题相同,因为我无法将Jenkins工作区安装在内部容器中。对我来说有效的是使用数据容器容器方法,并且工作区文件对代理容器和内部容器均可见。我喜欢的方法是两个容器都以相同的方式引用数据量。使用内部容器来安装目录会非常棘手,因为内部容器现在需要知道其父容器正在运行的主机。

我有详细的博客文章对我的做法在这里:

http://damnhandy.com/2016/03/06/creating-containerized-build-environments-with-the-jenkins-pipeline-plugin-and-docker-well-almost/

除了代码在这里:

https://github.com/damnhandy/jenkins-pipeline-docker

在我的具体情况,而不是一切工作我的方式按照Jenkins Pipeline插件喜欢它。但它确实解决了内部容器能够访问Jenkins工作空间目录的问题。

+0

我不能相信有人低估了这个答案。这是非常出色的,正确地处理问题的核心。这是一个解决方案,因为它存在的原因使用Docker的功能。 – neverfox

+0

另一个相关的博客文章可以在这里找到(https://www.develves.net/blogs/asd/2016-05-27-alternative-to-docker-in-docker/)(不是我的)。 – helmesjo

4

关于你的使用情况与詹金斯,你可以简单地伪造通过创建主机上的符号链接的路径:

ln -s $HOST_JENKINS_DATA_DIRECTORY/jenkins_data /var/jenkins_home 
+0

我解决了我的问题谢谢! –

0

一种方法来解决这个问题是在安装目录(你的搬运工容器内在其中您使用完全相同的路径来安装您的码头插座)。然后,当您从该容器内运行容器时,您可以使用docker -v将该容器的路径内的任何内容安装到新容器中。

借此例如:

# Spin up your container from which you will use docker 
docker run -v /some/dir:/some/dir -v /var/run/docker.sock:/var/run.docker.sock docker:latest 

# Now spin up a container from within this container 
docker run -v /some/dir:/usr/src/app $CONTAINER_IMAGE 

文件夹/some/dir现在被安装在您的主机上,中间容器以及您的目的地容器中。由于安装路径作为“几乎在码头中的泊坞窗”容器在主机上存在,因此可以按预期使用docker -v

这有点类似于在主机上创建一个符号链接的建议,但我发现这个(至少在我的情况下)是一个更干净的解决方案。之后不要忘记清理主机上的目录! ;)