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 來查看每層的文件大小
