为什么Docker不会销毁隐藏的图层?
考虑到Docker的联盟文件系统,任何改变将实际上在当前的图像(最顶层)而不是以前的图像上进行; 问题是为什么这些层不被Docker破坏,只是隐藏? 有什么特别的理由吗?
高速caching
通过单独保存每个图层,docker可以caching结果,并在以后再次使用时,如果它没有被任何以前的更改无效。
从同一个基本映像生成多个图像时,可以实现更快速的构build和更小的整个文件系统的使用
Docker是build立在联盟文件系统AUFS上的。
图像是通过在AUFS上层叠变化来创build的(从那时起,其他方法已经被添加了)
一个典型的构build将RUN
一些创build一些数据,并保存在一个层。
RUN touch a -- L1 a RUN touch b -- L2 b RUN touch c -- L3 c
每个图层只存储自己的一组更改。
这些AUFS层的总和安装在每个层上,成为容器的底层虚拟文件系统。 “Image”只是底层数据的一个视图。
图像本身不存储任何数据。 它只引用存储数据的图层。
*image view abc L3 c L2 b L1 a
然后,容器的变化是在这一层之上的一层。 如果需要修改任何现有的数据,将其添加到其图层中,或者“删除”删除数据引用的数据,而不是基础层中的实际数据。
如果我要修改一个文件,创build一个文件,并删除一个文件
echo test >> a touch d rm c
图层看起来像:
Lcontainer a * d L3 c L2 b L1 a
如果要销毁其中一个较低层,则呈现给容器的视图将会丢失该数据。
*image view ac L3 c L1 a
正如Derick Bailey提到的,这允许一些巧妙的图像构build时间caching,允许在图像之间共享图层,如果再次使用完全相同的图层。 这通常是FROM
现有的图像生成。
较新的存储驱动程序(如decivemapper
和zfs
实现相同的策略,但在块级别上为每个层使用文件系统快照或克隆。 与底层/快照保持不变的磁盘块将从原始层/快照中读取。 容器层/快照将指针保持为原始数据,直到它被更改或删除。