linux 为什么Docker容器提示“权限被拒绝”?

yvgpqqbh  于 2022-12-03  发布在  Linux
关注(0)|答案(5)|浏览(472)

我使用以下命令运行一个Docker容器,并将一个目录从主机(/root/database)Map到容器(/tmp/install/database):

# docker run -it --name oracle_install -v /root/database:/tmp/install/database bofm/oracle12c:preinstall bash

但是在container中,我发现我不能使用ls来列出/tmp/install/database/中的内容,尽管我是root并且拥有所有权限:

[root@77eb235aceac /]# cd /tmp/install/database/
[root@77eb235aceac database]# ls
ls: cannot open directory .: Permission denied
[root@77eb235aceac database]# id
uid=0(root) gid=0(root) groups=0(root)
[root@77eb235aceac database]# cd ..
[root@77eb235aceac install]# ls -alt
......
drwxr-xr-x. 7 root root  4096 Jul  7  2014 database

我在主机中检查了/root/database,一切看起来都正常:

[root@localhost ~]# ls -lt
......
drwxr-xr-x.  7 root root       4096 Jul  7  2014 database

为什么Docker容器提示“权限被拒绝”?

更新

根本原因与SELinux有关,实际上,我去年遇到过类似的issue

ax6ht2ek

ax6ht2ek1#

在容器内拒绝共享目录的权限可能是因为此共享目录存储在设备上。默认情况下,容器无法访问任何设备。添加选项$docker run --privileged允许容器访问所有设备并执行内核调用。这被认为是不安全的。
共享设备的一种更简洁的方法是使用选项docker run --device=/dev/sdb(如果/dev/sdb是您要共享的设备)。
在手册页中:

--device=[]
      Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm)

  --privileged=true|false
      Give extended privileges to this container. The default is false.

      By default, Docker containers are “unprivileged” (=false) and cannot, for example, run a Docker daemon inside the Docker container. This is because by default  a  container is not allowed to access any devices. A “privileged” container is given access to all devices.

      When  the  operator  executes  docker run --privileged, Docker will enable access to all devices on the host as well as set some configuration in AppArmor to allow the container nearly all the same access to the host as processes running outside of a container on the host.
qnyhuwrf

qnyhuwrf2#

我在使用docker-compose共享一个nfs挂载点作为一个卷时遇到了类似的问题。我可以通过以下方法解决这个问题:

docker-compose up --force-recreate

即使您发现了问题,这也可能对其他人有所帮助。

jm81lzqq

jm81lzqq3#

另一个原因是UID/GID不匹配。
您可以设置UID,因此对于作为ubuntu运行的ubuntu容器,您可能需要附加:uid=1000(检查id -u)或根据您的用例在本地设置UID。
uid=值和gid=值
设置文件系统中文件的所有者和组(默认值:uid=gid=0)
这里有一个很好的关于它的博客,里面有这个tmpfs的例子

docker run \
       --rm \
       --read-only \
       --tmpfs=/var/run/prosody:uid=100 \
       -it learning/tmpfs

http://www.dendeer.com/post/docker-tmpfs/

c3frrgcw

c3frrgcw4#

我从下面的评论中得到了回答:Why does docker container prompt Permission denied?
man docker-run给出了正确的答案:
标记系统(如SELinux)要求在装入容器的卷内容上放置正确的标签。如果没有标签,安全系统可能会阻止容器内运行的进程使用内容。默认情况下,Docker不会更改操作系统设置的标签。
要更改容器上下文中的标签,您可以将两个后缀之一添加到卷装载中:z或:Z。这些后缀告诉Docker重新标记共享卷上的文件对象。z选项告诉Docker两个容器共享卷内容。因此,Docker使用共享内容标签标记内容。共享卷标签允许所有容器读取/写入内容。Z选项告诉Docker使用专用非共享标签标记内容。只有当前容器可以使用专用卷。
例如:

docker run -it --name oracle_install -v /root/database:/tmp/install/database:z ...
x0fgdtte

x0fgdtte5#

因此,我试图在容器中使用Python操作系统运行一个C文件,但我得到了同样的错误,我的修复是在创建图像时添加此行RUN chmod -R 777 app,它对我有效

相关问题