ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
> **overlayFS**是被称为联合文件系统的其中一个解决方案。在2014年,发布了第一个版本并且合并到了Linux的内核3.18版本中,此时,在docker被称为是overlay文件驱动。后来在Linux 内核4.0 版本中进行了改进,称为overlay2。(overlay存在诸多性能和不稳定的问题,不推荐使用overlay,直接使用默认的overlay2即可) # <span style="font-size:15px">**overlay2工作原理**</span> ![](https://img.kancloud.cn/e5/9f/e59f0c05dda5414df8a053bedbbd9a4e_1191x249.png) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;overlayfs 通过三个目录:lower 目录、upper 目录、以及 work 目录实现,其中 lower 目录可以是多个,work 目录为工作基础目录,挂载后内容会被清空,且在使用过程中其内容用户不可见,最后联合挂载完成给用户呈现的统一视图称为为 merged 目录。 * lowerdir对应底层文件系统,是能被上层文件系统upperdir所共享的只读层 * workdir则可以理解为overlay2运作的一个工作目录,用于完成copy-on-write等操作 * overlay2运作时(也就是容器启动时),会将lowerdir、upperdir和workdir联合挂载到merged目录,为使用者提供一个“**统一视图**” &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;查看 `/var/lib/docker/overlay2/容器ID`目录结构,使用`mount | grep overlay`查看overlay的挂载情况。如图,确实此目录下的link、lower、work、diff等目录是通过挂载多个目录后,合并显示在一起的。 ![](https://img.kancloud.cn/40/e1/40e18b73e7d9340bf657960d180796e4_1871x172.png) # <span style="font-size:15px">**overlay2 是如何存储文件的?**</span> ## <span style="font-size:15px">**镜像怎么存储的?**</span> 1、为了更好的演示,使用一个纯净的环境:没有任何镜像和容器,/var/lib/docker/overlay2目录也是空的 ![](https://img.kancloud.cn/fa/10/fa10245d011b85241a36dde616368600_952x159.png) 2、拉取一个nginx镜像,观察拉取过程:可以看到镜像一共被分为6层拉取。 ![](https://img.kancloud.cn/8c/89/8c899d2335b259e9ee5f7fa5e47454bf_915x201.png) 3、/var/lib/docker/overlay2/ 目录下也多了6个文件夹 ![](https://img.kancloud.cn/12/89/12898e3cc6442d855c916e70afb7d418_1696x98.png) 4、首先来查看一下l目录,可以看到l目录是一堆软连接,把一些较短的随机串软连到镜像层的 diff 文件夹下,这样做是为了避免达到mount命令参数的长度限制 ![](https://img.kancloud.cn/fb/d4/fbd49528ae56fe71b63c61460a9a0cf6_1570x218.png) 5、`docker image inspect nginx` 查看nginx镜像的信息,每个镜像都会有一个`GraphDriver.Data`信息,这个信息指示了镜像是怎么存的 ![](https://img.kancloud.cn/e4/04/e40401cdd18073c9b7ddd7b8d96454de_1881x435.png) 6、将这6个文件夹全部展开,可以看到目录结构几乎都是一致的,需要重点关注的是diff文件夹和lower文件。 可以看到`5160f86fbe7acce3826ed5c7d1acdb351b931d67978b1c91138d86b7eef8d0ab`文件夹中不存在lower文件,说明它是最底层的,等于是根镜像,即docker pull时下载的第一层。 同时,`diff`文件夹下的文件,正是Linux文件目录结构。说明在nginx的dockerfile中,肯定有FROM centos的操作。 ![](https://img.kancloud.cn/4f/5e/4f5e91d44806bd99d952b53240af4647_1644x276.png) **实例说明:`Dockerfile`的每一个命令都可能引起了系统的变化,它的每一个变化都会记录一层diff文件。** ## <span style="font-size:15px">**容器怎么存储的?**</span> 1、当前环境有一个nginx镜像,/var/lib/docker/overlay2/ 目录下只有镜像层的存储目录。 ![](https://img.kancloud.cn/00/bb/00bbc4d093c031ac444fa244e62cc1cc_1685x126.png) 2、docker run 启动一个容器 ![](https://img.kancloud.cn/ba/02/ba02e8e6071da7278f2220671d99fcd8_1128x105.png) 3、查看/var/lib/docker/overlay2/ 目录,发现新增了两个目录:其中带`-init`的目录是只读的;没有init的容器目录才是容器的读写目录 ![](https://img.kancloud.cn/7e/75/7e751a6debb0ce0ba5865714e05893d1_1054x223.png) 4、`link`和`lower`文件与镜像层的功能一致,`link`文件内容为该容器层的`短 ID`,`lower`文件为该层的所有父层镜像的`短 ID`。`diff`目录为容器的读写层,容器内修改的文件都会在`diff`中出现,`merged`目录为分层文件联合挂载后的结果,也是容器内的工作目录。 ![](https://img.kancloud.cn/65/8b/658b8e329ca5bf005d066fb620e09d20_1070x103.png) ![](https://img.kancloud.cn/60/73/6073e3287c1274dc6a3b91dfb6ecb229_1731x215.png) 5、根据 docker inspect nginx获取到的`GraphDriver.Data`数据显示,merged目录,是lowerDir各个目录合并UpperDir各个目录后的结果。 ![](https://img.kancloud.cn/19/d1/19d1989757d317299ca149ac5c42c95e_1446x116.png) 6、当我们进入容器创建文件时,文件也会出现在这里。 ![](https://img.kancloud.cn/8e/c2/8ec2d54c0a9fc8e66f49536edf9eb73d_1688x208.png) <nr> <br> **结论:** overlay2将镜像层和容器层都放在单独的目录,并且有唯一 ID,每一层仅存储发生变化的文件,最终使用联合挂载技术将容器层和镜像层的所有文件统一挂载到容器中,使得容器中看到完整的系统文件。