简体   繁体   English

Docker 将一个容器的目录挂载到另一个容器

[英]Docker mount an directory of container to another container

I have an container Container-A which has directory /opt/test/data which contains files which get created during building image.我有一个容器 Container-A,它的目录 /opt/test/data 包含在构建映像期间创建的文件。 Now I want to share /opt/test/data(container-a directory) to Container-B as it requires to use those files during its lifecycle.现在我想将 /opt/test/data(container-a directory) 共享给 Container-B,因为它需要在其生命周期内使用这些文件。 I have tried below option我试过下面的选项

docker run -it -d -v shareddata:/opt/test/data --name container-a test

and then run container-B as然后运行容器-B

docker run -it --volumes-from container-a --name container-b test-prod:latest

The data got shared but it creates an named volume shareddata on the host which contains a duplicate data of /opt/test/data directory of container-a.数据已共享,但它在主机上创建了一个命名卷 shareddata,其中包含 container-a 的 /opt/test/data 目录的重复数据。

I have tried another option of creating a name volume data and mounting it in container-a.我尝试了另一种创建名称卷数据并将其安装在容器-a 中的选项。 Then I created a symlink of /opt/test/data on mounted volume as below然后我在已安装的卷上创建了 /opt/test/data 的符号链接,如下所示

ln -s /data/data /opt/test/data

Now mounted the /data volume to container-b but the symlink didn't work on container-b as it shows it as broken links.现在将 /data 卷安装到 container-b 但符号链接在 container-b 上不起作用,因为它显示为断开的链接。

Is there a way I can share container-a directory to container-b without duplicating the data as we want to keep data which is static and quite big approx 2.5G to one image and then an instance keep running which is shared across multiple container of test-prod image?有没有一种方法可以在不复制数据的情况下将容器-a 目录共享到容器-b,因为我们要保留 static 的数据,并且一个图像大约 2.5G 相当大,然后一个实例继续运行,该实例在多个容器之间共享测试产品图像?

If you are willing and can replace docker with podman , it should be able to do it:如果您愿意并且可以用 podman 替换docker ,它应该可以做到:

  1. podman create says its --mount option supports type=image , so something like podman create说它的--mount选项支持type=image ,所以像

    podman run --mount type=image,source=test,destination=/opt/test/data test-prod:latest

    should work.应该管用。

  2. It also has podman mount that allows you to access the container filesystem from the host, which you can then bind into another container.它还具有podman mount ,允许您从主机访问容器文件系统,然后您可以将其绑定到另一个容器。

If you can't go to podman, the low level ctr command that controls the containerd (that now is underneath docker and also most kubernetes installs) has a ctr image mount command that should work similar to the podman mount one.如果你不能 go 到 podman,控制containerd的低级ctr命令(现在位于 docker 和大多数kubernetes ctr image mount的命令下) Unfortunately I couldn't find proper documentation.不幸的是,我找不到合适的文档。 Also the command may not be installed on your system.此外,该命令可能未安装在您的系统上。

Another option is to access it through the /proc filesystem when sharing a pid namespace.另一种选择是在共享 pid 命名空间时通过/proc文件系统访问它。

$ docker run -d --name container-a test sh -c 'echo $$; while :; do sleep 1; done'
$ docker run -it --pid container:container-a --name container-b -e "A_PID=$(docker logs container-a)" test-prod:latest

and then the directory should be available at /proc/$A_PID/root/opt/test/data .然后目录应该在/proc/$A_PID/root/opt/test/data可用。

Besides sharing the PID namespace the containers have to be using the same UID for this to work.除了共享 PID 命名空间之外,容器必须使用相同的 UID 才能工作。

Explanation:解释:

  • The filesystem view a specific process sees is available under /proc/ pid /root .特定进程看到的文件系统视图在/proc/ pid /root下可用。 It can only be accessed by processes with the same UID (the same rules as for ptrace should apply).它只能由具有相同 UID 的进程访问(应适用与 ptrace 相同的规则)。
  • You can make two containers share the PID namespace with the --pid container: container flag, which makes the /proc/ pid accessible from the other container.您可以使用--pid container: container标志使两个容器共享 PID 命名空间,这使得/proc/ pid可以从另一个容器访问。
  • The PID is not necessarily fixed, so the container providing the data must print the PID of a process it is running and then enter an endless loop. PID 不一定是固定的,所以提供数据的容器必须打印它正在运行的进程的 PID,然后进入无限循环。

The usual way to do this is to create those files while starting the container, instead while building.通常的方法是在启动容器时创建这些文件,而不是在构建时。 You can check first if the files are created, and if not, create them (or move them from a /tmp or wathever)您可以先检查文件是否已创建,如果没有,则创建它们(或从 /tmp 或 wathever 移动它们)

This is the way official image for mysql do that, for example.例如,这是 mysql 的官方映像的方式。

Then, you can mount a volume in that directory, and share it between containers.然后,您可以在该目录中挂载一个卷,并在容器之间共享它。

Try this, you could share data directly from one container to another without using the host machines directory,试试这个,你可以直接从一个容器共享数据到另一个容器而不使用主机目录,

$ docker run -v /opt/test/data --name container-a test
$ docker run --volumes-from container-a test-prod:latest

Hope, this solves your problem.希望,这可以解决您的问题。 As the data size is larger and also you are sharing this between multiple containers, probably go for better storage orchestration solution like rexray which you could share easily between n number of containers.由于数据规模更大,而且您要在多个容器之间共享数据,可能会选择更好的存储编排解决方案,例如rexray ,您可以在 n 个容器之间轻松共享。

If files already exist in the directory of the container you're mounting as a volume, the contents of the directory will be copied to the volume.如果文件已存在于您作为卷挂载的容器目录中,则该目录的内容将被复制到该卷中。 See Populate a volume using a container .请参阅使用容器填充卷

There's no way to mount a container's directory as a volume without copying.不复制就无法将容器的目录挂载为卷。 An alternative is to not store the data in a container and instead create a volume on the host and populate it with the data.另一种方法是不将数据存储在容器中,而是在主机上创建一个卷并用数据填充它。 This way, the data will only exist on once.这样,数据将只存在一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM