在docker镜像创建过程中,镜像少则几百M,大则1G多,但是好奇的是镜像每次的提交到远程速度超快。通过提交日志,我们可以多少看出端倪,Docker的文件系统是分块管理的,如图所示:

整个镜像由多个用十六进制Id标记的layer组成,每次只提交被修改过的layer, 这也是dockert提交镜像快速的秘密--增量提交。
那Docker是怎么组织文件系统做到这一点的呢?
首先我们从Docker镜像的结构谈起。Docker镜像的一系列的layer,每一层代表了Dockerfile中的一条指令。比如下面的Dockerfile:
FROMubuntu:15.10
COPY. /app
RUN make/app
CMD java -jar /app/application.jar
它有四个指令,每个指令生成一个层级,每一层都建立在前一个层级之上,他们是顺序的层叠关系。下面是四个层级的展示层(最上层不属于镜像,它是容器的读写层):

如果使用镜像创建出了容器,那么存储结构如下,多了容器的读写层,当容器被删除,读写层会被删除,镜像的layer会保留,因此需要在容器中共享的静态内容需要都需要打包到镜像文件中。下图展示了容器的文件layer结构:

docker通过不同的storage driver来管理这些文件层级,不同的driver有不同的实现,并各有优劣。但是,所有的drivers都是堆叠式的层级并且遵从CoW策略。
最后,我们来看看docker的卷(volume)。容器中任何修改过的,但是没有写进卷中的修改都会随着容器的删除而被移除。如果你想保存容器中修改过的内容,需要存储在与volume关联的docker host上的文件或者目录中。下图展示的是默认的docker数据卷在docker host上存储的位置。

从上面的三个方面可以看到,docker的整个文件结构整个结构由层叠的镜像只读层,容器的读写层以及存储容器状态数据的数据卷组成。通过本文,我们详细的了解了docker组织文件的方式,有了它作为基础,我们就可以更合理的配置和管理docker镜像和容器。
网友评论