【问题标题】:How does Docker Swarm implement volume sharing?Docker Swarm 如何实现卷共享?
【发布时间】:2017-12-11 15:21:35
【问题描述】:

Docker Swarm 可以管理两种类型的存储:

volumebind

虽然 Docker 文档没有建议 bind,因为它在本地目录(在每个 swarm 节点上)与任务之间创建了绑定,但没有提到 volume 实现,所以我不明白卷是如何任务之间共享?

  • Docker Swarm 如何在节点之间共享卷?
  • 卷保存在哪里(在一个管理器上?如果有多个管理器?)
  • 如果在不同网络的不同机器上运行,节点之间是否没有问题?
  • 它会创建 VPN 吗?

【问题讨论】:

  • Swarm 是否共享卷?大约一年前,我处理了 docker swarm,但我认为 swarm 不负责在节点之间共享卷。如果您希望您的节点共享相同的卷,则必须使用 azure volumedriver 等卷插件。

标签: docker docker-swarm docker-machine


【解决方案1】:

Swarm 模式本身不会对卷做任何不同的事情,它会运行您在运行容器的节点上提供的任何卷挂载命令。如果您的卷安装在该节点本地,那么您的数据将本地保存在该节点上。没有在节点之间自动移动数据的内置功能。

有一些基于软件的分布式存储解决方案,例如 GlusterFS,Docker 有一个称为 Infinit 的解决方案,它还不是 GA,它的开发已经让位于 EE 中的 Kubernetes 集成。

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

最常见的基于文件的网络存储是 NFS(这与 EFS 使用的协议相同)。您可以在没有任何 3rd 方插件驱动程序的情况下安装它。不幸的是,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"
  ...

如果您在最后使用 compose 文件示例,请注意,对卷的更改(例如更新服务器路径或地址)不会反映在现有命名卷中,只要它们存在。您需要重命名您的卷或删除它,以允许 swarm 使用新值重新创建它。

我在大多数 NFS 使用中看到的另一个常见问题是在服务器上启用了“root squash”。当以 root 身份运行的容器尝试将文件写入卷时,这会导致权限问题。您也有类似的 UID/GID 权限问题,其中容器 UID/GID 需要权限才能写入卷,这可能需要在 NFS 服务器上调整目录所有权和权限。

【讨论】:

    【解决方案2】:

    您所问的是一个常见问题。卷数据和卷可以执行的功能由卷驱动程序管理。就像您可以使用不同的网络驱动程序(如 overlaybridgehost)一样,您也可以使用不同的卷驱动程序。

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

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

    有很多 3rd 方音量驱动程序,您可以在 Docker Store 上找到它们。

    【讨论】:

    • hadoop 可以充当这样的共享卷吗?
    【解决方案3】:

    我对本地托管群的解决方案: 每个工作节点都挂载了一个 nfs 共享,由我们的文件服务器在/mnt/docker-data 上提供。在我的服务组合文件中定义卷时,我将设备设置为/mnt/docker-data 下的某个路径,例如:

    volumes:
      traefik-logs:
        driver: local
        driver_opts:
          o: bind
          device: /mnt/docker-data/services/traefik/logs
          type: none
    

    使用此解决方案,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
    

    【讨论】:

    • 这在混合群体中有效吗?即 Windows 节点。
    • 我不这么认为
    【解决方案4】:

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

    1. Create EFS(别忘了在安全组打开NFS 2049端口)
    2. 安装 nfs-common 包:

      sudo apt-get install -y nfs-common

    3. 检查你的 efs 是否有效:

      mkdir efs 测试点
      sudo chmod go+rw efs-test-point
      sudo mount -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
      sudo umount efs-测试点/
      ls -la efs-test-point/

      目录必须为空

      sudo mount -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 文件:

      服务:
        旁白:
          卷:
            - 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]:/

    【讨论】:

      【解决方案5】:

      默认swarm会一直寻找本地卷驱动,所以最好的办法是

      1. 创建 nfs 共享,即yum -y install nfs-utils
      2. 将其导出到 /etc/exports 中,如下所示, /root/nfshare 192.168.1.0/24(rw,sync,no_root_squash)
      3. 打开所需的端口,在我的情况下,我在下面做了, firewall-cmd --permanent --add-service mountd ; firewall-cmd --permanent --add-service rpc-bind ; firewall-cmd --permanent --add-service nfs ; firewall-cmd --zone=public --permanent --add-port 2049/tcp
      4. 在 docker 工作节点上挂载新创建的共享,然后
      5. docker service create --name my-web --replicas 3 -p 80:80 --mount 'type=volume,source=nfshare,target=/usr/share/nginx/html/,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/root/nfshare,"volume-opt=o=addr=192.168.1.8,rw"' nginx:latest
      6. 在上面的示例中,我在 192.168.1.8 主机上创建了 nfshare 并使用 /etc/exports 文件导出
      7. 已启动守护程序 systemctl start nfs-server rpcbind & systemctl enable nfs-server rpcbind
      8. exportfs -r 更改生效
      9. /root/nfshare 有我自己的 index.html 10.仔细检查volume-drive条目,它也可以是外部的&哇它对我有用
      10. 更多参考https://docs.docker.com/storage/volumes/

      【讨论】:

      • 我不喜欢答案中提到的所有 NFS 解决方案。它将产生单点故障。要么使用分布式文件系统,如 GlusterFS,要么只是尝试摆脱对分布式卷的需求(例如,使用可以支持共享文件的数据库,如 MongoDB 中的 GridFS)。
      • 我喜欢 GridFS 的想法。对我来说,GlusterFS 是一个完整的 Glusterf*,当部署到数字海洋节点时,它会不断断开连接并重置所有内容。大规模单点故障。我查看了 GridFS 并阅读了以下内容:“如果您需要以原子方式更新整个文件的内容,请不要使用 GridFS。”因此,如果您计划更新文件,例如 SSL 证书,则必须有更好的东西......
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-29
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多