docker storage driver
使用docker目录创建一个volume,并将该volume挂载到容器的/my_Cvol目录下 # docker volume create my_vo # docker run -itd --rm --mount source=my_vol,target=/my_Cvol busybox:latest /bin/sh 查看该volume,其源目录实际在/var/lib/docker/volumes/my_vol/_data下 # docker volume inspect my_vol [ { "CreatedAt": 2018-12-24T22:42:18+08:00",DriverlocalLabels": nullMountpoint/var/lib/docker/volumes/my_vol/_dataNamemy_volOptionsScope } ] 查看使用docker inspect容器相关信息,可以看到volume的挂载信息,挂载到容器中的目录是可读写的。这样在容器的/my_Cvol目录下的操作也会同步到host的/var/lib/docker/volumes/my_vol/_data目录中。 Mounts: [ { TypevolumeSourceDestination/my_CvolModezRWtruePropagation"" } 查看host上/var/lib/docker/volumes/my_vol/_data的MAC属性可以看到它们变为了容器的MAC属性,这样也防止了容器操作不属于其权限范围的文件 # ls -Z -rw-------. root root system_u:object_r:container_var_lib_t:s0 metadata.db drwxr-xr-x. root root system_u:object_r:container_var_lib_t:s0 my_vol 使用tmpfs主要用于存储临时数据,由于tmpfs使用的是共享内存方式,所以其效率比较高。使用tmpfs时有如下2个选项用于指定tmpfs的大小和访问权限: tmpfs-size:指定tmpfs的大小 tmpfs-mode:指定mount的目录权限
首先安装docker插件 # docker plugin install --grant-all-permissions vieux/sshfs
在node1节点上创建位于node2节点的卷,登陆的ssh密码为root,对端ip为192.168.80.161 # docker volume create --driver vieux/sshfs -o sshcmd=root@192.168.80.161:/home/sshvolume -o password=root sshvolume 在host上查看容器进程的挂载信息,可以看到其实际使用了fuse.sshfs的方式挂载了来自的root@192.168.80.161:/home/sshvolume目录 # cat /proc/19574/mountinfo |grep 176 502 399 0:49 / /sshvolume rw,nosuid,nodev,relatime master:176 - fuse.sshfs root@80.161:/home/sshvolume rw,user_id=0,group_id=0 node1上查看docker卷信息,可以看到新增了drive为vieux/sshfs:latest,名字为sshvolume的卷 # docker volume ls DRIVER VOLUME NAME vieux/sshfs:latest sshvolume 在node1上创建一个容器,并将上一步的卷挂载到容器,在容器内部创建2个文件夹,登陆到node2的/home/sshvolume,可以看到该目录下有node1的容器创建的文件夹 docker run -itd --mount source=sshvolume,target=/sshvolume busybox:latest /bin/sh ? docker storage driver storage driver负责不同layer之间的交互,它允许在容器的读写层创建数据,读写层数据不会被持久化,且读写效率较低。如下图所示,容器镜像的layer是只读的,当创建一个容器时,会新增一个读写层,称为”container layer“,对容器的所有修改都在该layer上进行。当容器删除后,该读写层也会被删除。不同的storage driver实现不同,但所有的storage driver都使用了如下栈式镜像结构以及CoW(copy-on-write)策略。这是对CoW的描述
使用docker ps -s可以查看镜像大小,可以看到"SIZE"有2个值,如container id为5b22377a773d的容器中,38B表示容器读写层的数据总和;virtual表示只读的镜像层加上读写层的大小,不同的容器可能会共用部分或全部的镜像层,因此计算容器占用空间大小不能简单地对virtual进行叠加 # docker ps -s CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE 5b22377a773d echo:v1 /bin/sh" 2 hours ago Up 2 hours practical_darwin 38B (virtual 1.2MB) 803ee1eb5acf echo:v1 sh -c /home/echo.sh" 2 hours hungry_hertz 66B (1.2MB) 当在5b22377a773d中手动创建一个非空文件之后,可以看到size变为了95B # docker ps -2 hours practical_darwin 95B (.2MB) 803ee1eb5acf 6d495122f721 1.2MB) 当使用docker pull拉取一个容器镜像时,会在/var/lib/docker/<storage-driver>/layers/下面保存各个layer。 容器的读写层只保存修改过的变动,而未修改的文件或目录等则不会被保存在读写层。当修改容器中已经存在的文件时,会执行CoW操作,此时在镜像层中逐层搜索该文件,当找到该文件时,会将文件拷贝到容器的读写层(容器的镜像只读层可共享,但读写层不可以共享,CoW技术可以最大化减小容器占用的磁盘,提高磁盘利用率)。当CoW的读写效率比较低,可能会影响IO效率,需要注意以下2点:
ocker的storage driver使用插件方式提供功能。插件的选择取决于docker的版本以及使用的系统等,官方对storage driver的选择有如下建议,可以看出目前主要推荐overlay2。overlay和devicemapper已经在docker 18.09版本中被废除
不同storage driver所需要的文件系统如下:
不同的storage driver各有优缺点:
在对storage driver修改时需要注意
下面讲解下overlay2的文件结构和特点,首先下载一个centos镜像,查看改镜像有如下3个layer # docker history centos:latest IMAGE CREATED CREATED BY SIZE COMMENT 1e1148e4cc2c 2 months ago /bin/sh -c #(nop) CMD [/bin/bash] 0B <missing> 2 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> 2 months ago /bin/sh -c #(nop) ADD file:6f877549795f4798a… 202MB 使用docker inspect查看该镜像可以看到其文件系统 GraphDriver: { Data: { MergedDir/var/lib/docker/overlay2/0bb8525e901534d5c3884a9e47b91d27f887278d0433506126c45081a2a482b8/mergedUpperDir/var/lib/docker/overlay2/0bb8525e901534d5c3884a9e47b91d27f887278d0433506126c45081a2a482b8/diffWorkDir/var/lib/docker/overlay2/0bb8525e901534d5c3884a9e47b91d27f887278d0433506126c45081a2a482b8/work },1)">overlay2 }, 使用docker run -itd centos:latest /bin/sh启动一个centos的容器,此时会自动创建overlay需要的lowerdir,upperdir,merged和workdir,使用docker inspect命令,可以看到该容器的overlay2使用情况 LowerDir/var/lib/docker/overlay2/7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d-init/diff:/var/lib/docker/overlay2/0bb8525e901534d5c3884a9e47b91d27f887278d0433506126c45081a2a482b8/diff/var/lib/docker/overlay2/7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d/merged/var/lib/docker/overlay2/7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d/diff/var/lib/docker/overlay2/7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d/workmerged,upperdir和lowerdir的定义如下,upperdir为容器的读写层,lowerdir为容器的镜像只读层,merged为二者的合集 |