淺談Docker之Docker數據持久化Bind Mount和Volume(轉)


轉自 https://www.jianshu.com/p/ef0f24fd0674

Docker的數據持久化主要有兩種方式:

  • bind mount
  • volume

Docker的數據持久化即是數據不隨着container的結束而結束,數據存在於host機器上——要么存在於host的某個指定目錄中(使用bind mount),要么使用docker自己管理的volume(/var/lib/docker/volumes下)。

 

bind mount

bind mount自docker早期便開始為人們使用了,用於將host機器的目錄mount到container中。但是bind mount在不同的宿主機系統時不可移植的,比如Windows和Linux的目錄結構是不一樣的,bind mount所指向的host目錄也不能一樣。這也是為什么bind mount不能出現在Dockerfile中的原因,因為這樣Dockerfile就不可移植了。

將host機器上當前目錄下的host-data目錄mount到container中的/container-data目錄:

docker run -it -v $(pwd)/host-dava:/container-data alpine sh

有幾點需要注意:

  • host機器的目錄路徑必須為全路徑(准確的說需要以/~/開始的路徑),不然docker會將其當做volume而不是volume處理
  • 如果host機器上的目錄不存在,docker會自動創建該目錄
  • 如果container中的目錄不存在,docker會自動創建該目錄
  • host機器目錄無論有沒文件,都會覆蓋container掛載目錄

 

volume

volume也是繞過container的文件系統,直接將數據寫到host機器上,只是volume是被docker管理的,docker下所有的volume都在host機器上的指定目錄下/var/lib/docker/volumes。

將my-volume掛載到container中的/mydata目錄:

docker run -it -v my-volume:/mydata alpine sh

然后可以查看到給my-volume的volume:

docker volume inspect my-volume
[
    {
        "CreatedAt": "2018-03-28T14:52:49Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/my-volume/_data",
        "Name": "my-volume",
        "Options": {},
        "Scope": "local"
    }
]

可以看到,volume在host機器的目錄為 /var/lib/docker/volumes/my-volume/_data 。此時,如果my-volume不存在,那么docker會自動創建my-volume,然后再掛載。

也可以不指定host上的volume:

docker run -it -v /mydata alpine sh

此時docker將自動創建一個隨機名稱的volume,並將其掛載到container中的/mydata目錄。匿名volume在host機器上的目錄路徑類似於var/lib/docker/volumes/300c2264cd0acfe862507eedf156eb61c197720f69e7e9a053c87c2182b2e7d8/_data

除了讓docker幫我們自動創建volume,我們也可以自行創建:

docker volume create my-volume-2

然后將這個已有的my-volume-2掛載到container中:

docker run -it -v my-volume-2:/mydata alpine sh
需要注意的是,與bind mount不同的是,如果volume是空的而container中的目錄有內容,那么docker會將container目錄中的內容拷貝到volume中,但是如果volume中已經有內容,則會將container中的目錄覆蓋。

Dockerfile中的VOLUME

在Dockerfile中,我們也可以使用VOLUME指令來申明contaienr中的某個目錄需要映射到某個volume:

#Dockerfile
VOLUME /foo
這表示,在docker運行時,docker會創建一個匿名的volume,並將此volume綁定到container的/foo目錄中,如果container的/foo目錄下已經有內容,則會將內容拷貝的volume中。也即,Dockerfile中的  VOLUME /foo 與  docker run -v /foo alpine 的效果一樣。

Dockerfile中的VOLUME使每次運行一個新的container時,都會為其自動創建一個匿名的volume,如果需要在不同container之間共享數據,那么我們依然需要通過 docker run -it -v my-volume:/foo 的方式將/foo中數據存放於指定的my-volume中。

因此,VOLUME /foo在某些時候會產生歧義,如果不了解的話將導致問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM