Docker鏡像進階:瞭解其背後的技術原理

什麼是 docker 鏡像docker

  docker 鏡像是一個只讀的 docker 容器模板,含有啓動 docker 容器所需的文件系統結構及其內容,所以是啓動一個 docker 容器的基礎。docker 鏡像的文件內容以及一些運行 docker 容器的配置文件組成了 docker 容器的靜態文件系統運行環境:rootfs。能夠這麼理解,docker 鏡像是 docker 容器的靜態視角,docker 容器是 docker 鏡像的運行狀態。咱們能夠經過下圖來理解 docker daemon、docker 鏡像以及 docker 容器三者的關係(此圖來自互聯網):json

Docker鏡像進階:瞭解其背後的技術原理

  從上圖中咱們能夠看到,當由 ubuntu:14.04 鏡像啓動容器時,ubuntu:14.04 鏡像的鏡像層內容將做爲容器的 rootfs;而 ubuntu:14.04 鏡像的 json 文件,會由 docker daemon 解析,並提取出其中的容器執行入口 CMD 信息,以及容器進程的環境變量 ENV 信息,最終初始化容器進程。固然,容器進程的執行入口來源於鏡像提供的 rootfs。ubuntu

rootfs安全

  rootfs 是 docker 容器在啓動時內部進程可見的文件系統,即 docker 容器的根目錄。rootfs 一般包含一個操做系統運行所需的文件系統,例如可能包含典型的類 Unix 操做系統中的目錄系統,如 /dev、/proc、/bin、/etc、/lib、/usr、/tmp 及運行 docker 容器所需的配置文件、工具等。在傳統的 Linux 操做系統內核啓動時,首先掛載一個只讀的 rootfs,當系統檢測其完整性以後,再將其切換爲讀寫模式。而在 docker 架構中,當 docker daemon 爲 docker 容器掛載 rootfs 時,沿用了 Linux 內核啓動時的作法,即將 rootfs 設爲只讀模式。在掛載完畢以後,利用聯合掛載(union mount)技術在已有的只讀 rootfs 上再掛載一個讀寫層。這樣,可讀寫的層處於 docker 容器文件系統的最頂層,其下可能聯合掛載了多個只讀的層,只有在 docker 容器運行過程當中文件系統發生變化時,纔會把變化的文件內容寫到可讀寫層,並隱藏只讀層中的舊版本文件。架構

Docker 鏡像的主要特色工具

  爲了更好的理解 docker 鏡像的結構,下面介紹一下 docker 鏡像設計上的關鍵技術。操作系統

  分層docker 鏡像是採用分層的方式構建的,每一個鏡像都由一系列的 "鏡像層" 組成。分層結構是 docker 鏡像如此輕量的重要緣由。當須要修改容器鏡像內的某個文件時,只對處於最上方的讀寫層進行變更,不覆寫下層已有文件系統的內容,已有文件在只讀層中的原始版本仍然存在,但會被讀寫層中的新版本所隱藏。當使用 docker commit 提交這個修改過的容器文件系統爲一個新的鏡像時,保存的內容僅爲最上層讀寫文件系統中被更新過的文件。分層達到了在不的容器同鏡像之間共享鏡像層的效果。設計

  寫時複製docker 鏡像使用了寫時複製(copy-on-write)的策略,在多個容器之間共享鏡像,每一個容器在啓動的時候並不須要單獨複製一份鏡像文件,而是將全部鏡像層以只讀的方式掛載到一個掛載點,再在上面覆蓋一個可讀寫的容器層。在未更改文件內容時,全部容器共享同一份數據,只有在 docker 容器運行過程當中文件系統發生變化時,纔會把變化的文件內容寫到可讀寫層,並隱藏只讀層中的老版本文件。寫時複製配合分層機制減小了鏡像對磁盤空間的佔用和容器啓動時間。3d

  內容尋址在 docker 1.10 版本後,docker 鏡像改動較大,其中最重要的特性即是引入了內容尋址存儲(content-addressable storage) 的機制,根據文件的內容來索引鏡像和鏡像層。與以前版本對每一個鏡像層隨機生成一個 UUID 不一樣,新模型對鏡像層的內容計算校驗和,生成一個內容哈希值,並以此哈希值代替以前的 UUID 做爲鏡像層的惟一標識。該機制主要提升了鏡像的安全性,並在 pull、push、load 和 save 操做後檢測數據的完整性。另外,基於內容哈希來索引鏡像層,在必定程度上減小了 ID 的衝突而且加強了鏡像層的共享。對於來自不一樣構建的鏡像層,主要擁有相同的內容哈希,也能被不一樣的鏡像共享。blog

相關文章
相關標籤/搜索