网站首页 文章专栏 Docker存储驱动之--overlay2
Docker存储驱动之--overlay2
编辑时间:2021-01-08 10:31:50 作者:admin 浏览量:126

docker支持多种graphDriver,包括vfs、devicemapper、overlay、overlay2、aufs等等,其中最常用的就是aufs了,但随着linux内核3.18把overlay纳入其中,overlay的地位变得更重。


docker默认的存储目录是/var/lib/docker,下面我们简单打印一下这个目录:

image.png

在这里,我们只关心imageoverlay2就足够了。
做这个实验之前,我们应该先启动一个容器,在这里使用tensorflow作为实验:

image.png


可以看到新启动的tf容器的id是86b5733e54c7,我们继续往下看。

上面说了,我们只需要关心/var/lib/docker/image/var/lib/docker/overlay2,可以先到/var/lib/docker/image打印一下:

image.png

我们只能看到overlay2这个目录,想必聪明的你也猜到了,docker会在/var/lib/docker/image目录下按每个存储驱动的名字创建一个目录,如这里的overlay2

接下来,使用tree命令浏览一下这个目录:

image.png


这里的关键地方是imagedblayerdb目录,看这个目录名字,很明显就是专门用来存储元数据的地方,那为什么区分image和layer呢?因为在docker中,image是由多个layer组合而成的,换句话就是layer是一个共享的层,可能有多个image会指向某个layer。

那如何才能确认image包含了哪些layer呢?答案就在imagedb这个目录中去找。比如上面启动的tf容器,我们可以先找到这个容器对应的镜像:

image.png

可以看到,imageID是b1caf62daa3a,再次记住这个id,我们打印/var/lib/docker/image/overlay2/imagedb/content/sha256这个目录:

image.png

上述文件正是记录我们tensorflow镜像元数据的文件,接下来cat一下这个文件,得到一个长长的json:

image.png

由于篇幅原因,我只展示最关键的一部分,也就是rootfs。可以看到rootfs的diff_ids是一个包含了3个元素的数组,其实这3个元素正是组成tf镜像的3个layerID,从上往下看,就是底层到顶层,也就是说6cebf3abed5fac58d2e792c...是image的最底层。既然得到了组成这个image的所有layerID,那么我们就可以带着这些layerID去寻找对应的layer了。


接下来,我们返回到上一层的layerdb中,先打印一下这个目录:

image.png

在这里我们只管mountssha256两个目录,再打印一下sha256目录:

6cebf3abed5fac58d2e792ce8461454e92c245d5312c42118f02e231a73b317f  

f7eae43028b334123c3a1d778f7bdf9783bbe651c8b15371df0120fd13ec35c5

.................................................................................................

15b0a4930718a33932103afb7d69518132181e8aaa3618651278d189e1330009

image.png


在这里,我们仅仅发现6cebf3abed5fac58d2e792ce8461454e92c245d5312c42118f02e231a73b317f 这个最底层的layer,那么剩余两个layer为什么会没有呢?那是因为docker使用了chainID的方式去保存这些layer,简单来说就是chainID=sha256sum(H(chainID) diffid),也就是5dacd731af1b038..的上一层的sha256 id是:

 

[root@node1 sha256]# echo -n "sha256: 6cebf3abed5fac58d2e792ce8461454e92c245d5312c42118f02e231a73b317f sha256:6cebf3abed5fac58d2e792ce8461454e92c245d5312c42118f02e231a73b317f" | sha256sum -
f7eae43028b334123c3a1d778f7bdf9783bbe651c8b15371df0120fd13ec35c5  -


这个时候,你能看到f7eae43028...这个layer层的目录了吧?依次类推,我们就能找出所有的layerID的组合。


但是上面我们也说了,/var/lib/docker/image/overlay2/layerdb存的只是元数据,那么真实的rootfs到底存在哪里呢?其中cache-id就是我们关键所在了。我们打印一个:

image.png

没错,这个id就是对应

/var/lib/docker/overlay2/73c925c44160516254059a0e36261d034b793be01431b9 d4156d6657d26f21ed

可以进去看看,是不是你熟悉的linux目录结构呢?(最底层文件系统)

image.png


因此,以此类推,更高一层的layer对应的cache-id也能找到对应的rootfs,当这些rootfs的diff目录通过联合挂载的方式挂载到某个目录,就能完整整个容器需要的rootfs了。


划重点:

/var/lib/docker/image

imagedb和layerdb记录了镜像层的存储信息

image.png


/var/lib/docker/overlay2才存储的是每一层的文件信息(镜像分层)

image.png

/var/lib/docker/overlay2/73c..../diff是镜像层文件

image.png

来说两句吧
最新评论