Docker(42)- 鏡像原理之聯合文件系統


前言

學習狂神老師的 Docker 系列課程,並總結

 

鏡像是什么

  • 鏡像是一種輕量級、可執行的獨立軟件保,用來打包軟件運行環境和基於運行環境開發的軟件
  • 他包含運行某個軟件所需的所有內容,包括代碼、運行時庫、環境變量和配置文件
  • 所有應用,都可以直接打包 docker 鏡像,就可以直接跑起來

 

如何得到鏡像

  • 從遠程倉庫下載
  • 別人拷貝給你
  • 自己制作一個鏡像 DockerFile

 

UnionFs (聯合文件系統)

  • Union文件系統(UnionFs)是一種分層、輕量級並且高性能的文件系統
  • 他支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下
  • Union文件系統是 Docker 鏡像的基礎
  • 可以通過分層來進行繼承,基於基礎鏡像(沒有父鏡像),可以制作各種具體的應用鏡像
  • 特性:一次同時加載多個文件系統,但從外面看起來,只能看到一個文件系統,聯合加載會把各層文件系統疊加起來,這樣最終的文件系統會包含所有底層的文件和目錄

 

Docker鏡像加載原理

  • Docker 的鏡像實際上由一層一層的文件系統組成,這種層級的文件系統叫 UnionFS
  • boots(boot file system)主要包含 bootloader 和 Kernel, bootloader 主要是引導加載 kernel, Linux 剛啟動時會加 bootfs 文件系統,在 Docker 鏡像的最底層是 boots,幾乎不變
  • 這一層與我們典型的 Linux/Unix 系統是一樣的,包含 bootloader 和 Kernel
  • 當 boot 加載完成之后,整個內核就都在內存中了,此時內存的使用權已由 bootfs 轉交給內核,此時系統也會卸載 bootfs
  • rootfs(root file system),在 bootfs之上,包含的就是典型 Linux 系統中的 /dev、/proc/bin、/etc 等標准目錄和文件
  • rootfs 就是各種不同的操作系統發行版,比如 Ubuntu, Centos 等等

 

平時我們安裝進虛擬機的 CentOS 都是好幾個G,為什么 Docker 這里才200M?

  • 對於個精簡的 OS , rootfs 可以很小,只需要包合最基本的命令,工具和程序庫就可以了
  • 因為底層直接用主機的 kernel,自己只需要提供 rootfs 就可以了
  • 由此可見對於不同的 Linux 發行版, boots 基本是一致的, rootfs 會有差別,因此不同的發行版可以公用 bootfs
  • 所以虛擬機啟動是分鍾級別,容器是秒級!

 

分層理解

下載鏡像的時候看到一層層下載就是分層

思考:為什么Docker鏡像要采用這種分層的結構呢?

  • 最大的好處,我覺得莫過於資源共享了!
  • 比如有多個鏡像都從相同的 Base 鏡像構建而來,那么宿主機只需在磁盤上保留一份 base 鏡像,同時內存中也只需要加載一份 base 鏡像
  • 這樣就可以為所有的容器服務了,而且鏡像的每一層都可以被共享
  • Already exists 代表宿主機已存在鏡像所需的文件,所以不再需要下載,直接使用即可
  • Downloading 代表宿主機沒有所需的文件,所以需要下載,下載完之后就會存在宿主機,以后下載其他鏡像時如果用到這些文件就可以直接拿來用,不用二次下載了

 

如何查看鏡像分層?

docker inspect redis

能看到它分了六層,比如說第一層可能就是安裝 centos,后面幾層就是安裝 redis 所需的緩解經

 

關於鏡像分層的理解

  • 所有的 Docker 鏡像都起始於一個基礎鏡像層,其實就是 rootfs,像 Ubuntu、CentOS
  • 當進行修改或添加新的內容時,就會在當前鏡像層之上,創建新的鏡像層

 

栗子

  • 基於 Ubuntu Linux16.04 創建一個新的鏡像,這就是新鏡像的第一層
  • 如果在該鏡像中添加 Python包,就會在基礎鏡像層之上創建第二個鏡像層
  • 如果繼續添加一個安全補丁,就會創健第三個鏡像層
  • 該鏡像當前已經包含 3 個鏡像層
  • 現在可以把它再次打包成一個新的鏡像(commit)提供給其他人下載,其他人 pull 下來之后就會有三層東西

 

重點

在添加額外的鏡像層的同時,鏡像始終保持是當前所有鏡像的組合

下圖中舉了一個簡單的例子,每個鏡像層包含3個文件,而鏡像包含了來自兩個鏡像層的6個文件

上圖中的鏡像層跟之前圖中的略有區別,主要目的是便於展示文件

 

下圖中展示了一個稍微復雜的三層鏡像,在外部看來整個鏡像只有6個文件,這是因為最上層中的文件7是文件5的一個更新版

這種情況下,上層鏡像層中的文件覆蓋了底層鏡像層中的文件

這樣就使得文件的更新版本作為一個新鏡像層添加到鏡像當中

 

存儲引擎

  • Docker 通過存儲引擎(新版本采用快照機制)的方式來實現鏡像層堆棧,並保證多鏡像層對外展示為統一的文件系統
  • Linux 上可用的存儲引撃有 AUFS、 Overlay2、 Device Mapper、Btrfs 以及 ZFS
  • 每種存儲引擎都基於 Linux 中對應的文件系統或者塊設備技術,井且每種存儲引擎都有其獨有的性能特點
  • Docker 在 Windows上僅支持 windowsfilter 一種存儲引擎,該引擎基於 NTFS 文件系統之上實現了分層和CoW

 

鏡像層合並

  • 下圖展示了與系統顯示相同的三層鏡像
  • 所有鏡像層堆並合井,對外提供統一的視圖

上面有查看 redis 鏡像的 layer 是 6 層,跟上圖差不多,6 個文件就是 6 個 layer

 

特點

  • Docker 鏡像都是只讀的,當容器啟動時,一個新的可寫層加載到鏡像的頂部!
  • 這一層就是我們通常說的容器層,容器之下的都叫鏡像層!

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM