容器(六)Data Volume 之 bind mount【34】

(二)Data Volume 之 bind mount

​ storage driver 和 data volume 是容器存放數據的兩種方式,上一節咱們學習了 storage driver,本節開始討論 Data Volume。Data Volume 本質上是 Docker Host 文件系統中的目錄或文件,可以直接被 mount 到容器的文件系統中。Data Volume 有如下特色:html

  1. Data Volume 是目錄或文件,而非沒有格式化的磁盤(塊設備)。
  2. 容器能夠讀寫 volume 中的數據。
  3. volume 數據能夠被永久的保存,即便使用它的容器已經銷燬。

如今咱們有數據層(鏡像層和容器層)和 volume 均可以用來存放數據,具體使用的時候要怎樣選擇呢?考慮下面幾個場景:mysql

  1. Database 軟件 vs Database 數據
  2. Web 應用 vs 應用產生的日誌
  3. 數據分析軟件 vs input/output 數據
  4. Apache Server vs 靜態 HTML 文件

相信你們會作出這樣的選擇:linux

  1. 前者放在數據層中。由於這部份內容是無狀態的,應該做爲鏡像的一部分。
  2. 後者放在 Data Volume 中。這是須要持久化的數據,而且應該與鏡像分開存放。

還有個你們可能會關心的問題:如何設置 voluem 的容量?sql

由於 volume 其實是 docker host 文件系統的一部分,因此 volume 的容量取決於文件系統當前未使用的空間,目前尚未方法設置 volume 的容量。在具體的使用上,docker 提供了兩種類型的 volume:bind mount 和 docker managed volume。docker

(1)bind mount

bind mount 是將 host 上已存在的目錄或文件 mount 到容器。經過 -v 將其 mount 到 httpd 容器:apache

root@cuiyongchao:~# docker run -d -p 81:80 -v /root/htdocs/://usr/local/apache2/htdocs httpd
c75e9caa7d615493f3c64e5c0c27a914c6ce9cb0d6fa97ca0d4c07cf8d0f5c74
root@cuiyongchao:~# cat /root/htdocs/index.html 
<html><body><h1>this is a file.</h1></body></html>
root@cuiyongchao:~#

-v 的格式爲 <host path>:<container path>。/usr/local/apache2/htdocs 就是 apache server 存放靜態文件的地方。因爲 /usr/local/apache2/htdocs 已經存在,原有數據會被隱藏起來,取而代之的是 host $HOME/htdocs/ 中的數據,這與 linux mount 命令的行爲是一致的。安全

root@cuiyongchao:~# curl 10.0.0.20:81
<html><body><h1>this is a file.</h1></body></html>
root@cuiyongchao:~#

curl 顯示當前主頁確實是 $HOME/htdocs/index.html 中的內容。更新一下,看是否能生效:bash

root@cuiyongchao:~# echo "<html><body><h1>it is changing,please waiting.</h1></body></html>" >/root/htdocs/index.html
root@cuiyongchao:~# curl 10.0.0.20:81
<html><body><h1>it is changing,please waiting.</h1></body></html>
root@cuiyongchao:~#

host 中的修改確實生效了,bind mount 可讓 host 與容器共享數據。這在管理上是很是方便的。curl

下面咱們將容器銷燬,看看對 bind mount 有什麼影響:學習

root@cuiyongchao:~# docker stop c75e9caa7d61
c75e9caa7d61
root@cuiyongchao:~# docker rm c75e9caa7d61
c75e9caa7d61
root@cuiyongchao:~# cat /root/htdocs/index.html 
<html><body><h1>it is changing,please waiting.</h1></body></html>
root@cuiyongchao:~#

可見,即便容器沒有了,bind mount 也還在。這也合理,bind mount 是 host 文件系統中的數據,只是借給容器用用,哪能隨便就刪了啊。

另外,bind mount 時還能夠指定數據的讀寫權限,默認是可讀可寫,可指定爲只讀:

root@cuiyongchao:~# docker run -d -p 82:80 -v /root/htdocs/:/usr/local/apache2/htdocs:ro httpd
fbb20d680a686c9270675f9dca4c059c0f6167816e30033dca8c1e904944d3f6
root@cuiyongchao:~# 
root@cuiyongchao:~# 
root@cuiyongchao:~# docker exec -it fbb20d680a686c9270675f9dca4c059c0f6167816e30033dca8c1e904944d3f6 /bin/bash
root@fbb20d680a68:/usr/local/apache2# ls
bin  build  cgi-bin  conf  error  htdocs  icons  include  logs	modules
root@fbb20d680a68:/usr/local/apache2# cd htdocs/
root@fbb20d680a68:/usr/local/apache2/htdocs# ll
bash: ll: command not found
root@fbb20d680a68:/usr/local/apache2/htdocs# ls
index.html
root@fbb20d680a68:/usr/local/apache2/htdocs# cat index.html 
<html><body><h1>it is changing,please waiting.</h1></body></html>
root@fbb20d680a68:/usr/local/apache2/htdocs# 
root@fbb20d680a68:/usr/local/apache2/htdocs# echo "thi is ro file.">index.html 
bash: index.html: Read-only file system
root@fbb20d680a68:/usr/local/apache2/htdocs#

ro 設置了只讀權限,在容器中是沒法對 bind mount 數據進行修改的。只有 host 有權修改數據,提升了安全性。

除了 bind mount 目錄,還能夠單獨指定一個文件:

root@cuiyongchao:~# docker run -d -p 83:80 -v /root/htdocs/index.html:/usr/local/apache2/htdocs/index.html httpd
44cfb081082ef03cbf9e125cf66136ebf0f95e27c732e799533f374666320260
root@cuiyongchao:~# curl 10.0.0.20:83
<html><body><h1>it is changing,please waiting.</h1></body></html>
root@cuiyongchao:~# cat /root/htdocs/index.html
<html><body><h1>it is changing,please waiting.</h1></body></html>
root@cuiyongchao:~# echo "321">/root/htdocs/index.html
root@cuiyongchao:~# curl 10.0.0.20:83
321
root@cuiyongchao:~#

使用 bind mount 單個文件的場景是:只須要向容器添加文件,不但願覆蓋整個目錄。在上面的例子中,咱們將 html 文件加到 apache 中,同時也保留了容器原有的數據。

使用單一文件有一點要注意:host 中的源文件必需要存在,否則會看成一個新目錄 bind mount 給容器。

mount point 有不少應用場景,好比咱們能夠將源代碼目錄 mount 到容器中,在 host 中修改代碼就能看到應用的實時效果。再好比將 mysql 容器的數據放在 bind mount 裏,這樣 host 能夠方便地備份和遷移數據。

bind mount 的使用直觀高效,易於理解,但它也有不足的地方:bind mount 須要指定 host 文件系統的特定路徑,這就限制了容器的可移植性,當須要將容器遷移到其餘 host,而該 host 沒有要 mount 的數據或者數據不在相同的路徑時,操做會失敗。

移植性更好的方式是 docker managed volume,下一節咱們討論。

相關文章
相關標籤/搜索