亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

UnionFS 與 Docker

我們自己在上一節留下了不少問題,在自制 rootfs 有很多不完善的地方,在 Docker 產品的方面,就對這些部分進行了補足, 解決的方案,基本都是圍繞 UnionFS (聯合文件系統)展開的,本節我們會講講 UnionFS 和它在 Docker中 的應用。

1. 什么是文件系統

計算機的文件系統是一種存儲和組織計算機數據的方法,它使得對其訪問和查找變得容易,文件系統使用文件和樹形目錄的抽象邏輯概念代替了硬盤和光盤等物理設備使用數據塊的概念,用戶使用文件系統來保存數據不必關心數據實際保存在硬盤(或者光盤)的地址為多少的數據塊上,只需要記住這個文件的所屬目錄和文件名。在寫入新數據之前,用戶不必關心硬盤上的那個塊地址沒有被使用,硬盤上的存儲空間管理(分配和釋放)功能由文件系統自動完成,用戶只需要記住數據被寫入到了哪個文件中。

一句話總結,文件系統是一套實現了數據的存儲、分級組織、訪問和獲取等操作的抽象數據類型。

2. 什么是 UnionFS

聯合文件系統(Union File System):2004 年由紐約州立大學開發,它可以把多個目錄內容聯合掛載到同一個目錄下,而目錄的物理位置是分開的。UnionFS可以把只讀和可讀寫文件系統合并在一起,具有寫時復制功能,允許只讀文件系統的修改可以保存到可寫文件系統當中。

目前有多種文件系統可以被當作聯合文件系統,CentOS8 使用的是 overlay2,下面,我們嘗試著掛載一個 overlay2 文件系統。

/root/test 目錄下,建立一個unionfs 目錄,它的目錄結構如下(a,b,c是文件,其他都是目錄):

unionfs
├── lower1
│   ├── a
│   └── b
├── lower2
│   └── a
├── merged
├── upper
│   └── c
└── work

進入 unionfs 目錄,使用 mount 命令掛載:

cd unionfs
mount -t overlay overlay -o lowerdir=lower1:lower2,upperdir=upper,workdir=work merged

如上,掛載了一個名為 overlay 的 overlay2 類型的文件系統,掛載點為 merged 目錄。

查看 merged 目錄的層次:

[root@centos8 unionfs]# tree merged
merged
├── a
├── b
└── c

查看這些文件的內容:

[root@centos8 unionfs]# for i in `ls merged`;do echo $i: `cat merged/$i`;done
a: in lower1
b: in lower1
c: in upper

可以看到,從 merged 視角,位于 lower2 的 a 文件被 lower1 的 a 文件覆蓋;b 文件位于 lower1,c 文件位于 upper,符合從高到低 upper->lower1->lower2 的層次結構。

我們按照如下操作來驗證 unionfs 的分層特性:

[root@centos8 unionfs]# touch merged/d
[root@centos8 unionfs]# ls merged/
a  b  c  d
[root@centos8 unionfs]# ls upper/
c  d
[root@centos8 unionfs]# ls lower1
a  b
[root@centos8 unionfs]# ls lower2
a

可以看到對 merged 目錄的改動同步至 upper 目錄中,并不會影響到 lower 目錄。

3. Docker 如何使用 UnionFS?

Docker 的官方文檔中有一張圖片,很好地展示了 Docker 使用 UnionFS 搭建的分層結構的狀態。
圖片描述

使用 UnionFS 搭建的分層結構

圖中的容器是運行在 debian 容器環境中的 apache 網頁應用,這個環境還提供了 emacs 編輯器功能。

將之前我們自己構建的 rootfs 與上面這張圖片對比,會發現我們將所有系統文件、運行庫文件和上層應用,都放到了一個 rootfs 里面,這樣做缺乏靈活性,增大了維護的復雜度。而 Docker 引入了層(layer)的概念,將 rootfs 的內容進行了分層管理,有系統層,運行庫依賴層等等,可以一層接一層進行增量式掛載疊加。啟動容器的時候通過 UnionFS 把相關的層掛載到一個目錄,作為容器的根 rootfs。

借助于 UnionFS,容器內部的更改都被保存到了最上面的讀寫層,而其他層都是只讀的,這樣中間的只讀 rootfs 是可以被多個容器復用的。UnionFS 將文件的更新掛載到老的文件之上,而不去修改那些不更新的內容,這就意味著即使虛擬的文件系統被反復修改,也能保證宿主機空間占用保持一個較低水平。

4. 衍生出的 Docker 概念

4.1 Docker 鏡像

我們將中間只讀的 rootfs 的集合稱為 Docker 鏡像,我們在后面的部分會講到,Docker 鏡像構建時,會一層層構建,前一層是后一層的基礎。每一層構建完就不會再發生改變,后一層上的任何改變只發生在自己這一層。UnionFS 使得鏡像的復用、定制變得更為容易。甚至可以用之前構建好的鏡像作為基礎層,然后進一步添加新的層,以定制自己所需的內容,構建新的鏡像。

4.2 Docker 容器

Docker 容器與我們之前的容器在本質上沒有區別,我們之前的容器更偏向抽象的技術概念,而受到在 Docker 管理約束的容器就是 Docker 容器,它會帶有 Docker 產品的一些特征和功能。

Docker鏡像 和 Docker容器 的關系,就像是面向對象程序設計中的 類 和 實例 一樣,鏡像是靜態的定義,容器是鏡像運行時的實體。
從文件系統來看,Docker容器比Docker鏡像多一層可讀寫的文件系統掛載層,從生命周期來看,Docker容器可以被創建、啟動、停止、刪除、暫停等。

5. 小結

在 rootfs 的基礎上,Docker 公司創新性地提出了使用 UnionFS,多個增量 rootfs 聯合掛載一個完整 rootfs 的方案,通過“分層鏡像”的設計,圍繞 Docker 鏡像,大家甚至可以協同工作,再加上 Docker 官方提供的鏡像倉庫,進一步減少了共享鏡像的成本,這大大提高了開發部署的效率。