docker技術(shù)剖析--數(shù)據(jù)卷

2018-06-08 18:09 更新

防偽碼:寧可枝頭抱香死,何曾吹落北風(fēng)中。

前言:

1、想要了解Docker Volume,首先我們需要知道Docker的文件系統(tǒng)是如何工作的。Docker鏡像是由多個文件系統(tǒng)(只讀層)疊加而成。當(dāng)我們啟動一個容器的時候,Docker會加載只讀鏡像層并在其上(即鏡像棧頂部)添加一個讀寫層。如果運(yùn)行中的容器修改了現(xiàn)有的一個已經(jīng)存在的文件,那該文件將會從讀寫層下面的只讀層復(fù)制到讀寫層,該文件的只讀版本仍然存在,只是已經(jīng)被讀寫層中該文件的副本所隱藏。當(dāng)刪除Docker容器,并通過該鏡像重新啟動時,之前的更改將會丟失。在Docker中,只讀層及在頂部的讀寫層的組合被稱為Union File System(聯(lián)合文件系統(tǒng))。

2、為了能夠保存(持久化)數(shù)據(jù)以及共享容器間的數(shù)據(jù),Docker提出了Volume的概念。簡單來說,Volume就是目錄或者文件,它可以繞過默認(rèn)的聯(lián)合文件系統(tǒng),而以正常的文件或者目錄的形式存在于宿主機(jī)上。

總結(jié):Volume可以將容器以及容器產(chǎn)生的數(shù)據(jù)分離開來,這樣,當(dāng)你使用dockerrmmy_container刪除容器時,不會影響相關(guān)的數(shù)據(jù)。

我們可以通過兩種方式來初始化Volume,這兩種方式有些細(xì)小而又重要的差別。我們可以在運(yùn)行時使用-v來聲明Volume:

docker管理數(shù)據(jù)的方式有兩種:

1、數(shù)據(jù)卷

2、數(shù)據(jù)卷容器

數(shù)據(jù)卷是為一個或多個容器專門指定繞過Union File System的目錄,為持續(xù)性或共享數(shù)據(jù)提供一些有用的功能:

1、數(shù)據(jù)卷可以在容器間共享和重用

2、數(shù)據(jù)卷數(shù)據(jù)改變是直接修改的

3、數(shù)據(jù)卷數(shù)據(jù)改變不會被包括在容器中

4、數(shù)據(jù)卷是持續(xù)性的,直到?jīng)]有容器使用它

 

數(shù)據(jù)卷的使用,類似于 Linux 下對目錄進(jìn)行 mount

掛載一個主機(jī)目錄作為數(shù)據(jù)卷

你想在容器中使用主機(jī)上的某個目錄,你可以通過-v參數(shù)來指定(注:注意冒號前面的和后面的內(nèi)容):

docker run -v /host/path:/some/path ...

這明確地告訴Docker使用指定的主機(jī)路徑來代替Docker自己創(chuàng)建的根路徑并掛載到容器內(nèi)指定的路徑(以上例子為/some/path)。需要注意的是,如果主機(jī)上的路徑不存在,目錄將自動在給定的路徑中創(chuàng)建。

在用docker run 命令的時候,可以指定掛載一個本地主機(jī)的目錄到容器中去,可以使用多次-v選項為一個 docker 容器運(yùn)行掛載多個本地主機(jī)目錄。

 

下面創(chuàng)建一個 web 容器,并加載一個宿主機(jī)目錄到容器的 /var/www/html/目錄

在宿主機(jī)上創(chuàng)建/web/webapp1目錄,并創(chuàng)建一個index.html文件,內(nèi)容如下:

查看鏡像:

使用鏡像創(chuàng)建容器:

上面的命令加載主機(jī)的 /web/webapp1 目錄到容器的 /var/www/html 目錄。這個功能在進(jìn)行測試的時候十分方便,

比如用戶可以放置一些程序到本地目錄中,來查看容器是否正常工作。本地目錄的路徑必須是絕對路徑,如果目錄不存在 Docker 會自動為你創(chuàng)建它。

