1. 程式人生 > >利用Volume在主機和Docker容器檔案傳輸。

利用Volume在主機和Docker容器檔案傳輸。

之前寫過一篇關於Docker容器和本機之間的檔案傳輸。的文章,但是此方法相對比較繁瑣一些,在查看了官方關於資料管理的文件之後發現利用volume來實現主機和容器的檔案傳輸效率更高一點,其實也就是將本地的目錄進行掛載到容器上,官方一共有三種方法:Manage data in Docker
這裡只介紹使用volume的操作:Use volumes

1.使用Volume在主機和容器之間傳輸檔案。

在官方文件中可以看到使用如下命令即可建立一個volume:

Create a volume:

$ docker volume create my-vol

注意這個命令不是所有的docker版本都可以執行的:

The client and daemon API must both be at least 1.21 to use this command. Use the docker version command on the client to check your client and daemon API versions.

這裡寫圖片描述

建立完成之後可以檢視詳細資訊:

$ docker volume inspect my-vol

這裡寫圖片描述

注意這個Mountpoint所對應的目錄就是我們用來主機和容器進行檔案傳輸的目錄。

然後在使用run啟動一個容器的時候就可以使用該volume:

這裡寫圖片描述

可以看到通過-v命令將剛才建立的資料卷掛載到容器中的hostdata目錄下了,這時候我們在容器中給hostdata目錄下新增檔案的時候,在主機的的/var/lib/docker/volumes/my-vol/_data中就可以看到了,同理在主機的該目錄中新增檔案,在容器的hostdata中也可以看到。

我將nginx這個檔案複製到主機中用來交換的目錄下,進入容器之後在hostdata的目錄下也可以檢視:

這裡寫圖片描述

同樣的在容器中將檔案拷貝到hostdata目錄下中,在主機的/var/lib/docker/volumes/my-vol/_data也能夠使用檢視。

在這裡我在容器中建立一個檔案testfile並向其中寫入:This is container write!,然後回到主機進行檢視,並在主機中使用vim向其中新增:“This is host write!”,並返回容器中進行檢視。

這裡寫圖片描述

2.使用資料卷容器。

我在有些地方看到有人使用資料卷容器來實現多個容器之間的資料共享,其過程是這樣子的:

1.先建立一個數據卷容器dbdata,並在其中建立一個數據卷掛載到/bdata:

這裡寫圖片描述

可以通過docker volume ls檢視生成了一個隨機名稱的volume。

2.然後,可以在其他容器中使用–volumes-from來掛載dbdata容器中的資料卷,例如建立db1和db2兩個容器,並從dbdata容器掛載資料卷:

這裡寫圖片描述

3.然後此時在三個容器中任何一方在/dbdata目錄下的寫入,其他容器中都可以看到。

這裡寫圖片描述

在圖中,在dbdata容器中建立testfile檔案並寫入”dbdata container write!”,然後在db1容器中檢視並寫入“db1 container write!”,然後在db2容器中檢視並寫入“da2 container write!”,最後回到dbdata容器中檢視。

4.然後還可以通過多個–volumes-from來掛載多個數據卷,然後還給出了備份和恢復的方法,網上一搜一大把。

3.為什麼不用資料卷容器?

在看到許許多多關於資料卷容器的文章,並且都是大同小異。然後我想了想發現並沒有使用資料卷的必要性(或許是我想的不夠周全)。

上面提到資料卷容器用來在多個容器中共享資料,但是在明明可以通過掛載一個相同的本地目錄就能實現該方法。比如說在第一步中建立的my-vol資料卷,我可以將其同時掛載到db3和db4容器中。

這裡寫圖片描述

在圖中,我將my-vol資料卷掛載到了db3和db4中,然後在其中能夠找到之前的資料檔案,並且在db4容器中對testfile檔案進行寫入操作,在db3中容器中也可以檢視。

那麼也就是說,我同樣的可以通過掛載一個數據卷就可以實現多個容器中的資料共享,並且在主機的目錄中新增的檔案,在所有的容器中也能夠檢視。如果備份的話直接在主機本地將資料夾進行拷貝即可,豈不是更方便。

4.為什麼使用資料卷容器?

但是資料卷容器還有一個作用比較不錯,那就是可以用來指定掛載本地目錄,在第一點中我們建立一個名為my-vol的資料卷,該資料卷在本地存放的目錄為:/var/lib/docker/volumes/my-vol/_data,可以看出這個名字很長不方便操作,可以通過資料卷容器來解決該問題。

比如我在主機上建立了一個專門用來存放主機和容器進行檔案互動的目錄,也就是說以後我想給容器中傳輸什麼檔案了,我直接將檔案拷貝到該目錄下即可:

這裡寫圖片描述

我在官方文件中並沒有發現使用docker volume create 建立資料卷時可以指定volume對應的本地目錄的命令(或許是我看的不夠多)。

但是我就是想要用/usr/local/datadb 這個目錄該怎麼辦?此刻資料卷容器的作用就出來了,可以通過建立一個數據卷容器,並且將該目錄掛在到資料卷容器上即可:

這裡寫圖片描述

在圖中,我建立了一個所謂的資料卷容器,並且使用-v引數,將剛才主機的/usr/local/datadb目錄掛載進去,然後在容器中建立檔案testfile並寫入“HAHAHAHA”,在主機上進行檢視。

然後在其他容器建立的時候既可以使用–volumes-from將該資料卷容器進行掛載,然後想給容器中傳檔案的時候直接拷貝到/usr/local/datadb目錄下即可,反過來容器給主機傳檔案直接拷貝到容器中的掛載目錄下即可。

至於備份,直接將主機/usr/local/datadb賦值一份就好了,恢復的話再次掛載就好了。

但有一個問題就是,上述所有的掛載volume操作都是使用run命令新建了一個容器,至於能不能直接給執行中的容器進行掛載,我查了半天只有一個是關於這個的,但是我也沒有考證,有興趣的可以看下:http://dockone.io/article/149