docker镜像大小的计算
docker镜像大小的计算
联合文件系统
Dockerfile 中命令与镜像层一一对应,那么是否意味着 docker build 完毕之后,镜像的总大小是否等于每一层镜像的大小总和呢?答案是肯定的。依然以上图为例:如果 ubuntu:14.04 镜像的大小为 200 MB,而 run.sh 的大小为 5 MB,那么以上三层镜像从上到下,每层大小依次为 0、0 以及 5 MB,那么最终构建出的镜像大小的确为 0 + 0 + 5 + 200 = 205 MB。
虽然最终镜像的大小是每层镜像的累加,但是需要额外注意的是,Docker 镜像的大小并不等于容器中文件系统内容的大小(不包括挂载文件,/proc、/sys 等虚拟文件)。个中缘由,就和联合文件系统有很大的关系了。
首先来看一下这个简单的 Dockerfile 例子(假设在 Dockerfile 当前目录下有一个 100 MB 的压缩文件 compressed.tar ):
FROM ubuntu:14.04
ADD compressed.tar /
RUN rm /compressed.tar
ADD compressed.tar /
FROM ubuntu:14.04
:镜像 ubuntu:14.04 的大小为 200 MB;ADD compressed.tar /
: compressed.tar 文件为 100 MB,因此当前镜像层的大小为 100 MB,镜像总大小为 300 MB;RUN rm /compressed.tar
:删除文件 compressed.tar ,此时的删除并不会删除下一层的 compressed.tar 文件,只会在当前层产生一个 compressed.tar 的删除标记,确保通过该层将看不到 compressed.tar ,因此当前镜像层的大小也为 0,镜像总大小为 300 MB;ADD compressed.tar /
:compressed.tar 文件为 100 MB,因此当前镜像层的大小为 300 MB + 100 MB,镜像总大小为 400 MB;
分析完毕之后,我们发现镜像的总大小为 400 MB,但是如果运行该镜像的话,我们很快可以发现在容器根目录下执行 du -sh 之后,显示的数值并非 400 MB,而是 300 MB 左右。主要的原因还是,联合文件系统的性质保证了两个拥有 compressed.tar 文件的镜像层,容器仅能看到一个。同时这也说明了一个现状,当用户基于一个非常大,甚至好几个 GB 的镜像运行容器时,在容器内部查看根目录大小,发现竟然只有 500 MB 不到,甚至更小。
分析至此,有一点大家需要非常注意:镜像大小和容器大小有着本质的区别。
我们可以通过 docker history Image_id
来查看每层的文件大小