如何在Docker for Windows (Windows 10)中挂载网络卷

22
我们正在努力创建一个标准的“数据科学” Docker 映像,以帮助我们的团队维护统一的开发环境。为了使它对我们有用,容器需要具有读写访问我们公司网络的权限。如何将网络驱动器挂载到 Docker 容器中?
以下是我使用 Docker Hub 上的 rocker/rstudio 映像尝试过的方法:
这个可以工作: docker run -d -p 8787:8787 -v //c/users/{insert user}:/home/rstudio/foobar rocker/rstudio 这个不行(其中 P 是网络驱动器映射的位置): docker run -d -p 8787:8787 -v //p:/home/rstudio/foobar rocker/rstudio 这个也不行: docker run -d -p 8787:8787 -v //10.1.11.###/projects:/home/rstudio/foobar rocker/rstudio 有什么建议吗?
我对 Docker 还比较新手,请让我知道如果我表述不够清楚。

你尝试过将远程驱动器挂载到本地目录吗?然后你可以在docker run命令中使用本地目录。 - Dave C
谢谢!你能帮我理解这与将网络卷映射到“本地”驱动器有何不同吗?在上面的例子中,网络驱动器是P:,但Docker无法识别它。 - KingOfTheNerds
1
没什么区别,只是我在你的问题中错过了那一部分。从进一步阅读中我可以发现,Docker 不支持映射驱动器。 - Dave C
谢谢 - 那就是我到达的地方。希望有人能找到解决方案。 - KingOfTheNerds
2
这里是一个快速的更新,针对那些正在查看此内容的人。据我们所知,这实际上是不可能的。因此,我们已经通过Linux机器部署了我们的容器以解决问题。 - KingOfTheNerds
5个回答

6

我会写下我的决定。我有一个群晖NAS。共享文件夹使用SMB协议。 我成功地以以下方式连接它。最重要的是要写版本1.0(vers=1.0)。如果没有它,它就无法工作!我试着解决这个问题2天。

version: "3"

services:
  redis:
    image: redis
    restart: always
    container_name: 'redis'
    command: redis-server
    ports:
      - '6379:6379'
    environment:
      TZ: "Europe/Moscow"

  celery:
    build:
      context: .
      dockerfile: celery.dockerfile
    container_name: 'celery'
    command: celery --broker redis://redis:6379 --result-backend redis://redis:6379 --app worker.celery_worker   worker --loglevel info
    privileged: true
    environment:
      TZ: "Europe/Moscow"
    volumes:
      - .:/code
      - nas:/mnt/nas
    links:
      - redis
    depends_on:
      - redis

volumes:
  nas:
    driver: local
    driver_opts:
      type: cifs
      o: username=user,password=pass,**vers=1.0**
      device: "//192.168.10.10/main"

5

我知道这篇文章比较旧,但是为了其他人的需要,以下是通常适用于我的解决方法。我们使用的是Windows文件服务器,所以我们使用cifs-utils来映射驱动器。我认为下面的指令也可以应用于nfs或其他任何内容。

首先,需要在特权模式下运行容器,以便您可以将远程文件夹挂载到容器内(--dns标志可能不是必需的):
docker run --dns <company dns ip> -p 8000:80 --privileged -it <container name and tag>

现在,假设在容器中使用centos并且拥有cifs和root权限 - 进入容器并运行:

如果尚未安装,请安装cifs-utils
yum -y install cifs-utils

创建要映射的本地目录
mkdir /mnt/my-mounted-folder

准备一个包含用户名和密码的文件
echo "username=<username-with-access-to-shared-drive>" > ~/.smbcredentials
echo "password=<password>" > ~/.smbcredentials

映射远程文件夹
mount <remote-shared-folder> <my-local-mounted-folder> -t cifs -o iocharset=utf8,credentials=/root/.smbcredentials,file_mode=0777,dir_mode=0777,uid=1000,gid=1000,cache=strict

现在您应该可以访问远程文件夹了。

希望这有所帮助..


