跳至主要内容

4.5 映像檔快取的秘密

在映像檔內,每一層映像層都有獨一無二由 SHA ( Secure Hash Algorithm ) 所計算出來的 ID,目的是幫助 Docker 去辨認是否已經有一樣的映像層。

舉例來說,我想要自製一個帶有 PHP 程式語言環境的映像檔,我們就使用 PHP 的映像檔當做基底,如下圖,以 PHP 做基底。

自製映像檔的第一層

接著會撰寫 Dockerfile 在這個第一層的 PHP 之上增加新的映像層,像是加入環境變數,或是 COPY 本機的資料到映像檔內等等,如下圖所示:

堆疊而成的映像檔

接著我們又想要做另外一個也以 PHP 為基礎的映像檔,Docker 將會利用前面提到的獨一無二的 ID 辨識出已經有相同的 PHP 映像檔在本機之中,並利用其已存在的特性加快映像檔的建置,也一併減少了整體電腦耗費的硬體容量,這也是 Docker 最基本的快取機制。

共用相同映像��檔的兩個映像檔

現在對於上面的指令 ENV、COPY、RUN 不熟都沒關係,要先了解到映像檔是透過一層一層的映像層堆疊而成,而每一個指令都會形成一個映像層,這是很重要的概念,之後會反覆的利用這個概念來加快建置的速度和大小。

再舉一個例子,相同的一個應用程式,可能會因為部署環境的不同而分成 Staging ( 接近正式 ) 以及 Production ( 正式 ) 兩種版本,並使用 COPY 這個指令來複製不同的設定檔案進而建置兩個不同的映像檔。

如下圖所示,雖然是不同的兩個版本,但利用辨識 SHA ID 的手法,乍看之下需要 8 個映像層的建置,最後其實只建造了 5 個。

Docker 的快取特性

映像檔歷史紀錄中的 missing

透過快取的機制更了解映像檔後,根據下方的圖片,由下往上看,就像是 docker image history 一樣,每一個歷史紀錄都代表了一個映像層。

而我們也可以透過歷史紀錄看到每一層最後一次更動的時間是什麼時候。

而最前面的 missing 其實不是錯誤訊息,也不是有什麼檔案缺失,只是這些都是同屬於一個映像檔的一部分,但又礙於 ID 並不是每一個映像層都需要,才用這種方式顯示。

雖然我自己認為這樣會造成一些誤會,但沒辦法,這是 Docker 公司的作法。

歷史紀錄示意圖