dockerrun-v详解
下列复制⾃上⾯博⽂,只为⾃⼰⽇后查⽅便:
Docker容器启动的时候,如果要挂载宿主机的⼀个⽬录,可以⽤-v参数指定。
譬如我要启动⼀个centos容器,宿主机的/test⽬录挂载到容器的/soft⽬录,可通过以下⽅式指定:
# docker run -it -v /test:/soft centos /bin/bash
这样在容器启动后,容器内会⾃动创建/soft的⽬录。通过这种⽅式,我们可以明确⼀点,即-v参数中,冒号":"前⾯的⽬录是宿主机⽬录,后⾯的⽬录是容器内⽬录。
貌似简单,其实不然,下⾯我们来验证⼀下:
⼀、容器⽬录不可以为相对路径
[root@localhost ~]# docker run -it -v /test:soft centos /bin/bash
invalid value "/test:soft" for flag -v: soft is not an absolute path
See 'docker run --help'.
直接报错,提⽰soft不是⼀个绝对路径,所谓的绝对路径,必须以下斜线“/”开头。
⼆、宿主机⽬录如果不存在,则会⾃动⽣成
如果宿主机中存在/test⽬录,⾸先删除它
[root@localhost ~]# rm -rf /test
[root@localhost ~]# ls /
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
启动容器
[root@localhost ~]# docker run -it -v /test:/soft centos /bin/bash
[root@a487a3ca7997 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  soft  srv  sys  tmp  usr  var
查看宿主机,发现新增了⼀个/test⽬录
[root@localhost ~]# ls /
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  test  tmp  usr  var
三、宿主机的⽬录如果为相对路径呢?
这次,我们换个⽬录名test1试试
# docker run -it -v test1:/soft centos /bin/bash
再到宿主机上查看是否新增了⼀个/test1⽬录,结果没有,是不是因为我⽤的是相对路径,所以⽣成的test1⽬录在当前⽬录下,结果发现还是没有。那容器内的/soft⽬录挂载到哪⾥去了?通过docker inspect命令,查看容器“Mounts”那⼀部分,我们可以得到这个问题的答案。
"Mounts": [
{
"Name": "test1",
"Source": "/var/lib/docker/volumes/test1/_data",
"Destination": "/soft",
"Driver": "local",
"Mode": "z",
"RW": true
}
],
可以看出,容器内的/soft⽬录挂载的是宿主机上的/var/lib/docker/volumes/test1/_data⽬录
原来,所谓的相对路径指的是/var/lib/docker/volumes/,与宿主机的当前⽬录⽆关。
四、如果只是-v指定⼀个⽬录,这个⼜是如何对应呢?
启动⼀个容器
[root@localhost ~]# docker run -it -v /test2 centos /bin/bash
[root@ea24067bc902 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  test2  tmp  usr  var
同样使⽤docker inspect命令查看宿主机的挂载⽬录
"Mounts": [
{
"Name": "96256232eb74edb139d652746f0fe426e57fbacdf73376963e3acdb411b3d73a",
"Source": "/var/lib/docker/volumes/96256232eb74edb139d652746f0fe426e57fbacdf73376963e3acdb411b3d73a/_data",            "Destination": "/test2",
"Driver": "local",
"Mode": "",
"RW": true
}
],
可以看出,同3中的结果类似,只不过,它不是相对路径的⽬录名,⽽是随机⽣成的⼀个⽬录名。
五、如果在容器内修改了⽬录的属主和属组,那么对应的挂载点是否会修改呢?
⾸先开启⼀个容器,查看容器内/soft⽬录的属性
[root@localhost ~]# docker run -it -v /test:/soft centos /bin/bash
[root@b5ed8216401f /]# ll -d /soft/
drwxr-xr-x 2 root root 6 Sep 24 03:48 /soft/
查看宿主机内/test⽬录的属性
[root@localhost ~]# ll -d /test/
drwxr-xr-x 2 root root 6 Sep 24 11:48 /test/
在容器内新建⽤户,修改/soft的属主和属组
[root@b5ed8216401f /]# useradd victor
[root@b5ed8216401f /]# chown -R victor.victor /soft/
[root@b5ed8216401f /]# ll -d /soft/
drwxr-xr-x 2 victor victor 6 Sep 24 03:48 /soft/
再来看看宿主机内/test⽬录的属主和属组是否会发⽣变化?
[root@localhost ~]# ll -d /test/
drwxr-xr-x 2 mycat mycat 6 Sep 24 11:48 /test/
竟然变为mycat了。。。
原来,这个与UID有关系,UID,即“⽤户标识号”,是⼀个整数,系统内部⽤它来标识⽤户。⼀般情况下它与⽤户名是⼀⼀对应的。
⾸先查看容器内victor对应的UID是多少,
[root@b5ed8216401f /]# cat /etc/passwd | grep victor
victor:x:1000:1000::/home/victor:/bin/bash
victor的UID为1000,那么宿主机内1000对应的⽤户是谁呢?
[root@localhost ~]# cat /etc/passwd |grep 1000
mycat:x:1000:1000::/home/mycat:/bin/bash
可以看出,宿主机内UID 1000对应的⽤户是mycat。
六、容器销毁了,在宿主机上新建的挂载⽬录是否会消失?
在这⾥,主要验证两种情况:⼀、指定了宿主机⽬录,即 -v /test:/soft。⼆、没有指定宿主机⽬录,即-v /soft
第⼀种情况:
[root@localhost ~]# rm -rf /test    --⾸先删除宿主机的/test⽬录
[root@localhost ~]# ls /    --可以看到,宿主机上⽆/test⽬录
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@localhost ~]# docker run -it --name=centos_test -v /test:/soft centos /bin/bash  --启动容器,为了删除⽅便,我⽤--name参数指定了容器的名字[root@82ad7f3a779a /]# exit
exit
[root@localhost ~]# docker rm centos_test  --删除容器
centos_test
[root@localhost ~]# ls /  --发现 /test⽬录依旧存在
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  test  tmp  usr  var
可以看出,即便容器销毁了,新建的挂载⽬录不会消失。进⼀步也可验证,如果宿主机⽬录的属主和属组发⽣了变化,容器销毁后,宿主机⽬录的属主和属组不会恢复到挂载之前的状态。
第⼆种情况,通过上⾯的验证知道,如果没有指定宿主机的⽬录,则容器会在/var/lib/docker/volumes/
随机配置⼀个⽬录,那么我们看看这种情况下的容器销毁是否会导致相应⽬录的删除
⾸先启动容器
[root@localhost ~]# docker run -it --name=centos_test -v /soft centos /bin/bash
[root@6b75579ec934 /]# exit
exit
通过docker inspect命令查看容器在宿主机上⽣成的挂载⽬录
"Mounts": [
{
"Name": "b53164cb1c9f1917788638692fb22ad11994cf1fbbc2461b6c390cd3e10ea301",
"Source": "/var/lib/docker/volumes/b53164cb1c9f1917788638692fb22ad11994cf1fbbc2461b6c390cd3e10ea301/_data",
"Destination": "/soft",
"Driver": "local",
"Mode": "",
"RW": true
}
],
对应的是/var/lib/docker/volumes/b53164cb1c9f1917788638692fb22ad11994cf1fbbc2461b6c390cd3e10ea301/_data ⽬录
销毁容器,看⽬录是否存在
[root@localhost ~]# docker rm centos_test
centos_test
[root@localhost ~]# ll /var/lib/docker/volumes/b53164cb1c9f1917788638692fb22ad11994cf1fbbc246
1b6c390cd3e10ea301
total 0
docker重启容器命令
drwxr-xr-x 2 root root 6 Sep 24 14:25 _data
发现该⽬录依旧存在,即便重启了docker服务,该⽬录依旧存在
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# ll /var/lib/docker/volumes/b53164cb1c9f1917788638692fb22ad11994cf1fbbc2461b6c390cd3e10ea301
total 0
drwxr-xr-x 2 root root 6 Sep 24 14:25 _data
七、挂载宿主机已存在⽬录后,在容器内对其进⾏操作,报“Permission denied”。
可通过两种⽅式解决:
1> 关闭selinux。
临时关闭:# setenforce 0
永久关闭:修改/etc/sysconfig/selinux⽂件,将SELINUX的值设置为disabled。
2> 以特权⽅式启动容器
指定--privileged参数
如:# docker run -it --privileged=true -v /test:/soft centos /bin/bash
⼋、docker -v需要挂在⼩层级⽬录,⼤⽬录可能会报错

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。