集群中的 Docker 卷

Loï*_*oix 6 docker docker-swarm docker-volume

有人可以为我确认这一点。

当使用 swarm 在 docker 中运行服务时,使用本地驱动程序的 docker 卷将在与服务的运行容器相同的节点上创建。

如果服务在 2 个不同的节点上生成任务,则每个容器将在其各自安装的卷中看到不同的数据。

例如,如果我在 node1 上运行了一个创建/填充卷的服务,如果使用本地驱动程序创建卷,它将始终只对 node1 可见。

因此,如果我在 node1 上运行了一项服务,该服务会更新名为 project-addons 的卷。我在 node2 上生成了一个服务,它可以挂载 project-addons 卷,但它是空的。如果我想在任何地方都正确填充项目插件。我必须在每个节点上运行一个任务,或者使用一个群感知的卷驱动程序(比如跨群节点复制数据)。

所以如果我的理解是正确的,卷不是特定于群节点的,可以从任何地方访问,但如果卷驱动程序是本地的,我很可能会挂载一个空卷。

Loï*_*oix 2

这是一个草稿答案,自从提出这个问题以来我学到了很多东西。

首先,了解什么是卷很重要。

卷是 docker 描述挂载点的一种方式。创建卷后,在容器需要它之前,它实际上不会物理安装到任何位置。

因此,如果您有一个 docker swarm 和多个节点,那么当您创建卷时,基本上该卷的描述会被复制到每个节点上,但不会发生其他情况。

当容器启动时,它将尝试在正在启动的主机上安装卷。如果该卷实际不存在,它将首次安装/创建并在那里重用。因此,如果您使用本地驱动程序,它实际上会创建该文件夹,仅此而已。

如果您有多个主机,则意味着每个主机将根据需要创建自己的文件夹。

因此本质上卷驱动程序至少可以通过这 4 种方法来描述:

  1. 卸载
  2. 创造
  3. 删除

如果您想设置一个群感知驱动程序,首先要定义一个插件来描述实现这 4 种方法的卷驱动程序。驱动程序被实现为与 docker 守护进程通信的 http 服务。例如,驱动程序接收操作并最终创建或删除文件夹。

所以此时,您应该明白,最终,卷只不过是一个挂载点。因此,任何可以安装的东西都可以用作卷。

问题在于,即使您可以安装网络驱动器,这也是一个非常愚蠢的过程,您唯一能做的就是安装存在的东西。因此,除非您实现驱动程序来执行一些时髦的操作,例如在尝试安装之前创建远程安装,否则您将被迫以不同的方式执行操作。

我们以 Amazon EFS 为例。您可以将其安装为 NFS 驱动器,然后它就可以正常工作了。但是假设您想在不同的服务之间共享您的 NFS 驱动器...如果您将 NFS 驱动器的根目录挂载到卷中,则无法执行此操作,因为根目录将在服务之间共享,并且可能会导致问题在不应该被容器看到的时候被容器看到。

我发现实现这一点的一种方法是让 NFS 驱动器的结构如下:

  • / 根
  • /volumes/[volume_name] 您要在服务中安装的卷

这是一种简化的定义方式,但简而言之,可以这样完成。每个卷都属于共享网络驱动器指定目录中的一个文件夹。

/volumes/fun但由于该过程非常愚蠢,如果您安装指向但不存在的卷,则简单安装不存在的文件夹将会失败/volumes/fun/volumes/fun不走运,docker 不够聪明,无法默认创建。这可以通过网络驱动程序来完成。

但幸运的是,我们有一种方法可以做到这一点,而无需安装插件等......

在网络驱动器上实现卷创建的一种方法是使用“看门狗”服务来检查卷的创建时间。该服务将挂载远程驱动器的 /(NFS、SSHFS 或其他任何方式,只要您具有写访问权限)。

然后它将侦听事件或轮询 docker 守护进程以获取卷。如果它发现以某种方式标记的卷要安装在它正在监视的同一驱动器中。它将检查安装的文件夹是否存在,如果不存在,则会创建它。

如果在创建文件夹之前启动容器,它将无法工作,但当远程驱动器看门狗创建文件夹时,服务将启动,就好像什么也没发生一样。

最后,很有可能制作“群”感知卷,而无需求助于各种奇怪的 docker 驱动程序卷插件实现。

最后,本地驱动程序只是一个挂载点。重要的是找到一种方法来挂载某些东西,并有一种方法知道你尝试挂载的东西是否存在。您可以通过访问 docker 守护进程轻松创建它。

一种策略是在卷上设置标签,如下所示:

  • swarm.volume.source :源标签
  • swarm.volume.name :要挂载在 /volumes/... 中的文件夹名称

这样您就不必解析选项参数,您可以直接使用定义的标签,并且定义标签时,很容易知道您的看门狗真正关心哪个卷。

但此时它非常依赖于基础设施,因为您可以在创建卷的同时在 /volumes 上创建文件夹。

因此,说您需要 swarm 感知驱动程序才能在 docker swarm 中拥有远程驱动器有点误导。不存在“群体”意识这样的东西。所有卷都是“群体感知”的。确实达到了你所期望的结果。