Docker容器中資料兩種持久化儲存方式:卷和掛載宿主目錄

fengbingchun發表於2020-11-17

映象使用的是分層儲存,容器也是如此。每一個容器執行時,是以映象為基礎層,在其上建立一個當前容器的儲存層,我們可以稱這個為容器執行時讀寫而準備的儲存層為容器儲存層。容器儲存層的生存週期和容器一樣,容器消亡時,容器儲存層也隨之消亡。因此,任何儲存於容器儲存層的資訊都會隨容器刪除而丟失。

按照Docker最佳實踐的要求,容器不應該向其儲存層內寫入任何資料,容器儲存層要保持無狀態化。所有的檔案寫入操作,都應該使用資料卷(Volume)、或者繫結宿主目錄,在這些位置的讀寫會跳過容器儲存層,直接對宿主(或網路儲存)發生讀寫,其效能和穩定性更高。

(1).卷(volumes):是宿主機器的檔案系統的一部分,由Docker進行管理(在Linux,儲存於/var/lib/docker/volumes/)。非Docker程式不應該去修改這些檔案。Docker推薦使用捲進行持久化資料。卷可支援卷驅動(volume drivers),該驅動允許使用者將資料儲存到遠端主機或雲服務商(cloud provider)或其它。沒有名字的卷叫匿名卷(anonymous volume),有名字的卷叫命名卷(named volume)。匿名卷沒有明確的名字,當被初始化時,會被賦予一個隨機名字。

卷是一個可供一個或多個容器使用的特殊目錄,它繞過UFS,可以提供很多有用的特性:A.卷可以在容器之間共享和重用;B.對卷的修改會立馬生效;C.對卷的更新,不會影響映象;D.卷預設會一直存在,即使容器被刪除。

卷的使用,類似於Linux下對目錄或檔案進行mount,映象中的被指定為掛載點的目錄中的檔案會複製到卷中(僅卷為空時會複製)。卷是被設計用來持久化資料的,它的生命週期獨立於容器,Docker不會在容器被刪除後自動刪除卷,並且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的卷。

(2).掛載宿主目錄(bind mounts, 繫結掛載):通過將宿主機器的路徑掛載到容器裡的這種方式,從而資料持久化,因此繫結掛載可將資料儲存在宿主機器的檔案系統的任何地方。非Docker程式可修改這些檔案。繫結掛載是Docker早期就存在的,相比起卷,繫結掛載十分簡單明瞭。在開發Docker應用時,應使用命名卷(named volume)代替繫結掛載,因為使用者不能對繫結掛載進行Docker CLI(command line interface, 命令列介面)命令操作。

繫結掛載常用於:A.同步配置檔案,如:將宿主主機的DNS配置檔案(/etc/resolv.conf)同步至容器中;B.在開發程式時,將原始碼或Artifact同步至容器中。這種用法與Vagrant類似。

卷相關操作命令如下:

docker volume create vol1 # 建立一個卷,如卷名為vol1 
docker volume ls # 檢視所有的卷 
docker volume inspect vol1 # 檢視指定卷的資訊,如卷vol1
# 啟動一個掛載卷的容器,如將卷名為"vol1"掛載到容器的/home/fengbingchun目錄;新建的容器名為"yyyy"; -P,隨機埠對映,容器內部埠隨機對映到主機的埠
docker run -it -P --name yyyy --mount source=vol1,target=/home/fengbingchun fengbingchun/ubuntu:16.04 /bin/bash
docker inspect yyyy # 檢視容器中卷的具體資訊,卷的資訊在"Mounts"欄位內,"yyyy"為容器名
docker volume rm vol1 # 刪除卷,如卷名為"vol1",需要卷"vol1"沒有被任何容器使用時才能刪除
docker volume prune # 刪除所有沒有被使用的卷

掛載主機目錄相關操作命令如下:

# 掛載一個本地主機的目錄到容器中去,新建的容器名為"test"; -P,隨機埠對映,容器內部埠隨機對映到主機的埠;
# "/home/GitHub"為本地主機目錄,本地目錄的路徑必須是絕對路徑;"/home/fengbingchun"為掛載到容器此目錄;Docker掛載主機目錄的預設許可權是讀寫
docker run -it -P --name test --mount type=bind,source=/home/GitHub,target=/home/fengbingchun fengbingchun/ubuntu:16.04 /bin/bash # linux
docker run -it -P --name test --mount type=bind,source=e:\GitCode,target=/home/fengbingchun fengbingchun/ubuntu:16.04 /bin/bash # windows
docker inspect yyyy # 檢視容器中掛載主機目錄的具體資訊,掛載主機目錄的配置資訊在"Mounts"欄位內,"yyyy"為容器名

 

相關文章