這篇文章為大家帶來了關於Docker映像原理之聯合文件系統和分層理解的相關知識,其中包括聯合文件系統、分層結構和分層實踐的相關問題,希望對大家有幫助。
UnionFS(聯合檔案系統)
UnionFS( 聯合檔案系統):Union檔案系統(UnionFS )是一種分層、輕量級且高效能的檔案系統,它支援對檔案系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬檔案系統下(unite several directories into a single virtualfilesystem)。 Union檔案系統是Docker映像的基礎。鏡像可以透過分層來進行繼承,基於基礎鏡像(沒有父鏡像),可以製作各種特定的應用鏡像。
另外,不同 Docker 容器就可以共用一些基礎的檔案系統層,同時再加上自己獨有的改動層,大大提高了儲存的效率。
Docker 中使用的 AUFS(AnotherUnionFS)就是一種聯合檔案系統。 AUFS 支援為每一個成員目錄(類似Git 的分支)設定唯讀(readonly)、讀寫(readwrite)和寫出(whiteout-able)權限, 同時AUFS 裡有一個類似分層的概念, 對唯讀權限的分支可以邏輯上進行增量地修改(不影響只讀部分的)。
Docker 目前支援的聯合檔案系統種類包括 AUFS, btrfs, vfs 和 DeviceMapper。
特性:一次同時載入多個檔案系統,但從外面看起來,只能看到一個檔案系統,聯合載入會把各層檔案系統疊加起來,這樣最終的檔案系統會包含所有底層的檔案和目錄。
base 鏡像
base 鏡像簡單來說就是不依賴其他任何鏡像,完全從0開始建起,其他鏡像都是建立在他的之上,可以比喻為大樓的地基,docker鏡像的始祖。
base 鏡像有兩層意義:(1)不依賴其他鏡像,從 scratch 建構;(2)其他鏡像可以之為基礎進行擴展。
所以,能稱為 base 映像的通常都是各種 Linux 發行版的 Docker 映像,像是 Ubuntu, Debian, CentOS 等。
Docker 映像載入原理
docker的映像其實是由一層一層的檔案系統所組成,而這種層級的檔案系統就是UnionFS。
典型的Linux 啟動到運行需要兩個FS,bootfs rootfs:
bootfs(boot file system)主要包含bpotloader 和kernel,bootloader主要是引導載入kernel,Linux 剛啟動時會載入bootfs檔案系統,在Docker映像的最底層就是bootfs。這一層與我們典型的Linux/Unix系統是一樣的,包含boot載入器bootloader和核心kernel。當boot載入完成之後整個內核就都在記憶體中了,此時記憶體的使用權已由bootfs轉交給內核,此時系統也會卸載bootfs。
rootfs (root file system),在bootfs之上。包含的就是典型Linux系統中的/dev, /proc, /bin, /etc等標準目錄和檔案。 roots就是各種不同的作業系統發行版,像是Ubuntu,Centos等等。
Docker 映像中為什麼沒有核心
從映像大小上面來說,一個比較小的映像只有1KB多點,或幾MB,而核心檔案需要幾十MB, 因此鏡像裡面是沒有內核的,鏡像在被啟動為容器後將直接使用宿主機的內核,而鏡像本身則只提供相應的rootfs,即係統正常運行所必須的用戶空間的文件系統,例如/dev/,/proc,/bin,/etc等目錄,所以容器當中基本上是沒有/boot目錄的,而/boot當中保存的就是與核心相關的檔案和目錄。
由於容器啟動和運行過程中是直接使用了宿主機的內核,不會直接調用過物理硬件,所以也不會涉及到硬體驅動,因此也用不上內核和驅動。而如果虛擬機器技術,對應每個虛擬機器都有自已獨立的核心
Docker 映像是一種分層結構,每一層都建構在其他層之上,從而實現增量增加內容的功能,Docker 映像下載的時候也是分層下載,以下載redis映像為例:
##可以看到,新鏡像是從base 鏡像一層一層疊加產生的。每安裝一個軟體,就在現有鏡像的基礎上增加一層。 為什麼 Docker 映像要採用這種分層結構呢?最大的好處,莫過於是資源共享了。例如有多個鏡像都從相同的Base鏡像建置而來,那麼宿主機只需在磁碟上保留一份base鏡像,同時記憶體中也只需要載入一份base鏡像,這樣就可以為所有的容器服務了,而且鏡像的每一層都可以被分享。
可寫入的容器層
Docker 映像都只是可讀(read-only)的,當容器啟動時,一個新的可寫層被載入到鏡像頂部。
這新的一層就是可寫入的容器層,容器底下都叫做鏡像層。
Docker透過一個修改時複製策略copy-on-write來保證base映像的安全性,以及更高的效能和空間利用率。
從最上層的鏡像層開始往下找,找到後讀取到記憶體中,若已經在記憶體中,可以直接使用。換句話說,運行在同一台機器上的Docker容器共用運行時相同的檔案。
從上往下查找,找到後複製到容器層,對容器來說,可以看到的是容器層的這個文件,看不到鏡像圖層裡的文件,然後直接修改容器層的文件。
從上往下查找,找到後在容器中記錄刪除,並不是真正的刪除,而是軟刪除。這導致鏡像體積只會增加,不會減少。
直接在最上層的容器可寫層增加,不會影響鏡像層。
所有對容器的改動,無論新增、刪除、或修改檔案都只會發生在容器層中。只有容器層是可寫入的,容器層下面的所有鏡像層都是唯讀的,所以鏡像可以被多個容器共用。
透過鏡像建立容器,然後對容器層進行操作,鏡像層不動,再把操作後的容器層和鏡像層打包成一個新的鏡像提交。
docker commit:用容器建立一個新的映像。
語法:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS說明:
使用實例:透過鏡像建立容器,然後對容器層進行操作,再把操作後的容器層和鏡像層打包成一個新的鏡像提交。
1、先下載tomcat 映像
2、透過tomcat 映像建立運行tomcat 容器:
docker run -d --name="tomcat01" tomcat
3、進入正在運行的tomcat容器:
docker exec -it tomcat01 /bin/bash
4、把tomcat容器webapps.dist目錄下的檔案拷貝到webapps目錄下:
cp -r webapps.dist/* webapps
5、docker commit 提交映像
#將容器dc904437d987 儲存為新的映像,並添加提交人資訊和說明信息,提交後的鏡像名為tomcatplus,版本為1.0:
docker commit -a="wanli" -m="add webapps files" dc904437d987 tomcatplus:1.0
可以看到commit提交後的新tomcat 鏡像大小比原來的tomcat鏡像要大一點,因為我們在容器層中進行了複製檔案操作。
推薦學習:《docker影片教學》
以上是Docker鏡像原理之聯合檔案系統與分層理解(實例詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!