[Docker]Volume
Posted yuxiaoba
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Docker]Volume相关的知识,希望对你有一定的参考价值。
容器技术使用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的主要内容,如果未能解决你的问题,请参考以下文章
(转)Docker volume plugin - enabled create local volume on docker host