「Allen 談 Docker 系列」之一圖看盡 docker 容器文件系統

jopen 9年前發布 | 15K 次閱讀 Docker
 

「Allen 談 Docker 系列」之一圖看盡 docker 容器文件系統

「Allen 談 Docker 系列」DaoCloud 正在啟動 Docker 技術系列文章,每周都會為大家推送一期真材實料的精選 Docker 文章。主講人為 DaoCloud 核心開發團隊成員 Allen 孫宏亮,他是 InfoQ《Docker 源碼分析》專欄作者,即將出版《Docker 源碼分析》一書。Allen 接觸 Docker 近兩年,愛鉆研系統實現原理,及 Linux 操作系統。

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 容器的哪些內容不在 Docker 鏡像中。

Docker 容器文件系統

那就讓我們一圖看盡 Docker 容器的文件系統:

「Allen 談 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 鏡像體現

毫無疑問,Docker 鏡像是由 Dockerfile 構建而成,我們也可以看到圖中下四層被標記為 Docker 鏡像。作為 Docker 技術的核心,我們必須了解 Docker 如何構建鏡像,以及 Docker 鏡像構建之后的產物是什么。

初次接觸 Docker,了解層級管理的 Docker 鏡像之后,很容易就認為:每一層 Docker 鏡像中都含有相應的文件系統文件。其實不然,以上 Dockerfile 中的四條命令,則是一個很好的佐證。

  • 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 以及容器的  hostshostnameresolv.conf 文件等都會掛載到這里。需要額外注意的是:雖然 Docker 容器有能力在可讀寫層看到  VOLUME 以及  hosts 文件等內容,但那都僅僅是掛載點,真實內容位于宿主機上。

總結

Docker 鏡像屬靜態,Docker 容器屬動態,兩者之間有著千絲萬縷的關系。從 Docker 容器文件系統的角度來認識兩者,我相信會對大家有很大的幫助。

Docker 鏡像以及 Docker 容器文件系統,絕對是非常細致的內容,基于這些概念,實在有太多有意思的話題可以展開,本系列后續會有以下多篇文章來分析:

  1. 深刻理解 Docker 鏡像大小
  2. 其實  docker commit  很簡單
  3. 不得不說的  docker save  與  docker export  區別
  4. 為什么有些容器文件動不得
  5. 打破  MNT Namespace  的容器  VOLUME

欲知 Docker 鏡像更精彩的內容,且聽下回分解

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!