还有其他人可以证实这个解决方案的成功吗? - lightbox142
是的,它可以工作,但我必须将我的用户名设置为username=user@domain.com - stephen meckstroth
2
很明显问题是如何在Windows中挂载而不是Linux。这个回答怎么会冒到最前面呢? - rantlr
@rantlr 因为 Linux 命令应该在容器内运行。 - Patrick Bard

4

我最近几天一直在寻找解决方案,最终找到了一个可行的方法。

我正在运行一个docker容器在一个ubuntu虚拟机上,并映射同一网络中运行windows 10的另一台主机上的文件夹。我几乎可以肯定容器所在的操作系统不是问题,因为映射是从容器本身进行的,所以我认为这个解决方案应该适用于任何操作系统。

让我们开始编码吧。

首先,您应该创建卷

docker volume create 
--driver local 
--opt type=cifs 
--opt device=//<network-device-ip-folder>
--opt o=user=<your-user>,password=<your-pw>
<volume-name>

然后你需要从镜像中运行一个容器。
 docker run 
 --name <desired-container-name> 
 -v <volume-name>:/<path-inside-container>
 <image-name>

在此之后,容器已运行,并将卷分配给其,映射到中。您可以在其中任何一个文件夹中创建一些文件,它们将自动复制到另一个文件夹中。
如果有人想从docker-compose中运行它,我在此留下。
services:
  <image-name>:
    build: 
      context: .
    container_name: <desired-container-name> 
    volumes:
       -  <volume-name>:/<path-inside-container>
    ...

volumes:
  <volume-name>:
    driver: local
    driver_opts: 
      type: cifs 
      device: //<network-device-ip-folder>
      o: "user=<your-user>,password=<your-pw>"

希望我能帮得上忙。

3
这在 Windows 容器中无法工作。由于操作系统不兼容,守护程序会抛出错误:Error response from daemon: create test_cifs_volume: options are not supported on this platform - jrbe228

0

在@Александр Рублев的解决方案基础上,对我有用的技巧是重新配置Synology NAS以接受docker使用的SMB版本。在我的情况下,我必须启用SMBv3。


您的答案可以通过提供额外的支持信息来改进。请[编辑]以添加更多细节,例如引用或文档,以便其他人可以确认您的答案正确无误。您可以在帮助中心找到有关撰写好答案的更多信息。 - Community
这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - Besworks

0

我知道这个很老了,但是在寻找类似东西的时候我发现它正在接收其他人的评论,就像我一样。

我已经弄清楚如何使其工作

对于一个类似的情况,我花了一段时间才想出来。

这里的答案缺少一些关键信息,我将包括这些信息,可能是因为它们当时不可用。

  1. 我认为CIFS存储仅适用于连接到Windows系统时使用,除非该系统模拟Windows环境,否则Linux根本不使用它。
  2. NFS也可以完成同样的事情,它比较不安全,但几乎被所有设备支持。

您可以以类似于CIFS的方式创建NFS卷,只需进行一些更改即可。 我将列出两者,以便可以并排查看。

在使用 WSL2 上的 NFS 时,您首先需要将 NFS 服务安装到 Linux 主机操作系统中。我相信 CIFS 需要类似的服务,很可能是由 @LevHaikin 提到的 cifs-utils,但我没有使用过,所以不确定。在我的情况下,主机操作系统是 Ubuntu,但您应该能够通过找到您系统的等效项来找到适当的安装程序 nfs-common(或者如果正确的话是 cifs-utils)。

sudo apt update
sudo apt install nfs-common

就这样。这将安装服务,使得NFS在Docker上能够工作(我花了很长时间才意识到这是问题所在,因为似乎没有任何地方提到需要这样做)


