docker數據持久化


轉載/參考:

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

 

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

  • bind mount
  • docker managed volume

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

1.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 /home/host-dava:/container-data alpine sh

有幾點需要注意:

  • host機器的目錄路徑必須為全路徑(准確的說需要以/~/開始的路徑),不然docker會將其當做volume而不是bind mount處理
  • 如果host機器上的目錄不存在,docker會自動創建該目錄
  • 如果container中的目錄不存在,docker會自動創建該目錄
  • 如果container中的目錄已經有內容,那么docker會使用host上的目錄將其覆蓋掉

2.docker managed volume

2.1在docker run使用

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

查看所有volume

docker volume ls

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

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

需要注意的是,與bind mount不同的是,如果volume是空的而container中的目錄有內容,那么docker會將container目錄中的內容拷貝到volume中,但是如果volume中已經有內容,則會將container中的目錄覆蓋

2.2.Dockerfile中的VOLUME

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

#Dockerfile
VOLUME /foo

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

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

3.對比

相同點:兩者都是 host 文件系統中的某個路徑。

不同點:

  bind mount docker managed volume
volume 位置 可任意指定 /var/lib/docker/volumes/...
對已有mount point 影響 隱藏並替換為 volume 原有數據復制到 volume
是否支持單個文件 支持 不支持,只能是目錄
權限控制 可設置為只讀,默認為讀寫權限 無控制,均為讀寫權限
移植性 移植性弱,與 host path 綁定 移植性強,無需指定 host 目錄

4.數據容器

如果用戶需要在多個容器之間共享一些持續更新的數據,最簡單的方式是使用數據卷容器。數據卷容器也是一個容器,但是它的目的是專門用來提供數據卷供其他容器掛載。通常會在容器中創建一個或多個卷,其他的容器就可以通過--volumes-from選項來訪問它們。

運行一個名為storage的數據容器,它包含一個卷並在后台運行:

docker run -d -v /data --name storage ubuntu

    接下來我們運行另一個容器:

docker run -it --name
storage2 --volumes-from storage ubuntu bash
 


免責聲明!

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



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