/web/webapp1目錄的文件都將會出現(xiàn)在容器內(nèi)。這對于在主機(jī)和容器之間共享文件是非常有幫助的,例如掛載需要編譯的源代碼。為了保證可移植性(并不是所有的系統(tǒng)的主機(jī)目錄都是可以用的),掛載主機(jī)目錄不需要從Dockerfile指定。

掛載的目錄可以通過docker inspect  容器ID

在瀏覽器中,輸入宿主IP和端口號,即可訪問測試頁(注:開啟路由轉(zhuǎn)發(fā))

-v選項除了可以掛載當(dāng)前主機(jī)的一個目錄到容器中也可以添加一個或多個數(shù)據(jù)卷

創(chuàng)建一個數(shù)據(jù)卷

Volume可以使用以下兩種方式創(chuàng)建:

1.在Dockerfile中指定VOLUME /some/dir

2.執(zhí)行docker run -v /some/dir命令來指定

無論哪種方式都是做了同樣的事情。它們告訴Docker在主機(jī)上創(chuàng)建一個目錄(默認(rèn)情況下是在/var/lib/docker/volumes下),然后將其掛載到指定的路徑(例子中是:/some/dir)。當(dāng)刪除使用該Volume的容器時,Volume本身不會受到影響,它可以一直存在下去。

如果在容器中不存在指定的路徑,那么該目錄將會被自動創(chuàng)建。

創(chuàng)建數(shù)據(jù)卷綁定到到新建容器,新建容器中會創(chuàng)建 /data 數(shù)據(jù)卷

注意:也可以在dockerfile中使用 volume 來添加一個或者多個新的卷到由該 image 創(chuàng)建的任意容器,例如:

FROM debian:wheezy

VOLUME /data

進(jìn)入容器,查看給容器添加的數(shù)據(jù)卷

創(chuàng)建的數(shù)據(jù)卷可以通過docker inspect獲取宿主機(jī)對應(yīng)路徑

這說明Docker把在/var/lib/docker下的某個目錄掛載到了容器內(nèi)的/data目錄下。

注:docker版本及運(yùn)行的宿主機(jī)系統(tǒng)不同,數(shù)據(jù)卷的查看和對應(yīng)的具體路徑會有差異。

讓我們從主機(jī)上添加文件到此文件夾下:

進(jìn)入我們的容器內(nèi)可以看到:

docker  attach  容器名|容器ID

注1:Docker 掛載數(shù)據(jù)卷的默認(rèn)權(quán)限是讀寫,用戶也可以通過 :ro指定為只讀。

加了  :ro之后,就掛載為只讀了。

 

數(shù)據(jù)卷容器

如果要授權(quán)一個容器訪問另一個容器的Volume,我們可以使用--volumes-from參數(shù)來執(zhí)行

如果你有一些持久性的數(shù)據(jù)并且想在容器間共享,可以創(chuàng)建一個數(shù)據(jù)卷容器,然后從此容器上掛載數(shù)據(jù)。

常見的使用場景是使用純數(shù)據(jù)容器來持久化數(shù)據(jù)庫、配置文件或者數(shù)據(jù)文件等。

例如:

docker run --name dbdata postgres echo "Data-only container for postgres"

該命令將會創(chuàng)建一個已經(jīng)包含在Dockerfile里定義過Volume的postgres鏡像(如:VOLUME  /var/lib/postgresql/data),運(yùn)行echo命令然后退出。當(dāng)我們運(yùn)行dockerps命令時,echo可以幫助我們識別某鏡像的用途。我們可以用--volumes-from命令來識別其它容器的Volume:

 docker run -d --volumes-from dbdata --name db1 postgres

 

現(xiàn)在就來創(chuàng)建一個命名的數(shù)據(jù)卷容器:

#docker run -dit -v /test --name data鏡像

