容器由最上面一个可写的容器层,以及若干只读的镜像层组成,容器的数据就存放在这些层中。这样的分层结构最大的特性是Copy-on-Write:
(1)新数据会直接存放在最上面的容器层。
(2)修改现有数据会先从镜像层将数据复制到容器层,修改后的数据直接保存在容器层中,镜像层保持不变。
(3)如果多个层中有命名相同的文件,用户只能看到最上面那层中的文件。
使用docker info命令查看信息:
目前使用的存储驱动是overlay2
对于某些容器,直接将数据放在由storage driver维护的层中是很好的选择,比如那些无状态的应用。无状态意味着容器没有需要持久化的数据,随时可以从镜像直接创建。
但对于另一类应用这种方式就不合适了,它们有持久化数据的需求,容器启动时需要加载已有的数据,容器销毁时希望保留产生的新数据,也就是说,这类容器是有状态的。这就要用到Docker的另一种存储机制:Data Volume。
Data Volume本质上是Docker Host文件系统中的目录或文件,能够直接被mount到容器的文件系统中。Data Volume有以下特点:
(1)Data Volume是目录或文件,而非没有格式化的磁盘(块设备)。
(2)容器可以读写volume中的数据。
(3)volume数据可以被永久地保存,即使使用它的容器已经销毁
bind mount
bind mount是将host上已存在的目录或文件mount到容器:
-v的格式为 :
可以设置为相关文件在容器内只读:
-v的格式为 ::ro
也可以指定共享某个文件:
bind mount需要指定host文件系统的特定路径,这就限制了容器的可移植性,当需要将容器迁移到其他host,而该host没有要mount的数据或者数据不在相同的路径时,操作会失败。
将某个具体文件同步过去,会自动在容器内生成一个相应的镜像文件:
docker run -it -v D:/ubuntu/useforinfo.txt:/home/info.txt ubuntu_vping
docker managed volume
docker managed volume与bind mount在使用上的最大区别是不需要指定mount源,指明mount point就行了。但是其目录映射到host,目前无法在win10中使用。
可用docker inspect 容器
查看具体的mount地址,每次mount申请,都将在宿主机自动申请一个目录。
由于volume位于host中的目录,是在容器启动时才生成,所以需要将共享数据复制到volume中。
容器间共享数据:
第一种方法是将共享数据放在bind mount中,然后将其mount到多个容器。
volume container是专门为其他容器提供volume的容器:
volume container的作用只是提供数据,它本身不需要处于运行状态
docker create --name mydata -v D:/ubuntu:/home ubuntu_vping
docker run --name main -it -v D:/ubuntu:/home --volumes-from mydata ubuntu_vping
(1)与bind mount相比,不必为每一个容器指定host path,所有path都在volume container中定义好了,容器只需与volume container关联,实现了容器与host的解耦。
(2)使用volume container的容器,其mount point是一致的,有利于配置的规范和标准化,但也带来一定的局限,使用时需要综合考虑。
将数据完全放到volume container中,同时又能与其他容器共享:data-packed volume container
FROM ubuntu
ADD file 目录
VOLUME 目录
VOLUME 相当于-v,可以用类似–volumes-from的方式,共享一些静态的文件
删除volume(数据卷)
docker不会销毁bind mount,删除数据的工作只能由host负责。对于dockermanaged volume,在执行docker rm删除容器时可以带上 -v参数,docker会将容器使用到的volume一并删除,但前提是没有其他容器mount该volume,目的是保护数据,非常合理。
docker volume rm可删除volume
使用如下命令:
docker volume rm $(docker volume ls -q)
可以批量删除不用的数据卷。