本文基于docker v1.13版本
首先查看本地文件系统的情况:
[root@localhost /]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/centos-root 52403200 26219152 26184048 51% /
devtmpfs 1923288 0 1923288 0% /dev
tmpfs 1933472 0 1933472 0% /dev/shm
tmpfs 1933472 17024 1916448 1% /run
tmpfs 1933472 0 1933472 0% /sys/fs/cgroup
/dev/mapper/centos-home 47760604 32928 47727676 1% /home
/dev/sda1 508588 155828 352760 31% /boot
tmpfs 386696 0 386696 0% /run/user/0
启动一个挂载了网络存储卷的容器:
[root@localhost /]# docker run -it --rm -v foo:/opt/foo busybox /bin/sh
再次查看本地文件系统的情况:
[root@localhost ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/centos-root 52403200 26224408 26178792 51% /
devtmpfs 1923288 0 1923288 0% /dev
tmpfs 1933472 0 1933472 0% /dev/shm
tmpfs 1933472 17092 1916380 1% /run
tmpfs 1933472 0 1933472 0% /sys/fs/cgroup
/dev/mapper/centos-home 47760604 32928 47727676 1% /home
/dev/sda1 508588 155828 352760 31% /boot
tmpfs 386696 0 386696 0% /run/user/0
/dev/dm-4 10474496 34660 10439836 1% /var/lib/docker/devicemapper/mnt/0e975c0bc5b50f8faaf52e3bd5a279ffb47b9a131e34192a4bb153cf5710604f
shm 65536 0 65536 0% /var/lib/docker/containers/cc814a199dbe9d542b7a0db6af4b8928f19afd74a60d7f3248125f4177b35902/shm
:/opt/test 18307072 8859648 9447424 49% /var/lib/docker/volumes/foo/_data
可以看出,最后多出了三个目录,其中/var/lib/docker/volumes/foo/_data
就是docker维护volume的目录,也是网络共享目录的挂载点。
Data Volume和存储驱动
由于Docker是基于镜像,在所有的镜像层之上,对每个容器分别创建读写层,所以容器中的操作都是在读写层中进行的。在容器中如果需要对一个文件进行改动,docker会从镜像的最上层到最下层逐层搜索这个需要被操作的文件,然后将它拷贝到读写层,然后供容器进行操作。这个操作叫做copy-on-write
,并且它只在第一次对该文件操作的时候会发生,以后所有的操作都是对第一次拷贝的文件副本的操作。针对不同的容器存储驱动,copy-on-write
的操作效率和实现方式会有所区别。
data volume是一个宿主机的本地目录,挂载到容器中去。data volume不受docker存储驱动的控制,在容器中对data volume的读写操作,取决于宿主机上该目录的本地速度,与docker存储驱动无关。
Docker Engine管理容器数据的两种方式
- Data volume
- Data volume containers
Data volume
data volume可以绕过容器的联合文件系统,在多个容器之间共享和持久化数据。
有如下特点:
- volume在容器创建的时候初始化
- 可以在容器之间共享和反复使用
- 其中的变化会立即生效
- 其中的变化和镜像无关
- 容器销毁后依然存在
volume的操作对宿主机和容器中对应目录的影响
如果在宿主机创建了docker volume并且volume的目录中已经留存有文件,同时,该volume挂载到容器中的目录中也存有文件,那么容器该目录将会指向宿主机的volume目录,并显示其中的文件,容器该目录中的原有文件将会在卷umount
之后,才可以操作。
另外,如果宿主机上volume目录为空,容器目标volume目录不为空,容器启动的时候,容器目标volume中的文件将会拷贝到宿主机volume目录中,即使容器被销毁,该volume中的文件依然留存。
具体的实验结果如下:
[root@localhost _data]# docker run -it busybox:volume
/ # cd busybox:volume/
/volumeInContainer # ls
hahaha
busybox:volume
镜像的/busybox:volume
目录中存有文件hahaha
,卷hostVolume
如下:
[root@localhost _data]# docker volume ls
DRIVER VOLUME NAME
local hostVolume
[root@localhost _data]# docker volume inspect hostVolume
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/hostVolume/_data",
"Name": "hostVolume",
"Options": {},
"Scope": "local"
}
]
[root@localhost _data]# cd /var/lib/docker/volumes/hostVolume/_data
[root@localhost _data]# ls
nothahaha
可见hostVolume
中存有文件nothahaha
。启动容器挂载卷,可见挂载目录中的文件是hostVolume的文件。
[root@localhost _data]# docker run -it -v hostVolume:/volumeInContainer busybox:volume /bin/sh
/ # cd volumeInContainer/
/volumeInContainer # ls
nothahaha
在宿主机hostVolume
中没有文件的时候:
[root@localhost _data]# cd /var/lib/docker/volumes/hostVolume/_data
[root@localhost _data]# ll
total 0
[root@localhost _data]# docker run -it -v hostVolume:/volumeInContainer busybox:volume /bin/sh
/ # exit
[root@localhost _data]# ll
total 0
-rw-r--r--. 1 root root 0 Jun 7 08:20 hahaha
经过容器卷的挂载之后,容器中的文件会被持久化到宿主机的hostVolume
中。即使删除容器后,文件依旧存在。
[root@localhost _data]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fca3709bbd52 busybox:volume "/bin/sh" About a minute ago Exited (0) About a minute ago amazing_clarke
[root@localhost _data]# docker rm fca3
fca3
[root@localhost _data]# ls
hahaha
docker启动时-v参数
如果是绝对路径
,指定宿主机的绝对路径
;如果是名称
,则对应有名volume
。如果该volume不存在,会自动创建。
[root@localhost _data]# docker run -itd -v foo2:/volumeInContainer busybox:volume /bin/sh
[root@localhost _data]# docker volume ls
DRIVER VOLUME NAME
local foo2