使用--volumes-from選項在另一個容器中掛載 /test 卷。不管 data 容器是否運(yùn)行,其它容器都可以掛載該容器數(shù)據(jù)卷,當(dāng)然如果只是單獨(dú)的數(shù)據(jù)卷是沒必要運(yùn)行容器的。

然后,你可以在其他容器中使用 --volumes-from  來掛載/test 卷

#docker run -dit --volumes-from data --name test1鏡像

添加另一個容器

#docker run -dit --volumes-from data --name test2 鏡像

注:還可以使用多個 --volumes-from  參數(shù)來從多個容器掛載多個數(shù)據(jù)卷

執(zhí)行dockerps查看

進(jìn)入test1、test2容器,執(zhí)行df查看

也可以繼承其它掛載有 /test 卷的容器

#docker run -dit --volumes-from test1 --name test3 鏡像

如果刪除了掛載的容器(包括 data、db1 和 db2),數(shù)據(jù)卷并不會被自動刪除。如果要刪除一個數(shù)據(jù)卷,必須在刪除最后一個還掛載著它的容器時使用dockerrm -v  命令來指定同時刪除關(guān)聯(lián)的容器。

利用 Data Volume Container  來備份、恢復(fù)、移動數(shù)據(jù)

備份

 

數(shù)據(jù)卷另外一個功能是使用他們來備份、恢復(fù)、移動數(shù)據(jù),如果你在用數(shù)據(jù)容器,那做備份是相當(dāng)容易的。

使用 --volume 標(biāo)記來創(chuàng)建一個加載了卷的新的容器,命令如下:

該示例應(yīng)該會將Volume里所有的東西壓縮為一個tar包

這里我們創(chuàng)建了一個容器,先從 data 容器來掛載數(shù)據(jù)卷。然后從本地主機(jī)掛載當(dāng)前目錄到容器的 /backup 目錄。最后,使用 tar 命令來將 data 卷備份為 backup.tar 。當(dāng)命令執(zhí)行完、容器停止之后,我們就備份了 data 數(shù)據(jù)卷

執(zhí)行完成之后刪除容器--rm,此時備份就在當(dāng)前的目錄下,名為backup.tar

宿主機(jī)當(dāng)前目錄下產(chǎn)生了 test 卷的備份文件 test.tar

恢復(fù)

附:

權(quán)限與許可

通常你需要設(shè)置Volume的權(quán)限或者為Volume初始化一些默認(rèn)數(shù)據(jù)或者配置文件。要注意的關(guān)鍵點(diǎn)是,在Dockerfile的VOLUME指令后的任何指令都不能改變該Volume,比如:

FROM debian:wheezy

RUN useradd foo

VOLUME /data

RUN touch /data/x

RUN chown -R foo:foo /data

該Docker file不能按預(yù)期那樣運(yùn)行,我們本來希望touch命令在鏡像的文件系統(tǒng)上運(yùn)行,但是實際上它是在一個臨時容器的Volume上運(yùn)行。如下所示:

FROM debian:wheezy

RUN useradd foo

RUN mkdir /data && touch /data/x

RUN chown -R foo:foo /data

VOLUME /data

所以,牢記Dockerfile中VOLUME指令的位置(VOLUME是設(shè)置指令)

如果你沒有通過RUN指令設(shè)置權(quán)限,那么你就需要在容器啟動時使用CMDENTRYPOINT指令來執(zhí)行

刪除 Volumes

Volume 只有在下列情況下才能被刪除:

dockerrm -v刪除容器時添加了-v選項

例如:你可以告訴Docker同時刪除容器和其Volume:

docker rm -v my_container

docker run --rm運(yùn)行容器時添加了--rm選項

即使用以上兩種命令,也只能刪除沒有容器連接的Volume。連接到用戶指定主機(jī)目錄的Volume永遠(yuǎn)不會被docker刪除。

否則,會在/var/lib/docker/volumes目錄下得到一些僵尸文件和目錄,并且還不容易說出它們到底代表什么。

 

謝謝觀看,真心的希望能幫到您!



本文出自 “一盞燭光” 博客,謝絕轉(zhuǎn)載!

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號