[英]Allowing multiple services in docker-compose to share a merged volume
给定一个docker-compose.yml
文件,如下所示,我正在寻找一种方法,服务a
和b
都可以访问由两个容器的合并内容组成的共享卷。
version: '3'
volumes:
shared-merged-volume:
services:
a:
volumes:
- shared-merged-volume:/shared
b:
volumes:
- shared-merged-volume:/shared
假设服务a
在/shared/dir-from-a
有一个目录,而服务b
有一个类似的/shared-dir-from-b
目录。 期望的结果是最终得到:
$ ls /shared # from either container
dir-from-a
dir-from-b
我发现其中一个容器“获胜”并且这两个目录中只有一个存在。 我可以像这样解决这个问题,但更冗长,如果目录内容发生变化,则需要修改:
version: '3'
volumes:
service-a-shared-volume:
service-b-shared-volume:
services:
a:
volumes:
- service-a-shared-volume:/shared/dir-from-a
- service-b-shared-volume:/shared/dir-from-b
b:
volumes:
- service-a-shared-volume:/shared/dir-from-a
- service-b-shared-volume:/shared/dir-from-b
提前感谢您的帮助
是否需要使用命名卷?
如果没有,那么为了完成这种合并,我通常只将目录映射到主机驱动器上的一个位置,而不是使用卷,并且合并不会有问题。 在大负载和多个容器同时写入的情况下进行了测试。
建议的撰写文件:
version: '3'
volumes:
shared-merged-volume:
services:
a:
volumes:
- /location/on/host/system:/shared
b:
volumes:
- /location/on/host/system:/shared
根据评论编辑
此方法将本地主机目录中的所有内容都挂载到/shared
,这意味着如果它为空-它将挂载空dir,并且在那里存在的所有内容-都会被空dir覆盖。 服务启动后,将在安装中写入的所有内容将被持久保存,并按预期跨服务合并。
如果两个容器都在创建不同的文件夹,我看不出它们如何争相创建自己的文件夹,除非它们都先删除/shared
的内容,然后再创建文件夹? 但这意味着在这种情况下使用卷是 null 因为每次容器启动时都会删除内容?
无论如何,我发现通过使用路径重定向来说服容器共享同一个文件夹通常很有用。 我将分享两种实现此目的的方法:
如果您有权访问在/shared
中创建文件夹的代码,则可以使用环境变量来更改每个服务的/shared
的预期位置
version: '3' volumes: shared-merged-volume: services: a: environment: SHARED_VOLUME_PATH: /shared/a/ volumes: - shared-merged-volume:/shared b: environment: SHARED_VOLUME_PATH: /shared/b/ volumes: - shared-merged-volume:/shared
您可能需要让服务创建SHARED_VOLUME_PATH
,但现在它们可以彼此和平相处。
如果您无法更改/shared
的位置,这意味着每个服务将始终希望使用该路径,则创建路径重定向的另一种方法是使用符号链接。 为此,您必须覆盖服务的入口点或在映像的构建过程中执行此步骤。
version: '3' volumes: shared-merged-volume: services: a: entrypoint: [ "ln", "-sf", "/symshared/a/", "/shared/" ] volumes: - shared-merged-volume:/symshared b: entrypoint: [ "ln", "-sf", "/symshared/b/", "/shared/" ] volumes: - shared-merged-volume:/symshared
或者,提前构建映像,并在Dockerfile
中添加一个简单的RUN
命令,该命令会创建此符号链接:
... ARG SHARED_VOLUME_PATH RUN ln -sf ${SHARED_VOLUME_PATH} /shared/
这允许您做的是每个容器将像以前一样继续使用/shared
,但您仍然可以将其内容存储在卷中,而不会干扰其他容器想要使用自己的/shared
版本执行的操作.
不用说, ln
命令只适用于 linux 和其他 unix,在某些情况下,您可能需要事先安装它。 如果您的容器映像基于 windows 之类的其他内容,那么请查找其他可用于创建符号链接的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.