什么是卷?
将主机上的某个目录与容器的某个目录(称为挂载点、或者叫卷)关联起来,容器上的挂载点下的内容就是主机的这个目录下的内容。这样的话,我们修改主机上该目录的内容时,不需要同步容器,对容器来说是立即生效的。相反容器向挂载点写数据,也会立刻在主机某个目录生效,而不会写入到容器存储层。
匿名卷:
Dockfile 有VOLUME /data指令 ,docker run未指定卷。
容器向/data写数据
主机目录写数据
查看容器使用的卷的位置
docker inspect redis-volume
"Mounts": [
{
"Type": "volume",
"Name": "19e187baaf5a272a033591cf5c5ad781f0f303ebe5c3ddf284b2be865e24782c",
"Source": "/var/lib/docker/volumes/19e187baaf5a272a033591cf5c5ad781f0f303ebe5c3ddf284b2be865e24782c/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
命名卷:
创建命名卷为my-vol,docker run使用my-vol
创建一个卷my-vol
使用my-vol运行容器
主机目录和挂载目录
查看卷的信息:
[root@izhp3fuhf0tnxi9u27z7d5z ~]# docker volume inspect my-vol
[
{
"CreatedAt": "2019-03-16T01:28:24+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]
挂载主机目录:
挂载主机目录/home/myapp到容器的/myapp目录
指定主机目录
为什么使用卷来保存数据?
- 避免数据丢失
镜像是多层存储,每个RUN指令构建一层。镜像是只读文件系统,而容器会以镜像当作基础层,在其上加一层可读写层,作为容器运行时的存储层。运行中修改了容器的文件,也就是改动了容器的存储层。一旦容器删除后,这些数据就没了。 - 避免镜像臃肿
如果希望数据保存下来,有种方法是使用docker commit命令 ,就和git提交一样,在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像,成为镜像的最后一层,容器再这之上打开新的存储层。这将使镜像越来越臃肿,是极不可取的。我们需要数据持久化到主机上,而不是存在镜像中。设置示例指令,任何向/data中写入的信息都不会记录进容器的存储层。 - 当开发环境是在主机本地,但运行测试环境是放在docker容器上。本地修改文件后,需要再同步到容器中,这显然比较麻烦。
- 多个容器运行一组相关联的服务,如果他们要共享一些数据怎么办?
VOLUME指令的作用 示例VOLUME /data
这个命令是指定容器中的一个目录作为匿名卷。防止用户在运行容器时没有指定卷, 而向容器存储层写入数据。与之对应的是用户指定卷,在run时添加-v参数,则会覆盖这个配置。