Docker Swarm如何实现卷共享?

ale*_*308 75 docker docker-swarm docker-machine

Docker Swarm可以管理两种类型的存储:卷和绑定.虽然Docker文档不建议绑定,因为它在本地目录(在每个群集节点上)与任务之间创建绑定,但未提及卷方法实现,因此我不理解任务之间如何共享卷.

Docker Swarm如何在节点之间共享卷?卷保存在哪里(在经理上?如果有多个管理?)?

如果节点在不同的网络中的不同机器上运行,那么它们之间没有问题吗?它是否创建了VPN?

Bre*_*her 53

您所询问的是一个常见问题.卷数据和卷的功能由卷驱动程序管理.就像你可以使用不同的网络驱动器一样overlay,bridge或者host,你可以用不同的音量驱动程序.

Docker和Swarm只提供local开箱即用的标准驱动程序.它没有任何Swarm的意识,只会在您的服务任务安排的任何节点上为您的数据创建新卷.这通常不是你想要的.

您需要一个可识别Swarm的第三方驱动程序插件,并确保您在正确的时间在正确的节点上为服务任务创建的卷.选项包括使用"Docker for AWS/Azure"及其包含的CloudStor驱动程序或流行的开源REX-Ray解决方案.

有许多第三方卷驱动程序,您可以在Docker Store上找到它们.


BMi*_*tch 39

Swarm Mode本身与卷没有任何不同,它运行您在运行容器的节点上提供的任何volume mount命令.如果您的卷安装是该节点的本地卷,那么您的数据将本地保存在该节点上.没有内置功能可以自动在节点之间移动数据.

有一些基于软件的分布式存储解决方案,如GlusterFS,而Docker有一个名为Infinit的尚未成为GA,其开发已经落后于EE中的Kubernetes集成.

典型的结果是您需要管理应用程序中的存储复制(例如etcd和其他基于raft的算法),或者在外部存储系统上执行安装(希望使用自己的HA).挂载外部存储系统有两个选项,基于块或文件.基于块的存储(例如EBS)通常具有更高的性能,但仅限于安装在单个节点上.为此,您通常需要第三方卷插件驱动程序,以使您的docker节点能够访问该块存储.基于文件的存储(例如EFS)具有较低的性能,但更具可移植性,并且可以同时安装在多个节点上,这对于复制服务非常有用.

最常见的基于文件的网络存储是NFS(这与EFS使用的协议相同).你可以在没有任何第三方插件驱动程序的情况下安装它.不幸的是,docker附带的"本地"卷插件驱动程序为您提供了使用驱动程序选项将所需的任何值传递给mount命令的选项,并且没有选项,它默认将存储卷存储在docker目录/ var/lib /中泊坞窗/卷.使用选项,您可以将NFS参数传递给它,它甚至可以在NFS主机名上执行DNS查找(通常情况下您没有使用NFS).下面是使用本地卷驱动程序安装NFS文件系统的不同方法的示例:

  # create a reusable volume
  $ docker volume create --driver local \
      --opt type=nfs \
      --opt o=nfsvers=4,addr=192.168.1.1,rw \
      --opt device=:/path/to/dir \
      foo

  # or from the docker run command
  $ docker run -it --rm \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=192.168.1.1\",volume-opt=device=:/host/path \
    foo

  # or to create a service
  $ docker service create \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=192.168.1.1\",volume-opt=device=:/host/path \
    foo

  # inside a docker-compose file
  ...
  volumes:
    nfs-data:
      driver: local
      driver_opts:
        type: nfs
        o: nfsvers=4,addr=192.168.1.1,rw
        device: ":/path/to/dir"
  ...
Run Code Online (Sandbox Code Playgroud)


tig*_*igu 12

我为本地托管的 swarm 提供的解决方案:每个工作节点都安装了一个 nfs-share,由我们的文件服务器在/mnt/docker-data. 当我在我的服务组合文件中定义卷时,我将设备设置为 下的某个路径/mnt/docker-data,例如:

volumes:
  traefik-logs:
    driver: local
    driver_opts:
      o: bind
      device: /mnt/docker-data/services/traefik/logs
      type: none
Run Code Online (Sandbox Code Playgroud)

使用这个解决方案,docker 在每个节点上创建卷,服务被部署到 - 令人惊讶 - 已经有数据,因为它是另一个节点上的卷使用的相同路径。

如果您仔细查看节点文件系统,您会看到挂载到我的文件服务器挂载是在 下创建的/var/lib/docker/volumes,请参见此处:

root@node-3:~# df -h
Dateisystem                                                                                                   Größe Benutzt Verf. Verw% Eingehängt auf
[...]
fs.mydomain.com:/srv/shares/docker-data/services/traefik/logs                                 194G    141G   53G   73% /var/lib/docker/volumes/traefik_traefik-logs/_data
Run Code Online (Sandbox Code Playgroud)


sup*_*r_p 7

我的适用于AWS EFS的解决方案有效:

  1. 创建EFS(不要忘记在安全组中打开NFS端口2049)
  2. 安装nfs-common软件包:

    sudo apt-get install -y nfs-common

  3. 检查您的ef是否有效:

    mkdir efs测试点
    须藤chmod go + rw efs-test-point
    须藤安装-t nfs -o nfsvers = 4.1,rsize = 1048576,wsize = 1048576,hard,timeo = 600,retrans = 2,noresvport [YOUR_EFS_DNS]:/ efs-test-point
    触摸efs-test-point / 1.txt
    须藤umount efs-test-point /
    ls -la efs-test-point /

    目录必须为空

    须藤安装-t nfs -o nfsvers = 4.1,rsize = 1048576,wsize = 1048576,hard,timeo = 600,retrans = 2,noresvport [YOUR_EFS_DNS]:/ efs-test-point

    ls -la efs-test-point/

    文件1.txt必须存在

  4. 配置docker-compose.yml文件:

    服务:
      sidekiq:
        数量:
          -uploads_tmp_efs:/ home / application / public / uploads / tmp
      ...
    数量:
      uploads_tmp_efs:
        司机:本地
        driver_opts:
          类型:nfs
          o:addr = [YOUR_EFS_DNS],nfsvers = 4.1,rsize = 1048576,wsize = 1048576,hard,timeo = 600,retrans = 2
          设备:[YOUR_EFS_DNS]:/