docker - 挂载目录

我们可以在创建容器的时候,将宿主机的目录与容器内的目录进行映射,这样我们就可以实现宿主机和容器目录的双向数据自动同步

挂载一个容器

启动容器时挂载一个目录(推荐)

Docker容器启动的时候,如果要挂载宿主机的一个目录,可以用-v参数指定。

譬如我要启动一个centos容器,宿主机的/test目录挂载到容器的/soft目录,可通过以下方式指定:

1
# docker run -it -v /test:/soft centos /bin/bash

这样在容器启动后,容器内会自动创建/soft的目录。通过这种方式,我们可以明确一点,即-v参数中,冒号”:”前面的目录是宿主机目录,后面的目录是容器内目录容器目录不可以是相对目录,必须是绝对目录 )。

默认挂载的目录是可以进行双向同步的,但是有些数据库文件,一般在镜像中我们只会进行数据的读取,可以挂载为只读目录。

1
docker run -it -v  /宿主机目录:/容器目录:ro 镜像名

其中进行目录挂载时的几个执行的逻辑情况如下:

  1. 可以挂载多个目录(-v 参数可以重复使用)

    1
    docker run -it -v /宿主机目录:/容器目录 -v /宿主机目录2:/容器目录2 镜像名
  2. 容器目录不可以是相对目录,必须是绝对目录

  3. 宿主机目录如果不存在,则会自动生成
  4. 宿主机目录如果是相对目录,则会基于/var/lib/docker/volumes/ 生成相对目录,与执行目录无关。(可以通过 docker inspect 查看)
  5. -v挂载时,只指定一个目录,则会在宿主机/var/lib/docker/volumes/下生成一个随机目录名,指定的目录为容器内的目录。
  6. 容器内如果对挂载目录的属主和属组进行了修改,会同步修改宿主对应目录的属主和属组信息,但是更改的是用户的UID,由于容器内和宿主机中UID标识的实际用户一般不一样,因此属主和属组会发生改变,但是用户会存在差异。
  7. 容器销毁后,挂载目录内的更改仍会保留,不会还原。

通过使用数据容器挂载

  • 首先创建一个数据卷
    命令: docker run -v 需挂载目录的路径:容器挂载路径 –name 数据卷名字 容器名字 /bin/bash

    1
    docker run -v /home/dock/Database:/Database --name Database ubuntu64 /bin/bash
  • 再创建一个新的容器,来使用这个数据卷(通过数据卷的名字 Database

    1
    docker run -it --volumes-from Database ubuntu64 /bin/bash

通过dockerfile创建挂载点

上面介绍的通过docker run命令的-v标识创建的挂载点只能对创建的容器有效。

通过dockerfile的 VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点。

还有一个区别是,通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的

容器共享卷(挂载点)

1
docker run --name test1 -it myimage /bin/bash

上面命令中的 myimage是用前面的dockerfile文件构建的镜像。 这样容器test1就有了 /data1 和 /data2两个挂载点。

下面我们创建另一个容器可以和test1共享 /data1 和 /data2卷 ,这是在 docker run中使用 –volumes-from标记,如:

1
2
3
4
5
可以是来源不同镜像,如:
docker run --name test2 -it --volumes-from test1 ubuntu /bin/bash

也可以是同一镜像,如:
docker run --name test3 -it --volumes-from test1 myimage /bin/bash

上面的三个容器 test1 , test2 , test3 均有 /data1 和 /data2 两个目录,且目录中内容是共享的,任何一个容器修改了内容,别的容器都能获取到。

常见异常情况及处理

挂载宿主机目录后,无操作权限

挂载宿主机已存在目录后,在容器内对其进行操作,报“Permission denied”。

解决方式

  1. 关闭selinux。
  • 临时关闭:# setenforce 0
  • 永久关闭:修改/etc/sysconfig/selinux文件,将SELINUX的值设置为disabled。
  1. 以特权方式启动容器
    指定–privileged参数
    如:# docker run -it –privileged=true -v /test:/soft centos /bin/bash
-------------本文结束感谢您的阅读-------------