天天看點

用一個實際例子了解Docker volume工作原理

要了解Docker Volume,首先我們需要了解Docker檔案系統的工作原理。Docker鏡像是由多個檔案系統的隻讀層疊加而成。當一個容器通過指令docker run啟動時,Docker會加載隻讀鏡像層并在鏡像棧頂部添加一個讀寫層。如果運作中的容器修改了現有的一個已經存在的檔案,那該檔案将會從讀寫層下面的隻讀層複制到讀寫層,但是該檔案的隻讀版本依然存在,隻不過已經被讀寫層中該檔案的副本所隐藏。

當删除Docker容器,并通過該鏡像重新啟動時,之前在讀寫層的更改将會丢失。在Docker中,隻讀層及在頂部的讀寫層的組合被稱為Union File System(聯合檔案系統),簡稱UnionFS,它用到了一個重要的資源管理技術,叫寫時複制。寫時複制(copy-on-write),也叫隐式共享,是一種對可修改資源實作高效複制的資源管理技術。對于一個重複資源,若不修改,則無需立刻建立一個新的資源,該資源可以被共享使用。當發生修改的時候,才會建立新資源。這會大大減少對于未修改資源複制的消耗。其實COW這個概念對程式設計人員來說一點也不陌生,廣泛用在各種領域,比如ABAP裡對于内表(Internal table)的拷貝動作,Java字元串的拷貝實作等等。Docker基于UnionFS去建立containers。

我們下面看一個實際例子。

使用指令行docker run --help檢視這個指令的幫助文檔。 -h 的作用是指定容器的主機名。

使用指令行建立一個新的容器:

docker run -it --name jerry-container-test -h CONTAINER -v /data busybox /bin/sh

名稱為jerry-container-test, 用-v建立了一個volume /data

建立完畢之後,在容器裡執行cd /data進入這個目錄,這個時候還是空的。

docker ps檢視容器狀态:

現在我想知道主機上為了實作這個volume,使用了哪個internal目錄。

用指令docker inspect jerry-container-test檢視關鍵字"volumes":

得到了容器裡/data在主機上實作的目錄:

/var/lib/docker/volumes/96aa969033ee7e6d7ff607a0a47de5a5866613a422518ed3f86fee6240bae8cc/_data

現在我在主機上使用touch指令在這個目錄下直接建立一個檔案:

sudo touch /var/lib/docker/volumes/96aa969033ee7e6d7ff607a0a47de5a5866613a422518ed3f86fee6240bae8cc/_data/test.s

現在切換到容器裡,用ls也能看到直接在主機上用touch指令在internal folder裡建立的檔案了。

要擷取更多Jerry的原創文章,請關注公衆号"汪子熙":