docker -v 和Dockerfile 中VOLUME 区别

kingpin 2020-06-01

Dockerfile中 VOLUME ["/data/nginx","/usr/share/nginx"] 

 docker run  -v  /data/nginx:/usr/share/nginx   

如果只是读文件   两者都可以 

如果是想把文件写出  两个也都可以  但是有区别

volume 默认会写到 /var/lib/docker/volumes 中 

-v 写到指定文件

在学习Dockerfile的过程中有个VOLUME命令,很多教程或书中说的是用来定义匿名卷的,其作用如下:

容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存
动态数据的应用,其数据库文件应该保存于卷(volume)中,后面的章节我们会进一步介绍
Docker 卷的概念。为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在
Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂
载,其应用也可以正常运行,不会向容器存储层写入大量数据。
  这领我们想起docker的run命令中的 "-v"参数的作用

# docker run --help | grep volume
  -v, --volume list                    Bind mount a volume
      --volume-driver string           Optional volume driver for the container
      --volumes-from list              Mount volumes from the specified

那么Dockerfile中的VOLUME指令实际使用中是不是就是跟docker run中的-v参数一样是将宿主机的一个目录绑定到容器中的目录以达到共享目录的作用呢?并不然,其实VOLUME指令只是起到了声明了容器中的目录作为匿名卷,但是并没有将匿名卷绑定到宿主机指定目录的功能。但是当我们生成镜像的Dockerfile中以Volume声明了匿名卷,并且我们以这个镜像run了一个容器的时候,docker会在安装目录下的指定目录下面生成一个目录来绑定容器的匿名卷(这个指定目录不同版本的docker会有所不同)。如我使用的版本如下:

# docker --version
Docker version 18.09.0, build 4d60db4    //docker版本
# pwd
/var/lib/docker/volumes          //默认绑定容器的匿名卷的目录
# ll
total 32
drwxr-xr-x. 3 root root  4096 Nov 25 20:18 593fda6d7b8296bfca22894b326727c734133eebb11c9bc2c25a73b892157a37  //其中一个容器的共享目录文件夹
drwxr-xr-x. 3 root root  4096 Nov 25 20:14 78d890eeb15ac6295484d5e84e97928e981b01501fa40bac40b965fc9e54899a  //其中一个容器的共享目录文件夹
-rw-------. 1 root root 32768 Nov 25 20:18 metadata.db

   就是说当Dockerfile中声明了匿名卷但是run的时候没有使用 -v绑定匿名卷的话那么docker就会在/var/lib/docker/volumes这个目录下创建一个目录来绑定匿名卷。

所以真正使用的时候我们在Dockerfile构建镜像的时候如:

FROM centos:latest
RUN groupadd -r redis && useradd  -r -g redis redis
RUN yum -y update &&  yum -y install epel-release && yum -y install redis && yum -y install net-tools

RUN mkdir -p /config && chown -R redis:redis /config


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


EXPOSE 6379

   那么使用该Dockerfile构建镜像的为

# docker build -t image-redis    //构建镜像image-redis
......
#docker run -itd -name redis1 -v /data:/share/data image-redis    //运行一个容器并且将当前机器的/data目录绑定到容器的匿名卷中
.....
#docker run -itd  -name redis2 image-redis     //运行一个容器但是不绑定目录到容器的匿名卷,这时候再/var/lib/docker/volumes(不同版本目录不一样)中就会创建一个目录绑定匿名卷
.....

   以上为我实验的结果,记录一下备忘。

相关推荐