我试图在Docker中挂载一个主机目录,但然后我不能从容器中访问它,即使访问权限看起来不错。

我正在做

sudo docker run -i -v /data1/Downloads:/Downloads ubuntu bash

然后

ls -al

它给我:

total 8892
drwxr-xr-x.  23 root root    4096 Jun 18 14:34 .
drwxr-xr-x.  23 root root    4096 Jun 18 14:34 ..
-rwxr-xr-x.   1 root root       0 Jun 18 14:34 .dockerenv
-rwx------.   1 root root 9014486 Jun 17 22:09 .dockerinit
drwxrwxr-x.  18 1000 1000   12288 Jun 16 11:40 Downloads
drwxr-xr-x.   2 root root    4096 Jan 29 18:10 bin
drwxr-xr-x.   2 root root    4096 Apr 19  2012 boot
drwxr-xr-x.   4 root root     340 Jun 18 14:34 dev
drwxr-xr-x.  56 root root    4096 Jun 18 14:34 etc
drwxr-xr-x.   2 root root    4096 Apr 19  2012 home

还有很多这样的台词(我认为这是相关的部分)。

如果我这样做

cd /Downloads
ls

结果是

ls: cannot open directory .: Permission denied

主机版本为Fedora 20, Docker 1.0.0, go1.2.2。

哪里出了问题?


当前回答

关于Volumes和SELinux的完整故事,请参阅Project Atomic的博客文章。

具体地说:

This got easier recently since Docker finally merged a patch which will be showing up in docker-1.7 (We have been carrying the patch in docker-1.6 on RHEL, CentOS, and Fedora). This patch adds support for "z" and "Z" as options on the volume mounts (-v). For example: docker run -v /var/db:/var/db:z rhel7 /bin/sh Will automatically do the chcon -Rt svirt_sandbox_file_t /var/db described in the man page. Even better, you can use Z. docker run -v /var/db:/var/db:Z rhel7 /bin/sh This will label the content inside the container with the exact MCS label that the container will run with, basically it runs chcon -Rt svirt_sandbox_file_t -l s0:c1,c2 /var/db where s0:c1,c2 differs for each container.

其他回答

我也遇到过类似的问题。我的错误是由于主机的UID和容器用户的UID不匹配造成的。解决方法是将用户的UID作为参数传递给docker build命令,并使用相同的UID创建容器的用户。

在DockerFile中:

ARG UID=1000
ENV USER="ubuntu"
RUN useradd -u $UID -ms /bin/bash $USER

在构建步骤中:

docker build <path/to/Dockerfile> -t <tag/name> --build-arg UID=$UID

在那之后,根据OP运行容器和命令给了我预期的结果。

尝试docker卷创建。

mkdir -p /data1/Downloads
docker volume create --driver local --name hello --opt type=none --opt device=/data1/Downloads --opt o=uid=root,gid=root --opt o=bind
docker run -i -v hello:/Downloads ubuntu bash

看一下创建的文档docker卷。

我通过使用数据容器解决了这个问题。这还具有将数据与应用层隔离的优点。你可以这样运行:

docker run --volumes-from=<container-data-name> ubuntu

本教程很好地解释了数据容器的使用。

关于Volumes和SELinux的完整故事,请参阅Project Atomic的博客文章。

具体地说:

This got easier recently since Docker finally merged a patch which will be showing up in docker-1.7 (We have been carrying the patch in docker-1.6 on RHEL, CentOS, and Fedora). This patch adds support for "z" and "Z" as options on the volume mounts (-v). For example: docker run -v /var/db:/var/db:z rhel7 /bin/sh Will automatically do the chcon -Rt svirt_sandbox_file_t /var/db described in the man page. Even better, you can use Z. docker run -v /var/db:/var/db:Z rhel7 /bin/sh This will label the content inside the container with the exact MCS label that the container will run with, basically it runs chcon -Rt svirt_sandbox_file_t -l s0:c1,c2 /var/db where s0:c1,c2 differs for each container.

在我的情况下,问题就不同了。我不知道为什么,但是即使主机上的一个目录上运行了chmod 777,在Docker容器中它仍然是可见的755。

在容器内部运行sudo chmod 777 my_volume_dir修复了它。