容器技术使用 rootfs 机制和 Mount Namespace, 构建出一个同宿主机完全隔离开的文件系统环境
那容器里进程新建的文件, 怎么样才能让宿主机获取到? 宿主机上的文件和目录, 怎么样才能让容器里的进程访问到?
Docker Volume 就可以解决这个问题, 它允许你将宿主机上指定的目录或文件挂载到容器里面进行读取和修改操作
在 Docker 项目里, 它支持两种 Volume 声明方式, 可以把宿主机目录挂载进容器的 / test 目录当中
- $docker run -v /test ... //docker 没有显式声明宿主机目录, Docker 会默认在宿主机上创建一个临时目录 / var/lib/docker/volumes/[VOLUME_ID]/_data, 然后把它挂载到容器的 / test 目录上
- $docker run -v /home:/test ... // 直接把宿主机的 / home 目录挂载到容器的 / test 目录上
Docker 如何将宿主机上的目录或文件挂载到容器里面呢?
当容器进程被创建之后, 尽管开启了 Monut Namespace, 但是在它执行 chroot 之前, 容器进程一直可以看到宿主机上的整个文件系统 (包括了要使用的容器镜像, 这个镜像的各个层, 保存在 / var/lib/docker/aufs/diff 目录下, 在容器启动后, 它们会被联合挂载在 var/lib/docker/aufs/mnt 中). 在执行 chroot 之前, 把 Volume 指定的宿主机目录(如 / home 目录) 挂载到指定的容器目录 (如 / test 目录) 在宿主机对应的目录 (var/lib/docker/aufs/mnt/[可读写层 ID]/test, 这个 Volume 的挂载工作就完成了. 由于执行了这个挂载操作, 容器进程(Docker 初始化进程 dockerinit, 负责完成根目录的准备, 挂载设备和目录, 配置 hostname 等一系列需要容器内进行的初始化操作, 最后它通过 execv() 系统调用, 让应用进程取代自己, 成为容器里 PID=1 的进程)已经创建了, 也就意味着此时 Monut namespace 已经开启了. 所以这个挂载事件只在容器里可见, 在宿主机是看不见容器内部的这个挂载点的, 这就保证了容器的隔离性不会被 Volume 打破.
这里使用到的挂载技术, 就是 Linux 的绑定挂载 (bind mount) 机制, 它的主要作用是允许你将一个目录或者文件, 而不是整个设备挂载到一个指定的目录上, 并且这时你在该挂载点上进行的任何操作, 只是发生在被挂载的目录或者文件上, 而源挂载点的内容则会被隐藏起来且不受影响.
[Docker]Volume
来源: http://www.bubuko.com/infodetail-2768164.html