方式:1、利用run指令,語法為「docker run --name test1 -it -v」;2、利用dockerfile的VOLUME指令建立掛載點,語法為「VOLUME ["/data1" ,"/data2"]”;3、利用容器共享卷。
本教學操作環境:linux7.3系統、docker-1.13.1版、Dell G3電腦。
在介紹VOLUME指令之前,我們來看下如下場景需求:
1.容器是基於映像建立的,最後的容器檔案系統包括鏡像的唯讀層可寫層,容器中的程序操作的資料持久化都是保存在容器的可寫層上。一旦容器刪除後,這些資料就沒了,除非我們人工備份下來(或基於容器建立新的鏡像)。能否讓容器程序持久化的資料保存在主機上呢?這樣即使容器刪除了,資料還在。
2. 當我們在開發一個web應用時,開發環境是在主機本地,但運行測試環境是放在docker容器上。
這樣的話,我在主機上修改檔案(如html,js等)後,需要再同步到容器中。這顯然比較麻煩。
3. 多個容器運行一組相關聯的服務,如果他們要共享一些資料怎麼辦?
對於這些問題,我們當然能想到各種解決方案。而docker本身提供了一個機制,可以將主機上的某個目錄與容器的某個目錄(稱為掛載點、或稱為卷宗)關聯起來,容器上的掛載點下的內容就是主機的這個目錄下的內容,這類似linux系統下mount的機制。這樣的話,當我們修改主機上該目錄的內容時,不需要同步容器,對容器來說是立即生效的。掛載點可以讓多個容器共用。
下面我們來介紹具體的實作機制。
1.執行指令:docker run --name test -it -v /home/xqh/myimage:/data ubuntu /bin/bash
其中的-v 標記在容器中設定了一個掛載點/data(就是容器中的一個目錄),並將主機上的/home/xqh/myimage 目錄中的內容關聯到/data下。
這樣在容器中對/data目錄下的操作,還是在主機上對/home/xqh/myimage的操作,都是完全即時同步的,因為這兩個目錄實際上都是指向主機目錄。
2.執行指令:docker run --name test1 -it -v /data ubuntu /bin/bash
上面-v的標記只設定了容器的掛載點,並沒有指定關聯的主機目錄。這時docker會自動綁定主機上的目錄。透過docker inspect 指令可以查看到。
xqh@ubuntu:~/myimage$ docker inspect test1 [ { "Id": "1fd6c2c4bc545163d8c5c5b02d60052ea41900a781a82c20a8f02059cb82c30c", ............................. "Mounts": [ { "Name": "0ab0aaf0d6ef391cb68b72bd8c43216a8f8ae9205f0ae941ef16ebe32dc9fc01", "Source": "/var/lib/docker/volumes/0ab0aaf0d6ef391cb68b72bd8c43216a8f8ae9205f0ae941ef16ebe32dc9fc01/_data", "Destination": "/data", "Driver": "local", "Mode": "", "RW": true } ],
上面 Mounts下的每個訊息記錄了容器上一個掛載點的信息,「Destination」 值是容器的掛載點,"Source"值是對應的主機目錄。可以看出這種方式對應的主機目錄是自動建立的,其目的不是讓在主機上修改,而是讓多個容器共用。
上面介紹的透過docker run指令的-v標識所建立的掛載點只能對所建立的容器有效。透過dockerfile的 VOLUME 指令可以在映像中建立掛載點,這樣只要透過該映像建立的容器都有了掛載點。還有一個差異是,透過 VOLUME 指令建立的掛載點,無法指定主機上對應的目錄,是自動產生的。
#test FROM ubuntu MAINTAINER hello1 VOLUME ["/data1","/data2"]
上面的dockfile檔案透過VOLUME指令指定了兩個掛載點/data1 和/data2.
我們透過docker inspect 查看透過該dockerfile所建立的映像所產生的容器,可以看到以下資訊
"Mounts": [ { "Name": "d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21", "Source": "/var/lib/docker/volumes/d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21/_data", "Destination": "/data1", "Driver": "local", "Mode": "", "RW": true }, { "Name": "6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36", "Source": "/var/lib/docker/volumes/6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36/_data", "Destination": "/data2", "Driver": "local", "Mode": "", "RW": true } ],
可以看到兩個掛載點的資訊。
下面我們建立另一個容器可以和test1(已經建立好的容器)共用/data1 和/data2卷,這是在docker run中使用--volumes-from標記,如:
可以是來源不同鏡像,如:
docker run --name test2 -it --volumes-from test1 ubuntu /bin/bash
也可以是同一鏡像,如:
docker run --name test3 -it --volumes-from test1 myimage /bin/bash
上面的三個容器test1 , test2 , test3 都有/data1 和/data2 兩個目錄,且目錄中內容是共享的,任何一個容器修改了內容,別的容器都能取得。
如果多個容器需要共用資料(如持久化資料庫、設定檔或資料檔案等),可以考慮建立一個特定的資料容器,該容器有1個或多個卷。
其它容器透過–volumes-from 來共享這個資料容器的磁碟區。
因為容器的磁碟區本質上對應主機上的目錄,所以這個資料容器也不需要啟動。
如: docker run --name dbdata myimage echo “data container”
說明:有個卷,容器之間的資料共享比較方便,但也有很多問題需要解決,如權限控制、資料的備份、磁碟區的刪除等。這些內容後續文章介紹。
推薦學習:《docker影片教學》
以上是docker有哪幾種掛載方式的詳細內容。更多資訊請關注PHP中文網其他相關文章!