容器如何工作:OverlayFS
| 2019-11-23 10:25 評論: 1 收藏: 2
今天早上,我為未來潛在容器雜誌畫了一幅 OverlayFS 的漫畫,我對這個主題感到興奮,想寫一篇關於它的部落格來提供更多詳細資訊。
容器映象很大
容器映象可能會很大(儘管有些很小,例如 alpine linux 才 2.5MB)。Ubuntu 16.04 約為 27 MB,Anaconda Python 發行版為 800MB 至 1.5GB。
你以映象啟動的每個容器都是原始空白狀態,彷彿它只是為使用容器而複製的一份映象複製一樣。但是對於大的容器映象,像 800MB 的 Anaconda 映象,複製一份複製既浪費磁碟空間也很慢。因此 Docker 不會複製,而是採用疊加。
疊加如何工作
OverlayFS,也被稱為 聯合檔案系統或 聯合掛載,它可讓你使用 2 個目錄掛載檔案系統:“下層”目錄和“上層”目錄。
基本上:
- 檔案系統的下層目錄是隻讀的
- 檔案系統的上層目錄可以讀寫
當程式“讀取”檔案時,OverlayFS 檔案系統驅動將在上層目錄中查詢並從該目錄中讀取檔案(如果存在)。否則,它將在下層目錄中查詢。
當程式“寫入”檔案時,OverlayFS 會將其寫入上層目錄。
讓我們使用 mount 製造一個疊加層!
這有點抽象,所以讓我們製作一個 OverlayFS 並嘗試一下!這將只包含一些檔案:我將建立上、下層目錄,以及用來掛載合併的檔案系統的 merged
目錄:
$ mkdir upper lower merged work
$ echo "I'm from lower!" > lower/in_lower.txt
$ echo "I'm from upper!" > upper/in_upper.txt
$ # `in_both` is in both directories
$ echo "I'm from lower!" > lower/in_both.txt
$ echo "I'm from upper!" > upper/in_both.txt
合併上層目錄和下層目錄非常容易:我們可以透過 mount
來完成!
$ sudo mount -t overlay overlay
-o lowerdir=/home/bork/test/lower,upperdir=/home/bork/test/upper,workdir=/home/bork/test/work
/home/bork/test/merged
在執行此操作時,我不斷收到一條非常煩人的錯誤訊息,內容為:mount: /home/bork/test/merged: special device overlay does not exist.
。這條訊息是錯誤的,實際上只是意味著我指定的一個目錄缺失(我寫成了 ~/test/merged
,但它沒有被展開)。
讓我們嘗試從 OverlayFS 中讀取其中一個檔案!檔案 in_both.txt
同時存在於 lower/
和 upper/
中,因此應從 upper/
目錄中讀取該檔案。
$ cat merged/in_both.txt
"I'm from upper!
可以成功!
目錄的內容就是我們所期望的:
find lower/ upper/ merged/
lower/
lower/in_lower.txt
lower/in_both.txt
upper/
upper/in_upper.txt
upper/in_both.txt
merged/
merged/in_lower.txt
merged/in_both.txt
merged/in_upper.txt
建立新檔案時會發生什麼?
$ echo 'new file' > merged/new_file
$ ls -l */new_file
-rw-r--r-- 1 bork bork 9 Nov 18 14:24 merged/new_file
-rw-r--r-- 1 bork bork 9 Nov 18 14:24 upper/new_file
這是有作用的,新檔案會在 upper
目錄建立。
刪除檔案時會發生什麼?
讀寫似乎很簡單。但是刪除會發生什麼?開始試試!
$ rm merged/in_both.txt
發生了什麼?讓我們用 ls
看下:
ls -l upper/in_both.txt lower/lower1.txt merged/lower1.txt
ls: cannot access 'merged/in_both.txt': No such file or directory
-rw-r--r-- 1 bork bork 6 Nov 18 14:09 lower/in_both.txt
c--------- 1 root root 0, 0 Nov 18 14:19 upper/in_both.txt
所以:
in_both.txt
仍在lower
目錄中,並且保持不變- 它不在
merged
目錄中。到目前為止,這就是我們所期望的。 - 但是在
upper
中發生的事情有點奇怪:有一個名為upper/in_both.txt
的檔案,但是它是字元裝置?我想這就是 overlayfs 驅動表示刪除的檔案的方式。
如果我們嘗試複製這個奇怪的字元裝置檔案,會發生什麼?
$ sudo cp upper/in_both.txt upper/in_lower.txt
cp: cannot open 'upper/in_both.txt' for reading: No such device or address
好吧,這似乎很合理,複製這個奇怪的刪除訊號檔案並沒有任何意義。
你可以掛載多個“下層”目錄
Docker 映象通常由 25 個“層”組成。OverlayFS 支援具有多個下層目錄,因此你可以執行:
mount -t overlay overlay
-o lowerdir:/dir1:/dir2:/dir3:...:/dir25,upperdir=...
因此,我假設這是有多個 Docker 層的容器的工作方式,它只是將每個層解壓縮到一個單獨的目錄中,然後要求 OverlayFS 將它們全部合併在一起,並使用一個空的上層目錄,容器將對其進行更改。
Docker 也可以使用 btrfs 快照
現在,我使用的是 ext4,而 Docker 使用 OverlayFS 快照來執行容器。但是我曾經用過 btrfs,接著 Docker 將改為使用 btrfs 的寫時複製快照。(這是 Docker 何時使用哪種儲存驅動的列表)
以這種方式使用 btrfs 快照會產生一些有趣的結果:去年某個時候,我在筆記本上執行了數百個臨時的 Docker 容器,這導致我用盡了 btrfs 後設資料空間(像這個人一樣)。這真的很令人困惑,因為我以前從未聽說過 btrfs 後設資料,而且弄清楚如何清理檔案系統以便再次執行 Docker 容器非常棘手。(這個 docker github 上的提案描述了 Docker 和 btrfs 的類似問題)
以簡單的方式嘗試容器功能很有趣!
我認為容器通常看起來像是在做“複雜的”事情,我認為將它們分解成這樣很有趣。你可以執行一條 mount
咒語,而實際上並沒有做任何與容器相關的其他事情,看看疊加層是如何工作的!
via: https://jvns.ca/blog/2019/11/18/how-containers-work–overlayfs/
作者:Julia Evans 選題:lujun9972 譯者:geekpi 校對:wxy
相關文章
- docker容器技術基礎之聯合檔案系統OverlayFSDocker
- 容器 工作目錄
- 容器的工作原理和隔離機制
- 同步容器、併發容器、阻塞佇列、雙端佇列與工作密取佇列
- Servlet 如何工作Servlet
- web 如何工作Web
- docker建立容器後如何使用Docker
- 如何理解 Laravel 的 IoC 容器Laravel
- 容器引擎Docker和容器編排kubernetes如何優雅的收集容器日誌Docker
- 從零開始寫 Docker(五)---基於 overlayfs 實現寫操作隔離Docker
- 如何檢視Docker容器環境變數,如何向容器傳遞環境變數Docker變數
- 紅帽推出Ansible原生容器工作流專案
- 如何快速部署容器化應用
- 如何修改Docker容器埠對映?Docker
- 如何在Docker容器中使用ArthasDocker
- GPS如何工作?
- 如何拯救工作列
- 雲原生時代,如何“玩轉”容器安全?
- 如何讓 Bean 深度感知 Spring 容器BeanSpring
- 論應該如何工作
- DNS是如何工作的?DNS
- Cucumber是如何工作的?
- Javascript是如何工作的JavaScript
- https如何工作的HTTP
- Orchard是如何工作的?
- 如何找實習工作
- CDN是如何工作的?
- 如何利用番茄工作法學習與工作
- 當容器應用越發廣泛,我們又該如何監測容器?
- Spring 原始碼 (2)Spring IOC 容器 前戲準備工作Spring原始碼
- 用於HPC和深度學習工作負載的容器技術深度學習負載
- 雲上跑容器,如何降低儲存成本
- MySQL是如何做容器測試的?MySql
- 小程式容器技術,該如何選擇?
- 如何合理使用 CPU 管理策略,提升容器效能?
- Docker 如何動態修改容器埠對映Docker
- 如何在生產環境執行容器
- 如何在 Windows 上執行 Linux 容器WindowsLinux