【Docker】7. 映象-載入原理、分層原理、commit映象

把蘋果v咬哭發表於2021-05-19

一、什麼是映象

映象是一種輕量級、可執行的獨立軟體包,用來打包軟體執行環境和基於執行環境開發的軟體。
它包含執行某個軟體所需的所有內容,包括程式碼、執行時環境、庫、環境變數和配置檔案。
所有的應用,直接打包成docker映象,就可以直接跑起來。

如何得到映象:

  • 從遠端倉庫下載
  • 從其他地方copy
  • 自己製作一個映象 DockerFile

二、docker映象載入原理

1. 聯合檔案系統UnionFS

UnionFS是一種分層、輕量級並且高效能的檔案系統。支援對檔案系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄
掛載到同一個虛擬檔案系統下。這個在我們下載映象的時候,就可以看到這樣的效果。


比如有涉及到相同的檔案,那麼就可以共用了,極大節省資源。

UnionFS是docker映象的基礎,映象可以通過分層來進行繼承,基於基礎映象(沒有父映象),可以
製作各種具體的應用映象。

特性:一次同時載入多個檔案系統,但從外面看起來,只能看到一個檔案系統,聯合載入會把各層檔案系統疊加起來,這樣最終的檔案系統會
包含所有底層的檔案和目錄。

2. 映象載入原理

docker的映象實際上由一層一層的檔案系統組成,這種層級檔案系統就是上述的UnionFS。接著,在內部又分為2部分:

  • bootfs(boot file system):docker映象的最底層是bootfs,主要包含bootloader(載入器)和kernel(核心)。
    bootloader主要是引導載入kernel,linux剛啟動時會載入bootfs檔案系統。這一層與典型的linux/Unix系統一樣,包含bootloader和kernel。
    當boot載入完成後,整個核心就在記憶體中了,此時記憶體的使用權已由bootfs轉交給了核心,此時系統也會解除安裝bootfs。
    這裡的載入,可以理解為,我們windows電腦開機時候,從黑屏到進入作業系統的過程。

  • rootfs(root file system):在bootfs之上,包含的就是典型linux系統中的/dev、/proc、/bin、/etc等標準目錄和檔案。
    rootfs就是各種不同的作業系統發行版,比如Ubuntu、Centos等等。

如圖所示:

圖中以debian系統為例,從左到右,分為3個過程:

  • 圖1,開始的狀態,下載了一個debian系統。
  • 圖2,安裝了一個emacs,這時候可以看到在圖1基礎上,加了一層Image。
  • 圖3,又裝了一個Apache,此時在圖2的基礎上再加了一層Image。

說明了docker的映象實際上是由層一層的檔案系統組成的。對於不同的的linux發行版本,bootfs基本是一致的,rootfs會有差別,所以不同的
發行版可以共用bootfs。

另外,在docker上的作業系統通常都是精簡版的,在VM上安裝個centos映象大小1個G多,而在docker上的centos映象只有200M大小。
因為底層直接用主機的核心,自己只需要提供rootfs就行了,所以rootfs可以很小,只需要包含最基本的命令、工具和程式庫即可。
這樣一來,啟動速度也快了,因為最浪費時間的引導載入過程沒了。

三、分層原理

知道了映象的載入原理,不妨再回頭看下映象分層的原理。之前提過,映象下載的時候是分層下載的,有些層如果已經存在了,就無需再次下載。
比如我下載一個redis的映象。

這種方式最大的好處就在於資源共享。比如有多個映象都從相同的BASE映象構建來的,那麼宿主機只需要在磁碟上保留1分BASE映象,同時記憶體中
也只需要載入一份BASE映象,這樣所有的容器都可以使用。另外,映象的每一層都是可以共享的。

可以通過docker image inspect來檢視映象的分層,比如檢視剛才下載的redis映象:

docker image inspect redis:latest 

所有的docker映象都起始於一個基礎映象層,當進行修改或者增加新的內容時,就會在當前映象層之上,建立新的映象層。
比如:

我現在要製作一個映象。

  1. 這個映象基於Ubuntu linux 16.04,這也是映象的第一層。
  2. 繼續還要安裝python包,就會在第一層之上建立第二個映象層。
  3. 繼續打補丁的話,還會再建立第三個映象層。

注意的是:
在新增額外的映象層的同時,映象始終保持是當前所有映象的組合,如下圖:

這裡每個映象層包含了3個檔案,而映象則是包含了來自2個映象層的6個檔案。

現在,如果第二層中的 檔案5 需要升級版本。這時候上層映象中的檔案會覆蓋底層映象中對應的檔案,使得檔案裡更新版本作為一個新映象層新增到映象當中。

docker 通過儲存引擎的方式來實現映象層堆疊,並保證多映象層對外展示為統一的檔案系統。

四、commit映象

通過上面的瞭解,現在已經知道映象的結構原理,那麼我們自己就可以製作一個映象來。

比如,現在pull一個tomcat映象作為基礎層,我啟動這個映象後,在容器裡做了一些我自己的改動,我覺得我的這些改動很好,映象變得更好用了。那麼我需要
來儲存這個容器的狀態,通過commit命令,提交映象。

docker commit -m="提交描述資訊" -a="作者" 容器id 目標映象名稱:版本標籤

執行tomcat後,進入到webapps下,發現是沒有專案的,因為是閹割版。

現在我把webapps.dist下的所有內容copy到webapps下。

現在我用ip:8080就可以訪問到專案了。

現在我提交這個改動過後的容器。

docker commit -m="pingguo first commit image" -a="pingguo" 03844ff66434 tomcatpingguo:1.0

提交成功後,docker images檢視映象,發現已經儲存在本地。

通過自己的提交映象操作,再回過來體會下映象的分層,是不是理解更深刻了些?

相關文章