登录后台

页面导航

本文编写于 150 天前,最后修改于 95 天前,其中某些信息可能已经过时。

Dockerfile 当中的volume参数

VOLUME /share/data #声明容器中/share/data为匿名卷

volume和run -v的区别,什么时候需要使用volume

​ 容器运行时应该尽量保持容器存储层容器的可写层,镜像层是不发生写入操作的,写入操作是发生在容器层当中,所以如果是不将大量的映射到一个对应的目录下存放,那么将会让容器的体积变得很大)不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中。

​ 为了防止运行时忘记将动态文件所保存目录挂载为卷(这里指的是忘记使用-v参数),在Dockerfile 中,可以事先指定某些目录挂载为匿名卷(名字是随机的),这样在运行时如果不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据,而是将数据写入到对应的匿名卷当中。

​ 那么Dockerfile中的VOLUME指令实际使用中是不是就是跟docker run中的-v参数一样是将宿主机的一个目录绑定到容器中的目录以达到共享目录的作用呢?

​ 并不然,其实VOLUME指令只是起到了声明了容器中的目录作为匿名卷,但是并没有将匿名卷绑定到宿主机指定目录的功能(没有像-v那种指定对应的目录挂载,而是在docker的安装目录下,创建了一个以随机数命名的卷,用来存储volume映射的路径当中的数据

​ 当我们生成镜像的Dockerfile中以Volume声明了匿名卷,并且我们以这个镜像run了一个容器的时候,docker会在安装目录下的指定目录下面生成一个目录来绑定容器的匿名卷(这个指定目录不同版本的docker会有所不同),我当前的目录

为:/var/lib/docker/volumes/{容器ID,是一串随机的字符}。

总结: volume只是指定了一个目录,用以在用户忘记启动时指定-v参数也可以保证容器的正常运行。比如mysql,你不能说用户启动时没有指定-v,然后删了容器,就把mysql的数据文件都删了,那样生产上是会出大事故的,所以mysql的dockerfile里面就需要配置

volume指定的位置在容器被删除以后数据文件会被删除吗

​ volume与-v指令一样,容器被删除以后映射在主机上的文件不会被删除。

如果-v和volume指定了不同的位置,会发生什么事呢?

​ 会以-v设定的目录为准,其实volume指令的设定的目的就是为了避免用户忘记指定-v的时候导致的数据丢失,那么如果用户指定了

-v,自然而然就不需要volume指定的位置了。

总结

​ 其实一般的dockfile如果不是数据库类的这种需要持久化数据到磁盘上的应用,都是无需指定volume的。指定volume只是为了避免用户忘记指定-v时导致的数据全部在容器中,这样的话容器一旦被删除所有的数据都丢失了。那么为什么dockerfile中不提供一个能够映射为主机目录:容器目录这样的指令呢?其实这样的设计是有道理的,如果在dockerfile中指定了主机目录,这样dockerfile就不具备了可移植性了,毕竟每个人所需要映射的目录可能是不同的,那么最好的办法就是把这个权利交给每个运行这个dockerfile的人,所以才会有 run -v 主机目录:容器目录 这样的指令。

博主已关闭本页面的评论功能