卷(Volume)
眾所周知卷(Volume)是容器中的一個數(shù)據(jù)掛載點(diǎn),卷可以繞過聯(lián)合文件系統(tǒng),從而為Docker 提供持久數(shù)據(jù),所提供的數(shù)據(jù)還可以在宿主機(jī)-容器或多個容器之間共享。通過卷,我們可以可以使修改數(shù)據(jù)直接生效,而不必重新構(gòu)建鏡像。
數(shù)據(jù)卷是一個可以繞過聯(lián)合文件系統(tǒng)的,專門指定的可在一或多個容器間共享目錄。卷為提供為持久化或共享數(shù)據(jù)提供了一些有用的特性。
數(shù)據(jù)卷設(shè)計(jì)的初哀是提供持久化數(shù)據(jù),而與容器的生命周期無關(guān)。因此,在刪除容器時,Docker不會自動刪除卷,直到?jīng)]有容器再引用。
1.1 添加數(shù)據(jù)卷
可以在docker create
和docker create
命令創(chuàng)建容器時,通過-v參數(shù)為容器添加數(shù)據(jù)卷。-v參數(shù)參數(shù)可以多次使用,以添加多個數(shù)據(jù)卷。
如,可以像下面這樣為容器添加一個卷:
1
|
$ sudo docker run -t -i - v /home/test --name test itbilu /test /bin/bash |
這樣就會在容器內(nèi)/webapp位置創(chuàng)建一個卷。
除了在創(chuàng)建容器時添加數(shù)據(jù)卷外,還可以通過Dockerfile文件中通過Volume指令添加,Volume可以多次使用以添加多個數(shù)據(jù)卷。
說明:本文中使用的示例鏡像(itbilu/test)通過以下Dockerfile文件創(chuàng)建:
1
2
3
4
5
6
7
8
9
10
11
|
# Version: 0.0.3 FROM ubuntu:16.04 MAINTAINER 何民三 "cn.liuht@gmail.com" RUN apt-get update RUN apt-get install -y nginx RUN echo 'Hello World, 我是個容器' \ > /var/www/html/index .html RUN mkdir /home/itbilu/ ENV ITBILU_PATH /home/itbilu/ VOLUME [$ITBILU_PATH] EXPOSE 80 |
1.2 卷位置
添加卷后,可以通過docker inspect
來查看數(shù)據(jù)卷在容器中的位置:
1
|
$ sudo docker inspect test |
docker inspect
可以用來查看容器或鏡像的詳細(xì)配置信息??梢栽谌萜鞯腗ounts節(jié)點(diǎn)下,查看容器的卷信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
... "Mounts" : [{ "Type" : "volume" , "Name" : "5f869c580c06e6079b0de2c5ce682c1c9467286c76b506703d87bf11d1271c24" , "Source" : "/var/lib/docker/volumes/5f869c580c06e6079b0de2c5ce682c1c9467286c76b506703d87bf11d1271c24/_data" , "Destination" : "/home/test" , "Driver" : "local" , "Mode" : "" , "RW" : true , "Propagation" : "" }, { "Type" : "volume" , "Name" : "e4fd6c3a91ba2e03b14cf174c2023f366abbe9f2f73ca07e6bac223f68e47773" , "Source" : "/var/lib/docker/volumes/e4fd6c3a91ba2e03b14cf174c2023f366abbe9f2f73ca07e6bac223f68e47773/_data" , "Destination" : "[/home/itbilu/]" , "Driver" : "local" , "Mode" : "" , "RW" : true , "Propagation" : "" }], ... |
在以上示例中,有兩個掛載卷,一個是在docker run
創(chuàng)建容器時創(chuàng)建的,而另一個是在創(chuàng)建運(yùn)行容器鏡像的Dockerfile文件中通過VOLUME指令創(chuàng)建。其中,Source表示宿主機(jī)源文件位置,Destination表示數(shù)據(jù)卷在容器中的掛載位置,而RW表示卷是否可讀/寫。
1.3 掛載本地?cái)?shù)據(jù)到容器數(shù)據(jù)卷
在前面示例中,我們運(yùn)行容器時并沒有指定要掛載到容器中數(shù)據(jù)卷的本地目錄,所在Docker使用一個默認(rèn)數(shù)據(jù)目錄。 -v
參數(shù)除了可以在容器中創(chuàng)建數(shù)據(jù)卷外,還可以將宿主機(jī)中的目錄掛載到容器中的數(shù)據(jù)卷。
如,運(yùn)行容器,并將本地的~/code/itbilu目錄掛載到容器的/home/itbilu數(shù)據(jù)卷上:
1
|
$ sudo docker run -t -i - v ~ /code/itbilu : /home/itbilu --name test itbilu /test /bin/bas |
注意:掛載本地目錄到容器內(nèi)的掛載目錄時,如果容器內(nèi)的數(shù)據(jù)卷中已經(jīng)存在數(shù)據(jù),那么本地內(nèi)容將與數(shù)據(jù)卷中的數(shù)據(jù)重疊,而不會刪除數(shù)據(jù)。
其中,容器目錄必須使用絕對路徑,而本地目錄可以使用絕對路徑或其它形式。
掛載共享存儲
除了可以載掛本地目錄到容器數(shù)據(jù)卷外,一些Docker卷插件讓你可以掛載共享存儲到容器的數(shù)據(jù)卷,如:iSCSI、NFS、FC。使用共享卷的好處是它們是獨(dú)立于主機(jī)的,這意味著,只要有訪問共享存儲權(quán)限,并安裝插件,就可以在任何容器上啟動卷。
詳細(xì)參考:
Mount a shared-storage volume as a data volume
掛載本地文件到容器數(shù)據(jù)卷
-v
參數(shù)不僅可掛載目錄,還可以掛載單個文件。如:
1
2
|
$ sudo docker run -t -i - v ~/.bash_history: /root/ .bash_history \ --name test itbilu /test /bin/bash |
以上會把本地的~/.bash_history文件掛載到新容器中,這樣你就可以在容器內(nèi)訪問宿主上的bash歷史記錄。
二、數(shù)據(jù)卷容器
如果你有一些要在容器之間共享的持久性數(shù)據(jù),或者希望在非持久容器中使用,那么最好創(chuàng)建一個命名的數(shù)據(jù)卷容器,然后從其掛載數(shù)據(jù)。
接下來,我們創(chuàng)建一個新的命名的共享容器。這個容器不運(yùn)行一個應(yīng)用程序,它利用training/postgres鏡像在所有的容器之間創(chuàng)建了一個共享層,以節(jié)省磁盤空間。
1
|
$ sudo docker create - v /dbdata --name dbstore training /postgres /bin/true |
注意:training/postgres是Docker 官方文檔中提供的一個鏡像,本文拿來直接使用了。
使用數(shù)據(jù)卷容器
創(chuàng)建數(shù)據(jù)卷容器后,我們可以通過--volumes-from
選項(xiàng),將一個數(shù)據(jù)容器掛載到其它容器:
1
|
$ sudo docker run -d --volumes-from dbstore --name db1 training /postgres |
也可以在多個容器間共享。如,掛載到另一個容器:
1
|
$ sudo docker run -d --volumes-from dbstore --name db2 training /postgres |
這時,如果training/postgres鏡像內(nèi)有名/dbdata的目錄,則會從dbstore容器掛載卷,并會隱藏training/postgres鏡像中/dbdata下的文件。最終只有dbstore容器中的文件可見。
還可以擴(kuò)展掛載鏈,從已經(jīng)存在的dbstore容器(如:db1、db2)來掛載卷:
1
|
$ sudo docker run -d --name db3 --volumes-from db1 training /postgres |
這種情況下,如果移除己掛載卷的容器,無論是最初的dbstore容器,還是其后的db1或db2容器,卷都不會被移除。要將卷從硬盤上移除,必須使用docker rm -v
命令刪除最后一個引用了該卷的容器。
三、備份、恢復(fù)與遷移數(shù)據(jù)卷
除上述操作外,數(shù)據(jù)卷的常用操作還有數(shù)據(jù)卷備份、恢復(fù)、合并操作。以下是一些常用操作:
3.1 備份數(shù)據(jù)卷
在前面介紹數(shù)據(jù)卷容器時,我們創(chuàng)建了一個名為dbdata容器,并在容器中創(chuàng)建了一個/dbdata的數(shù)據(jù)卷。接下來,可以在創(chuàng)建容器使用--volumes-from
參數(shù)來掛載這個數(shù)據(jù)卷,并對數(shù)據(jù)進(jìn)行備份:
1
|
$ sudo docker run --volumes-from dbdata - v $( pwd ): /backup ubuntu tar cvf /backup/backup . tar /dbdata |
在這個操作中,我們通過ubuntu鏡像創(chuàng)建了一個容器,創(chuàng)建容器時通過--volumes-from
參數(shù)共享了數(shù)據(jù)卷容器中的數(shù)據(jù),并將當(dāng)前目錄($(pwd) )掛載到了數(shù)據(jù)卷中。容器運(yùn)行后,使用tar命令對數(shù)據(jù)卷進(jìn)行了備份。
命令執(zhí)行結(jié)束后,容器就會停止,之后就可以在本地當(dāng)前操作目錄下找到所備份的數(shù)據(jù)。
3.2 備份數(shù)據(jù)卷
數(shù)據(jù)備份后,可以在創(chuàng)建容器恢復(fù)備份數(shù)據(jù)到容器內(nèi)的數(shù)據(jù)卷中,從而實(shí)現(xiàn)數(shù)據(jù)的遷移。
首先,創(chuàng)建并運(yùn)行容器并添加一個數(shù)據(jù)卷:
1
|
$ sudo docker run -i -t - v /dbdata --name dbdata2 ubuntu /bin/bash |
然后通過tar
命令恢復(fù)備份數(shù)據(jù):
1
|
$ sudo docker run -- rm --volumes-from dbdata2 - v $( pwd ): /backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1" |
這樣,數(shù)據(jù)就被恢復(fù)到了容器dbdata2的/dbdata目錄下,我們可以容器中操作和使用這些數(shù)據(jù)。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。
原文鏈接:https://itbilu.com/linux/docker/4kiHC33_G.html