将数据卷挂载到Docker并赋予读写权限

5
我希望将主机数据卷挂载到Docker中。但是容器应该对其具有读写权限,同时对数据卷进行的任何更改都不应影响主机中的数据。 我可以想象一种解决方法,即将多个数据卷挂载到单个文件夹中,其中一个是只读的,另一个是可读写的。但是只有这个第二个'-v'在我的命令中有效。
docker run -ti --name build_cent1 -v /codebase/:/code:ro -v /temp:/code:rw centos6:1.0 bash
4个回答

4

只有这个 '-v' 参数在我的命令中有效,

可能是因为两个 -v 参数都尝试将本地文件夹挂载到同一个容器内目标文件夹 /code 上。

   -v /codebase/:/code:ro 
                 ^^^^^
   -v /temp:/code:rw
            ^^^^^   

您可以将这些主机文件夹挂载到/code中的两个单独文件夹中。
例如:
-v /codebase/:/code/base:ro -v /temp:/code/temp:rw.

是的,我想要的是在单个容器路径中读写数据。但不要破坏主机文件夹中的数据。 - Xiaokun
@Xiaokun 我的意思是:你不能将两个不同的文件夹挂载到同一个目标文件夹中:只有最后一个指令会生效。你能否在/code文件夹内创建两个单独的文件夹进行挂载呢?比如使用 -v /codebase/:/code/base:ro -v /temp:/code/temp:rw - VonC
不行。因为我想在Docker容器中隔离数据(主机文件夹)。需要在此文件夹中进行操作(读写),而不影响主机文件夹。并且不能将其放入一个特定的文件夹中(我无法直接编写它)。 - Xiaokun
我知道 AUFS 可以做到这一点。它可以将多个文件夹挂载到一个文件夹,并授予不同的权限。然后,它可以确保某些源文件夹不会受到损坏。http://www.thegeekstuff.com/2013/05/linux-aufs/ - Xiaokun
@Xiaokun 至少你知道为什么你当前的命令不起作用了。 - VonC

2

通常情况下,我认为您需要将文件夹添加到Docker镜像中,这样运行它的任何容器都会在其(可写)文件系统中拥有该文件夹,但写操作将进入不同的层。

您需要在要使用的文件夹上面的文件夹中编写一个Dockerfile,如下所示:

FROM my/image
ADD codebase /codebase

然后,您可以使用 docker build -t some-name <path> 命令构建容器。 这些步骤可以添加到应用程序的构建脚本中(也许您会发现一些插件能够帮助您)。 然后您可以运行 docker run some-name
缺点是需要进行一次拷贝和镜像创建,但如果启动多个容器,则它们将共享只读层的相同副本,并在其上写入自己的修改到独立的层中。

1
谢谢你的回答。你能帮忙解释一下缺点吗?是复制过程、镜像创建过程还是容器启动过程? - Xiaokun
另外一件事是,这种方式不能轻松更新共享文件夹内容。我必须始终创建图像。 - Xiaokun
复制步骤必须在图像创建时进行,然后成为代码库构建过程的一个重要组成部分。要传播更改,您必须保存文件、构建图像、重新启动容器... 这不适合快速测试,但在您当前的限制条件下,没有更好的选择。 - Andrea Ratto

2
github中得到了nixun的一个答案。

您可以简单地使用overlayfs来修复这个问题:

mount -t overlay overlay \
    -olowerdir=/codebase,upperdir=/temp,workdir=/workdir /codebase_new
docker run -ti --name build_cent1 -v /codebase_new:/code:rw centos6:1.0 bash

这个解决方案具有很好的灵活性。使用共享文件夹创建图像可能是一种解决方案,但它不能轻松更新文件夹数据。

2

这篇回答不是给Docker用户的,但它会帮助任何使用 Lima 管理容器的人。

我曾经卡在解决 limactllima nerdctl 问题上。我认为值得分享解决方法,以便帮助社区中使用 Lima 而不是 Docker 的人:

默认情况下,Lima 将卷挂载为只读。要使它们默认可写,请执行以下操作:

编辑文件并在 mount 部分下设置 write: true

$ vim ~/.lima/default/lima.yaml

然后重新启动 Lima。

limactl list #this lists all running vms 
limactl stop default #or name of the machine 
limactl start default #or name of the machine 

你仍然需要像使用docker一样精确指定挂载选项。

    lima nerdctl run -ti --name build_cent1 \
    -v /codebase/:/code/base:ro \
    -v /temp:/code/temp:rw \
    centos6:1.0 bash

如需了解有关Lima的更多信息,请查看this


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