完美解决 Docker使用-v挂载主机目录到容器后出现Permission denied的问题 ls: cannot open directory ‘文件或目录’: Permission denied 官方解决办法

本文章为本站原创文章,转载请注明出处!

这是在学习docker数据管理的时候遇到的一个问题 首先我的环境是VMware Workstation 15 Player下安装的虚拟机 centos 7 64位
[root@calmsmile ~]# uname -a
Linux calmsmile.org 3.10.0-957.21.2.el7.x86_64 #1 SMP Wed Jun 5 14:26:44 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
我要挂载 /root/docker-share目录到容器下的/docker-share
首先创建一个docker-share目录,并创建一个文件 随意啊 这里只是举例操作
[root@calmsmile ~]# pwd
/root
[root@calmsmile ~]# mkdir docker-share
[root@calmsmile ~]# cd docker-share
[root@calmsmile ~]# echo hello-world > file
[root@calmsmile ~]# ls
file
[root@calmsmile ~]# cat file
hello-world
[root@calmsmile ~]# 
创建好目录和文件我们接下来 将这个目录映射到容器当中去


<题外话:
截止目前我还不知道如何在已创建好的容器内挂载外部的目录,有朋友会的 留言教下我 谢谢!
这里顺带说一下docker run 这个run 是创建一个容器,如果拿docker比作VMware虚拟机的话,每run一次 相当于新创建了一个虚拟机,就好像新装了一个系统一样,每run一次又创建了一个新的容器,那我之前的容器怎么办?报废了吗?不要了吗? 所以我还是比较讨厌平凡使用run 来加各种参数去新建一个容器而不是在已有的容器下去操作,run一般只用一次,在创建好的容器内搞开发,在打包成镜像就完事了,就像前面说的,有谁会在已创建好的容器内挂载外部的目录,有朋友会的 留言教下我 谢谢!
>
进入主题:
下面这个操作会出现标题里描述的问题 容器内ls挂载的文件夹会提示 拒绝访问 
[root@calmsmile ~]# docker run --name docker-share -v $(pwd)/docker-share:/docker-share -it docker.io/centos:latest /bin/bash
[root@8ec2ca60eea8 /]# ls /docker-share
ls: cannot open directory /docker-share/: Permission denied
[root@8ec2ca60eea8 /]# 
解释一个上面的命令:
--name docker-share     这个参数加不加都行 指定等会创建的容器的名字 如果不指定系统会随机生成一个 我看着别人的教程加我也跟着加
效果:
----------------------------------------------------------------------------
[root@calmsmile ~]# docker ps
CONTAINER ID        IMAGE                     COMMAND             CREATED             
8ec2ca60eea8        docker.io/centos:latest   "/bin/bash"         About an hour ago   
STATUS              PORTS               NAMES
Up About an hour                        docker-share 这个名字就是刚才我们指定的
[root@calmsmile ~]# 
----------------------------------------------------------------------------

挂载宿主机/root/docker-share目录到容器/docker-share目录的参数 -v的语法:
-v 宿主机目录路径(注意必须是绝对路径) 冒号 容器内的目录路径 冒号(rw ro z Z) 参数
-v /root/docker-share:/docker-share 
   注:宿主机目录必须提前创建好, 容器的目录就不用,会自己创建,有点像linux的软链接。

-it 这个-it的i是以交互的方式,那个交互的英文单词的缩写,这个t字母我不知道是tty的缩写还是terminal的缩写 两个都差不意思将就的理解吧 后面跟镜像名和标签 和 一个命令(我不知道/bin/bash 算不算是一个命令 哦对了 加上后会直接进入到容器内的bash 不然前面的-it就白写了)
 就像上面写的 -it docker.io/centos:latest /bin/bash
 docker.io是因为的镜像是直接从dockerhub上下载的 
下面这个方法是其中一种可以解决上面遇到的ls拒绝访问的问题
[root@calmsmile ~]# docker run --name docker-share -v $(pwd)/docker-share:/docker-share:z -it docker.io/centos:latest /bin/bash
[root@c8e114a6b718 /]# ls /docker-share/
file
[root@c8e114a6b718 /]# cat file
hello-world
[root@c8e114a6b718 /]# 
必须再次解释一下 -v 参数:
-v $(pwd)/docker-share:/docker-share:z
-v 后面的参数:
    z   小写字母z 表示所有的其他的容器都可以读写挂载到当前容器的/docker-share数据卷
    Z   大写字母Z 表示只有当前容器自己本身可以读写当前容器的/docker-share数据卷
    rw 表示读写
    ro 表示只读
注意!注意!注意!大家注意啦!下面这个方法才是最正确的方法!推荐使用这个方法!!!
OK 下面这个方法是 man docker run 帮助文档里面给出的解决办法,也是最正确的解决办法,因为是官方自己给出的,所以大家不用怀疑!我这边把帮助文档原文发出来 大家自己看下 就应该明白怎么操作了
Mounting External Volumes
       To mount a host directory as a container volume, specify the absolute path to the directory and the  absolute  path  for
       the container directory separated by a colon:

              # docker run -v /var/db:/data1 -i -t fedora bash

       When  using  SELinux, be aware that the host has no knowledge of container SELinux policy. Therefore, in the above exam‐
       ple, if SELinux policy is enforced, the /var/db directory is not writable to the container. A "Permission  Denied"  mes‐
       sage will occur and an avc: message in the host's syslog.

       To  work  around  this,  at time of writing this man page, the following command needs to be run in order for the proper
       SELinux policy type label to be attached to the host directory:

              # chcon -Rt svirt_sandbox_file_t /var/db

       Now, writing to the /data1 volume in the container will be allowed and the changes will also be reflected on the host in
       /var/db.

也就是将我们宿主机的需要挂载到容器的目录 执行一下chcon那行命令 例如我们前面举例的是/root/docker-share目录 我们可以这样写 下面完整的操作一遍:
[root@calmsmile ~]#docker run --name=test-pd -v /root/docker-share:/docker-share -it docker.io/centos:latest /bin/bash
[root@d1903346e2dc /]# ls /docker-share/
ls: cannot open directory /docker-share/: Permission denied
[root@d1903346e2dc /]# exit
exit
[root@calmsmile ~]# chcon -Rt svirt_sandbox_file_t /root/docker-share
[root@calmsmile ~]# docker exec -it test-pd /bin/bash
[root@d1903346e2dc /]# ls /docker-share
file
[root@d1903346e2dc /]# touch docker-share/aaa
[root@d1903346e2dc /]# ls docker-share/
aaa file
[root@d1903346e2dc /]# 

OK 按照上面操作一遍 就可以完美解决Docker使用-v挂载主机目录到容器后出现Permission denied的问题
推荐使用这个方法啊! 因为这是官方给出的解决方法! 

下面这个链接解释了本篇文章所遇到问题的另外两种解决办法(不过我没有试过) 大家可以去看下:
https://nanxiao.me/en/selinux-cause-permission-denied-issue-in-using-docker/
下面这个链接的就是我现在实验的方法之一,是在github上找到的
https://github.com/moby/moby/issues/14175

本文章为本站原创文章,转载请注明出处!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

CAPTCHAis initialing...