繁体   English   中英

允许 docker-compose 中的多个服务共享一个合并卷

[英]Allowing multiple services in docker-compose to share a merged volume

给定一个docker-compose.yml文件,如下所示,我正在寻找一种方法,服务ab都可以访问由两个容器的合并内容组成的共享卷。

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 因为每次容器启动时都会删除内容?

无论如何,我发现通过使用路径重定向来说服容器共享同一个文件夹通常很有用。 我将分享两种实现此目的的方法:

  1. 如果您有权访问在/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 ,但现在它们可以彼此和平相处。

  2. 如果您无法更改/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.

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