(二)Data Volume 之 bind mount
? storage driver 和 data volume 是容器存放資料的兩種方式,上一節我們學習了 storage driver,本節開始討論 Data Volume,Data Volume 本質上是 Docker Host 檔案系統中的目錄或檔案,能夠直接被 mount 到容器的檔案系統中,Data Volume 有以下特點:
- Data Volume 是目錄或檔案,而非沒有格式化的磁盤(塊設備),
- 容器可以讀寫 volume 中的資料,
- volume 資料可以被永久的保存,即使使用它的容器已經銷毀,
現在我們有資料層(鏡像層和容器層)和 volume 都可以用來存放資料,具體使用的時候要怎樣選擇呢?考慮下面幾個場景:
- Database 軟體 vs Database 資料
- Web 應用 vs 應用產生的日志
- 資料分析軟體 vs input/output 資料
- Apache Server vs 靜態 HTML 檔案
相信大家會做出這樣的選擇:
- 前者放在資料層中,因為這部分內容是無狀態的,應該作為鏡像的一部分,
- 后者放在 Data Volume 中,這是需要持久化的資料,并且應該與鏡像分開存放,
還有個大家可能會關心的問題:如何設定 voluem 的容量?
因為 volume 實際上是 docker host 檔案系統的一部分,所以 volume 的容量取決于檔案系統當前未使用的空間,目前還沒有方法設定 volume 的容量,在具體的使用上,docker 提供了兩種型別的 volume:bind mount 和 docker managed volume,
(1)bind mount
bind mount 是將 host 上已存在的目錄或檔案 mount 到容器,通過 -v 將其 mount 到 httpd 容器:
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 中的內容,更新一下,看是否能生效:
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 與容器共享資料,這在管理上是非常方便的,
下面我們將容器銷毀,看看對 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,下一節我們討論,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/228753.html
標籤:其他
