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

5

我有一个容器 Container-A,其中包含目录 /opt/test/data,该目录包含在构建镜像期间创建的文件。 现在我想将 /opt/test/data(Container-A 目录)共享到 Container-B 中,因为在其生命周期中需要使用这些文件。 我尝试了以下选项

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

然后运行容器B,如下:

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

数据被共享,但它在主机上创建了一个名为 shareddata 的命名卷,其中包含 container-a 的 /opt/test/data 目录的重复数据。
我尝试了另一种选项,创建了一个名为 data 的命名卷并将其挂载到 container-a 中。然后我创建了一个指向已挂载卷上 /opt/test/data 的符号链接,如下所示。
ln -s /data/data /opt/test/data

现在已将/data卷安装到container-b中,但符号链接在container-b上无法工作,因为它显示为损坏的链接。
有没有办法在不重复数据的情况下将container-a目录共享给container-b?我们希望将静态且相当大约2.5G的数据保存在一个镜像中,并保持实例运行,该实例在test-prod镜像的多个容器之间共享。
5个回答

1

另一种选择是在共享 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

然后目录应该在/proc/$A_PID/root/opt/test/data中可用。

除了共享PID命名空间,容器还必须使用相同的UID才能使此功能正常工作。

说明:

  • 特定进程看到的文件系统视图在/proc/pid/root下可用。只有具有相同UID的进程才能访问它(与ptrace的相同规则应适用)。
  • 您可以使用--pid container:container标志使两个容器共享PID命名空间,从而使/proc/pid可从另一个容器中访问。
  • PID不一定固定,因此提供数据的容器必须打印其正在运行的进程的PID,然后进入无限循环。

1

如果容器挂载的目录中已经存在文件,则该目录的内容将被复制到卷中。请参见使用容器填充卷

没有办法在不复制的情况下将容器的目录挂载为卷。另一种选择是不要将数据存储在容器中,而是在主机上创建一个卷并用数据填充它。这样,数据只会存在于一个地方。


0

如果您愿意并且可以使用podman替换docker,它应该能够做到:

  1. podman create 命令表示其 --mount 选项支持 type=image,因此类似以下命令:

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

    应该可以正常工作。

  2. 它还有 podman mount 命令,允许您从主机访问容器文件系统,然后将其绑定到另一个容器中。

如果您无法使用podman,可以使用低级别的ctr命令来控制containerd(现在位于docker和大多数kubernetes安装程序之下),该命令具有ctr image mount命令,应该类似于podman mount。不幸的是,我找不到适当的文档。此外,该命令可能未安装在您的系统上。

-1
通常的做法是在启动容器时创建这些文件,而不是在构建过程中。您可以首先检查文件是否已创建,如果没有,则创建它们(或从/tmp或其他位置移动它们)。
例如,MySQL的官方镜像就是这样做的。
然后,您可以在该目录中挂载一个卷,并在容器之间共享它。

容器镜像使用 RPM 安装这些文件,因为它们是特定区域的媒体文件。所以我们不能使用这种方法。 - Abhinav

-2

你可以尝试使用这个方法,直接在容器之间共享数据而不必使用主机机器的目录。

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

希望这能解决你的问题。由于数据量较大且你要在多个容器之间共享,建议选择更好的存储编排解决方案,比如rexray,它可以在任意数量的容器之间轻松共享。

我已经尝试过这个方法,但它会在主机卷上创建重复的文件。 - Abhinav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接