Docker-13-数据卷

数据卷,可以绕过拷贝系统,在多个容器之间,或者容器和宿主机之间共享目录或者文件,数据卷绕过了拷贝系统,可以达到本地磁盘I/O性能

示例

以之前的nginx镜像为例,运行一个容器,然后再运行的时候,指定一个数据卷,用-v参数,具体命令如下:

1
docker run -tid --name nginx -v /usr/share/nginx/html/ -p 80:80 27a188018e18

执行完毕之后,我们就创建一个数据卷并且挂载到容器的/usr/share/nginx/html/目录下面,该目录其实是nginx保存html目录,在这里挂载数据卷,一会我们只需修改本地的映射位置,就可以实现页面的修改了.

使用docker inspect命令来查看一下刚刚创建的容器的具体信息,找到数据卷映射目录,如下:

1
docker inspect c39c3e362d27

找到下面这个部分:
image

从上图中可以看到,Docker默认将宿主机的/var/lib/docker/volumes/609df55091699750b86ee1f870e56050d4083a5159c0234360ffe9f903e41b55/_data这个目录作为source目录,然后我们进到这个目录中,看一下文件,如下:
image

这个目录下面的文件跟容器中的/usr/share/nginx/html/目录下的文件是一致的,这是因为挂载一个空数据卷到容器中的一个非空目录中时这个目录下的文件会被复制到数据卷中,如果挂载一个非空的数据卷
到容器中的一个目录中,那么容器中的目录中会显示数据卷中的数据.如果原来容器中的目录中有数据,那么
这些原始数据会被隐藏掉

然后现在先访问一下nginx的首页,内容如下:
image

现在我们把宿主机中,刚才目录下面的index.html修改掉,命令如下:

1
echo "hello volumes" > index.html

修改完成之后,再回到浏览器中,看一下首页内容,内容已经发生更改了,如下:

image

使用宿主机目录做数据卷

上面我们使用数据卷是系统随机分配的一个目录,一般情况下,需要我们明确的指定宿主机中的一个目录挂载到容器中,方式如下:

1
docker run -tid --name nginx -v /usr/docker/nginx/html:/usr/share/nginx/html/ -p 80:80 27a188018e18

这样就是将宿主机中的/usr/docker/nginx/html目录挂载到容器的/usr/share/nginx/html/目录下.

接下来只需要修改/usr/docker/nginx/html这个目录下的文件,就可以在nginx中看到效果

这种用法对于开发测试非常方便,不用重新部署,重启容器等.宿主机地址是一个绝对路径

Dockerfile中挂载数据卷

如果我们使用了Dockerfile去构建镜像的话,也可以在构建镜像的时候声明数据卷,例如下面这个Dockerfile:

1
2
3
4
FROM nginx
ADD https://www.baidu.com/img/bd_logo1.png /usr/share/nginx/html/
RUN echo "hello docker volume!">/usr/share/nginx/html/index.html
VOLUME /usr/share/nginx/html/

通过VOLUME就配置了一个匿名的数据卷,由于没有指定挂载到的宿主机目录,因此会默认挂载到宿主机的/var/lib/docker/volumes下的一个随机名称的目录下,因此Dockerfile中使用VOLUME指令挂载目录和docker run时通过-v参数指定挂载目录的区别在于,run的-v可以指定挂载到宿主机的哪个目录,而Dockerfile的VOLUME不能,其挂载目录由docker随机生成

数据卷的一些常用操作

查看所有数据卷

命令:

1
docker volume ls

image

查看数据卷详情

命令:

1
docker volume inspect <VOLUME NAME>

image

删除数据卷

单个删除:

1
docker volume rm <VOLUME NAME>

批量删除:

1
docker volume prune

批量删除的时候,只能删除掉没有在使用中的数据卷,正在使用中的需要停止相关的容器然后再次删除.