详解Docker目录挂载的方法总结

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/b53164cb1c9f1917788638692fb22ad11994cf1fbbc2461b6c390cd3e10ea301
total 0
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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • docker基础知识之挂载本地目录的方法

    Docker可以支持把一个宿主机上的目录挂载到镜像里. 复制代码 代码如下: docker run -it -v /home/dock/Downloads:/usr/Downloads ubuntu64 /bin/bash 通过-v参数,冒号前为宿主机目录,必须为绝对路径,冒号后为镜像内挂载的路径. 现在镜像内就可以共享宿主机里的文件了. 默认挂载的路径权限为读写.如果指定为只读可以用:ro 复制代码 代码如下: docker run -it -v /home/dock/Downloads:/u

  • 详解Docker挂载本地目录

    docker可以支持把一个宿主机上的目录挂载到镜像里. docker run -it -v /home/dock/Downloads:/usr/Downloads ubuntu64 /bin/bash 通过-v参数,冒号前为宿主机目录,必须为绝对路径,冒号后为镜像内挂载的路径. 现在镜像内就可以共享宿主机里的文件了. 默认挂载的路径权限为读写.如果指定为只读可以用:ro docker run -it -v /home/dock/Downloads:/usr/Downloads:ro ubuntu

  • 详解Docker目录挂载的方法总结

    Docker容器启动的时候,如果要挂载宿主机的一个目录,可以用-v参数指定. 譬如我要启动一个centos容器,宿主机的/test目录挂载到容器的/soft目录,可通过以下方式指定: # docker run -it -v /test:/soft centos /bin/bash 这样在容器启动后,容器内会自动创建/soft的目录.通过这种方式,我们可以明确一点,即-v参数中,冒号":"前面的目录是宿主机目录,后面的目录是容器内目录. 貌似简单,其实不然,下面我们来验证一下: 一.容器

  • 详解docker nginx 容器启动挂载到本地

    首先nginx容器内部的结构: 进入容器: docker exec -it b511b6049f57 bash 查看容器的结构目录:其实每一个容器就相当于一个独立的系统. root@b511b6049f57:/# ls bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr nginx的结构目录在容器中: 日志位置:/var/log/nginx/ 配置文件位置:/etc/nginx/

  • 详解docker部署SpringBoot及替换jar包的方法

    关于docker的安装和使用,可以看看之前这两篇文章.docker kubernetes dashboard安装部署详细介绍和Docker如何使用link建立容器之间的连接.这篇文章主要介绍如何在docker上部署springboot项目.关于如何创建springboot项目可以看看这篇文章IDEA上面搭建一个SpringBoot的web-mvc项目遇到的问题 本文主要介绍docker部署springboot的三种方式,分别是:入门方式.jar包替换部署的方式和脚本部署方式,一步步来手把手教程.

  • 详解Docker修改容器端口映射的方法

    直接解决方法 具体可参考Stack Overflow链接 docker运行时存在守护程序,所以我们需要停止docker内运行的容器和docker服务.具体可参考官网给出的守护程序解释 docker stop 容器id //CentOS下停止docker服务(Ubuntu类似) sudo systemctl stop docker 使用以下命令找到已创建容器的hostconfig.json和config.v2.json配置文件. find / -name hostconfig.json //或co

  • 详解docker部署Jenkins新手使用教程

    本文通过docker部署Jenkins+Maven+SVN+Tomcat,在基础镜像Jenkins上安装Maven及自带的OpenJDK形成新的镜像,然后通过SVN将项目checkout下来,由Jenkins自带的插件或脚本将Maven生成的war包发送到指定的Tomcat的WebApps目录下,最终启动Tomcat完成自动化部署. 通过docker命令:sudo docker run –d -p 9898:8080 -p 50000:50000 -v /alidata/projects/jen

  • 详解docker容器的层的概念

    今天我们看看容器的层的概念. 上一节中,我们知道了,容器是一个进程,在这个进程的基础上,添加了下面3个部分: 1.启动Linux Namespace的配置实现与物理机的隔离. 2.设置Cgroups参数限制容器的资源. 3.生成系统文件目录,也就是rootfs文件,也叫镜像文件 这里需要备注的是:rootfs只是容器需要使用的基本文件的组合,并不包括操作系统内核,容器的操作系统内核依旧是使用宿主机的内核.当然,rootfs的存在,并不是没有意义,它的存在,使得容器拥有了一个最主要的性能:一致性.

  • 详解Docker在哪里保存日志文件

    目录 日志存储在哪里? 从容器内的应用程序查看日志 查看 Docker 守护进程日志 调试大多数 Linux 程序通常涉及检查日志文件,这可能是一个复杂的过程.但是,在 Docker 下的容器化环境中运行时,您需要使用更具体的工具来调试生产中的应用程序. 日志存储在哪里? 简单的答案是 Docker 将容器日志存储在其主要存储位置/var/lib/docker/. 每个容器都有一个特定于其 ID 的日志(完整 ID,而不是通常显示的缩短的 ID),您可以像这样访问它: /var/lib/dock

  • 详解Docker Compose配置文件参数

    目录 1. image 2. build 3. command 4.container_name 5.depends_on 6.dns 7. tmpfs 8. entrypoint 9.env_file 10. environment 11. expose 12. external_links 13. extra_hosts 14. labels 15. links 16. logging 17. pid 18. ports 19. security_opt 20. stop_signal 21

  • 详解Docker使用Linux iptables 和 Interfaces管理容器网络

    我使用docker至今已有一段时间了,与绝大部分的人一样,我被docker强大的功能和易用性深深的折服.简单方便是docker的核心之一,它强大的功能被抽象成了非常简单的命令.当我在使用和学习docker的时候,我很想知道docker在后台都做了一些什么事情,特别是在网络这一块(我最感兴趣的一块) 我找到了很多关于创建和操作容器网络的文档,但是关于docker如何使网络工作的却没有那么多. Docker广泛使用linux iptables和网桥接口,这篇文章是我如何用于创建容器网络的总结,大部分

  • 详解Docker镜像与容器的常见操作

    镜像加速器 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器.国内很多云服务商都提供了国内加速器服务,例如: 网易云加速器 https://hub-mirror.c.163.com 阿里云加速器(需登录账号获取): https://cr.console.aliyun.com/cn-hangzhou/mirrors 国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务,具体请参考官方文档. 在CentOS7系统

随机推荐