Dockerfile是軟件的原材料,Docker鏡像是軟件的交付品,而Docker容器則可以認為是軟件的運行態。從應用軟件的角度來看,Dockerfile、Docker鏡像與Docker容器分別代表軟件的三個不同階段,Dockerfile面向開發,Docker鏡像成為交付標準,Docker容器則涉及部署與運維,三者缺一不可,合力充當Docker體系的基石。
Docker鏡像
Docker鏡像是Dockerfile的產物,是Docker容器的前提,大有承前啟后之意。Docker技術發展兩年有余,相信大家很早就聽說過Docker大多采用聯合文件系統
(Union Filesystem),為Docker容器提供文件系統服務。
關于Docker鏡像,有以下特性:
- 由Dockerfile生成
- 呈現層級結構
- 每層鏡像包含:鏡像文件以及鏡像json元數據信息
Docker容器
Docker容器是Docker鏡像的運行態體現。概括而言,就是在Docker鏡像之上,運行進程。進程啟動的方式有兩種,用戶即可以選擇運行自己另行指定的命令,也可以選擇運行Docker鏡像內部指定的命令。
Docker容器的文件系統,可以說大部分由Docker鏡像來提供。為什么說是大部分呢?其實是有原因的,鏡像內容雖多,但依然不是全部。
Docker容器文件系統
那就讓我們一圖看盡Docker容器的文件系統:
上圖從一個較為全面的角度闡述了Dockerfile、Docker鏡像與Docker容器三者的關系。
Dockerfile體現Docker容器已經在運行,但是追本溯源,我們依然可以找到Dockerfile的影子。上圖中,我們可以發現,Docker容器依附Docker鏡像,而Docker鏡像的Dockerfile是這樣的:
FROM ubuntu:14.04
ADD run.sh
VOLUME /data
CMD ["./run.sh"]
我們可以看到,以上Dockerfile中的每一條命令,都在Docker鏡像中以一個獨立鏡像層的形式存在。
毫無疑問,Docker鏡像是由Dockerfile構建而成,我們也可以看到圖中下4層被標記為Docker鏡像。作為Docker技術的核心,我們必須了解Docker如何構建鏡像,以及Docker鏡像構建之后的產物是什么。
初次接觸Docker,了解層級管理的Docker鏡像之后,很容易就認為:每一層Docker鏡像中都含有相應的文件系統文件。其實不然,以上Dockerfile中的4條命令,則是一個很好的佐證。
FROM ubuntu:14.04
:設置基礎鏡像,此時會使用基礎鏡像ubuntu:14.04的所有鏡像層,為簡單起見,圖中將其作為一個整體展示。
ADD run.sh /
:將Dockerfile所在目錄的文件run.sh加至鏡像的根目錄,此時新一層的鏡像只有一項內容,即根目錄下的run.sh.
VOLUME /data
:設定鏡像的VOLUME,此VOLUME在容器內部的路徑為/data。需要注意的是,此時并未在新一層的鏡像中添加任何文件,但更新了鏡像的json文件,以便通過此鏡像啟動容器時獲取這方面的信息。
CMD ["./run.sh"]
:設置鏡像的默認執行入口,此命令同樣不會在新建鏡像中添加任何文件,僅僅在上一層鏡像json文件的基礎上更新新建鏡像的json文件。
Docker容器體現涉及到Docker容器,便是動態的內容,一切似乎都有了生命。上文曾提及,Docker容器的文件系統中不僅包含Docker鏡像。此言不虛,圖中的頂上兩層,就是Docker為Docker容器新建的內容,而這兩層恰恰不屬于鏡像范疇。
這兩層分別為Docker容器的初始層(Init Layer)與可讀寫層(Read-Write Layer),初始層中大多是初始化容器環境時,與容器相關的環境信息,如容器主機名,主機host信息以及域名服務文件等。
再來看可讀寫層,這一層的作用非常大,Docker的鏡像層以及頂上的兩層加起來,Docker容器內的進程只對可讀寫層擁有寫權限,其他層對進程而言都是只讀的(Read-Only)。如AUFS等文件系統下,寫下層鏡像內容即會涉及COW(Copy-on-Write)技術。另外,關于VOLUME以及容器的hosts、hostname、resolv.conf文件等都會掛載到這里。需要額外注意的是:雖然Docker容器有能力在可讀寫層看到VOLUME以及hosts文件等內容,但那都僅僅是掛載點,真實內容位于宿主機上。