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映象原理之聯合檔案系統和分層理解(範例詳解)的詳細內容,更多請關注TW511.COM其它相關文章!