如果使用NFS,在网络设备上,您需要为NFS文件夹设置NFS权限,在我的情况下,这将在folder文件夹上完成,然后将其挂载到其中一个文件夹。没问题。(在我的情况下,作为服务器的NAS挂载到#IP#/volume1/folder,在NAS中,我从未在目录结构中看到volume1,但是当我设置NFS权限时,共享文件夹的完整路径显示在设置页面中。我不包括volume1部分,因为您的系统可能会有所不同),并且您想要IP之后的完整路径(使用IP作为数字,而不是HostName),根据您的NFS共享,无论它是什么。
如果使用CIFS设备,则对于CIFS权限也是如此。
  • nolock 选项经常被需要,但可能没有在您的系统上。它只是禁用了“锁定”文件的能力。
  • soft 选项意味着如果系统无法连接到挂载目录,它将不会挂起。如果您需要它仅在挂载存在时才工作,可以改为使用 hard
  • rw(读/写)选项用于读/写ro(只读)选项用于只读

由于我个人不使用 CIFS 卷,所以设置的选项仅为我找到的示例中的选项,你需要进一步研究是否对你有必要。

  • usernamepassword是必需的,且必须包含在CIFS中。
  • uidgid是Linux用户和组设置,应该根据容器需要设置,因为Windows不使用它们(据我所知)。
  • file_mode=0777dir_mode=0777是Linux读/写权限,类似于chmod 0777,给予任何可以访问文件的人读/写/执行权限(更多信息请参见链接#4),这也应该是针对Docker容器而不是CIFS主机的。
  • noexec与执行权限有关,但我认为它在这里实际上没有作用,但大多数我找到的示例都包括它,nosuid限制了它访问特定用户ID的文件的能力,除非您知道需要将其删除,否则不应该删除,因为它是一种保护措施,如果可能的话,我建议留下它,nosetuids表示它不会为新创建的文件设置UID和GUID,nodev表示无法访问/创建挂载点上的设备,vers=1.0我认为是兼容性的后备方案,个人认为除非存在问题或没有它无法正常工作,否则不应包含它。
在这些示例中,我将//NET.WORK.DRIVE.IP/folder/on/addr/device挂载到名为"my-docker-volume"的卷中,并以读/写模式运行。CIFS卷使用用户supercool和密码noboDyCanGue55

CLI中的NFS

docker volume create --driver local --opt type=nfs --opt o=addr=NET.WORK.DRIVE.IP,nolock,rw,soft --opt device=:/folder/on/addr/device my-docker-volume

CIFS从CLI连接(如果Docker安装在Windows以外的系统上,则可能无法工作,仅能连接到Windows系统上的IP)

docker volume create --driver local --opt type=cifs --opt o=user=supercool,password=noboDyCanGue55,rw --opt device=//NET.WORK.DRIVE.IP/folder/on/addr/device my-docker-volume

这也可以在Docker Compose或Portainer中完成。

当您在那里执行时,您需要在compose文件底部添加一个Volumes:,没有缩进,在与services:相同的级别上。

在此示例中,我正在挂载卷

  • my-nfs-volume//10.11.12.13/folder/on/NFS/device挂载到“my-nfs-volume”,以读/写模式挂载到容器中的/nfs
  • my-cifs-volume//10.11.12.14/folder/on/CIFS/device挂载到“my-cifs-volume”,使用用户supercool和密码noboDyCanGue55的权限以读/写模式挂载到容器中的/cifs
version: '3'
services:
  great-container:
    image: imso/awesome/youknow:latest
    container_name: totally_awesome
    environment:
      - PUID=1000
      - PGID=1000
    ports:
      - 1234:5432
    volumes:
      - my-nfs-volume:/nfs
      - my-cifs-volume:/cifs

volumes:
  my-nfs-volume:
   name: my-nfs-volume
   driver_opts:
      type: "nfs"
      o: "addr=10.11.12.13,nolock,rw,soft"
      device: ":/folder/on/NFS/device"
  my-cifs-volume:
    driver_opts:
      type: "cifs"
      o: "username=supercool,password=noboDyCanGue55,uid=1000,gid=1000,file_mode=0777,dir_mode=0777,noexec,nosuid,nosetuids,nodev,vers=1.0"
      device: "//10.11.12.14/folder/on/CIFS/device/"

更多细节可以在这里找到:

  1. https://docs.docker.com/engine/reference/commandline/volume_create/
  2. https://www.thegeekdiary.com/common-nfs-mount-options-in-linux/
  3. https://web.mit.edu/rhel-doc/5/RHEL-5-manual/Deployment_Guide-en-US/s1-nfs-client-config-options.html
  4. https://www.maketecheasier.com/file-permissions-what-does-chmod-777-means/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接