在Docker中从Docker进行卷绑定安装? [英] Volume bind mounting from docker in docker?

查看:154
本文介绍了在Docker中从Docker进行卷绑定安装?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Docker容器 A,它将启动另一个容器 B(通过卷挂载/var/run/docker.sock)。现在,这些容器需要共享文件。

I have a Docker container "A" that will start another container "B" (by volume mounting /var/run/docker.sock). Now, these containers need to share files.

容器 B期望将文件进行卷挂载,而最简单的方法是从 A绑定挂载到为 B,但是Docker无法做到这一点(绑定装载始终源自主机文件系统)。

Container "B" expects files to be volume mounted, and the easiest way to do this would be to bind mount from "A" to "B", but Docker cannot do this (bind mounts always originate from the host file system).

容器是否有一种简单的方法可以与文件共享它创建的容器,而不依赖于主机文件系统,也没有从 A构建 B映像?

Is there a simple way for a container to share files with a container it created, without relying on the host file system, and without building the "B" image from "A"?

我一直在尝试创建卷并将文件复制到其中,但是解决方案往往很复杂且脆弱。理想情况下,我想将解决方案放在docker-compose文件中,然后在 A中运行,但这实际上几乎是不可能的。

I have been experimenting with creating volumes and copying files to it, but the solutions tend to be complicated and fragile. Ideally I would like to put the solution in a docker-compose file to be run inside of "A", but that looks virtually impossible.

作为参考,这是另一个可以完美解决我的问题的想法:
https://github.com。 com / docker / compose / issues / 3593#issuecomment-272089143

For reference, this is another idea that would have solved my problem perfectly: https://github.com/docker/compose/issues/3593#issuecomment-272089143

推荐答案

在安装Docker套接字时,它是在docker中并不是真正的docker,而是仅客户端通过API向主机上的守护程序发出请求,并且该守护程序不知道请求来自何处。因此,您可以将这个问题简化为您可以将文件从一个容器装载到另一个容器中。不幸的是,如果不使用两个容器外部的卷,就没有简单的答案。这是因为容器文件系统依赖于用于组装各种图像和容器层的图驱动程序,因此,即使是可能适用于overlay2的解决方案也将在其他驱动程序上中断,并且将依赖于docker内部,而该内部组件可能会更改而不会发出警告

When you mount the docker socket, it's not really docker in docker, but just a client making requests to the daemon on the host over the API, and that daemon doesn't know where the requests come from. So you can simplify this question to "can you mount files from one container into another container". Unfortunately there's no easy answer to that without using volumes that are external to both containers. This is because the container filesystems depend on the graph driver being used to assemble the various image and container layers, so even a solution that might work for overlay2 would break on other drivers, and it would depend on internals of docker that could change without warning.

一旦进入外部卷,我就会想到几种可能的解决方案。

Once you get into an external volume, there are several possible solutions I can think of.

选项A:一个通用的主机目录。我经常在笔记本电脑上使用透明容器,这是我在容器内运行命令的事实。我在容器中安装了具有完整路径的公共目录,例如 -v $ HOME:$ HOME 。如果在每个容器中都安装了相同的主机目录,则可以从容器 A和 B内部使用相同的技术。如果您对容器 A使用如上所述的卷挂载方式,则它将与组合文件一起使用,因为容器内的路径与主机上的路径相同。

Option A: a common host directory. I use this fairly often with what I consider transparent containers on my laptop, hiding the fact that I'm running commands inside of a container. I mount a common directory with the full path in my container, e.g. -v $HOME:$HOME. This same technique could be used from inside of container "A" and "B" if you mounted the same host directories in each. If you use a volume mount like the above for container "A", this would work with a compose file since the path is the same inside the container as it is on the host.

选项B:volumes_from。我什至会提及此选项,因为随着用户采用群体模式,该选项已逐步淘汰,但是可以选择将容器 A中的所有卷装入容器 B。这仍然需要您在容器 A中定义一个卷,但是现在您不必关心该卷的源了,它可以是主机卷,命名卷或匿名卷。

Option B: volumes_from. I hesitate to even mention this as an option because it's getting phased out as users adopt swarm mode, but there is an option to mount all volumes in container "A" to container "B". This still requires that you define a volume in container "A", but now you do no care about the source of the volume, it could be a host, named, or anonymous volume.

选项C:共享命名卷。命名卷使docker管理数据的存储,默认情况下位于主机上的/ var / lib / docker / volumes下。您可以使用相同的命名卷运行两个容器,这使您可以在容器之间传递数据。您确实需要在容器 A中具有该卷的名称,才能对具有相同名称的容器 B运行命令。首次使用命名卷时,命名卷还会从映像初始化命名卷的内容,因此这可能是有益的,尤其是对于文件所有权和权限。请注意,在下次使用相同命名卷时,它将不会对任何现有数据重新初始化,而是先前的数据将是持久性的。对于组合文件,您需要将命名卷定义为外部卷。

Option C: shared named volume. Named volumes let docker manage the storage of the data, by default under /var/lib/docker/volumes on the host. You can run both containers with the same named volume, which allows you to pass data between the containers. You do need to have the name of the volume in container "A" to run your command for container "B" with the same name. Named volumes also initialize the contents of the named volume from the image when you first use a named volume, so that may be beneficial, especially for file ownership and permissions. Just be aware that on the next usage of the same named volume, it will not reinitialize over any existing data, instead the previous data will be persistent. With a compose file, you would need to define the named volume as external.

选项D:手动创建的命名卷。尝试将某些文件从容器 A注入到容器 B中,可以通过多种方式通过Docker API注入。我已经看到文件保存到 A上的环境变量中,然后将环境变量写回到 B入口点中的文件中。对于较大的文件,或者为了避免更改 B的入口点,您可以创建命名卷并通过将数据通过docker的stdin / stdout管道传递到正在运行的容器中,并使用tar打包/解压缩该数据来进行填充I / O管道。这将在容器 A内部进行,因为tar命令的一半在该容器的文件系统内部运行。然后,容器 B将挂载该命名卷。要将数据从容器 A导入到命名卷,如下所示:

Option D: manually created named volume. If you are only trying to inject some files into container "B" from container "A", there are a variety of ways to inject that over the docker API. I've seen files saved into environment variables on "A" and then the environment variable written back out to a file in the entrypoint for "B". For larger files, or to avoid changing the entrypoint of "B", you can create a named volume and populate it by passing the data over docker's stdin/stdout pipes to a running container, and packing/unpacking that data with tar to send over the I/O pipes. This will work from inside of container "A" since one half of the tar command runs inside of that container's filesystem. Then container "B" would mount that named volume. To import data from container "A" to a named volume, that looks like:

tar -cC source_dir . | \
  docker run --rm -i -v target_vol:/target busybox tar -xC /target

要从指定的卷中取回数据,请按相反的顺序进行操作:

And to get data back out of a named volume, the process is reversed:

docker run --rm -v source_vol:/source busybox tar -cC /source . | \
  tar -xC target_dir

类似于选项C,您需要定义此选项在撰写文件中将卷命名为外部卷。

Similar to option C, you would need to define this named volume as external in your compose file.

这篇关于在Docker中从Docker进行卷绑定安装?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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