Docker與數據:三種掛載方式


操作系統與存儲

操作系統中將存儲定義為 Volume(卷) ,這是對物理存儲的邏輯抽象,以達到對物理存儲提供有彈性的分割方式。另外,將外部存儲關聯到操作系統的動作定義為 Mount(掛載)。

Docker 中的三種掛載方式

  1. Bind

把宿主機的某個目錄(或文件)掛載到指容器的指定目錄(后文件)下,比如下面的命令就表示通過 Bind 方式將外部的 HTML 文檔掛載到 Nginx 容器的模式網站根目錄下:

$ docker run -v ~/zioyi/html:/usr/share/nginx/html -p 81:80 -d --name nginx_bind nginx:latest

來驗證一下

$ curl localhost:81
<html>
<title>Hi, Docker</title>
<h1>You mount me by Bind mode</h1>V
</html>

這種方式的缺點就是被掛載的宿主機目錄(或文件)不收保護,任何容器都可以去隨意修改。

  1. Volume

Volume 模式下,我們需要通過docker volume命令來創建一個 Volume。實際上,是在 Docker 的/var/lib/docker/volumes/文件夾內創建一個相同名字的文件夾來保存數據。因為這個文件夾在 Docker 管控范圍里,Docker 可以根據掛載的設定來控制容器對 Volume 的讀寫權限。

# 創建 volume
$ docker volume create nginx-volume
nginx-volume
$ docker run --mount type=volume,source=nginx-volume,destination=/usr/share/nginx/html -p 82:80 -d --name nginx_volume nginx:latest

此時,nginx_volume 容器已經掛載了 nginx-volume 卷,通過 inpsect 命令可以看到:

$ docker inspect nginx_volume
{...
"Mounts": [
            {
                "Type": "volume",
                "Name": "nginx-volume",
                "Source": "/var/lib/docker/volumes/nginx-volume/_data",
                "Destination": "/usr/share/nginx/html",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            }
        ],
...}

我們進入容器中修改/usr/share/nginx/html中的 HTML 文檔

$ docker exec -it nginx_volume bash
root@d0df9a0eb3e5:/# echo "<html>                                    
<title>Hi, Docker</title>
<h1> You mount me by Volume mode</h1>
</html>" > /usr/share/nginx/html/index.html
root@d0df9a0eb3e5:/# exit
exit
# 在宿主機中驗證
$ curl localhost:82
<html>
<title>Hi, Docker</title>
<h1> You mount me by Volume mode</h1>
</html>

當我們刪除容器 nginx_volum 時,volume 也不會刪除

$ docker stop nginx_volume && docker rm nginx_volume
$ docker run --mount type=volume,source=nginx-volume,destination=/usr/share/nginx/html -p 82:80 -d --name nginx_volume nginx:latest

$ curl localhost:81
<html>
<title>Hi, Docker</title>
<h1>You mount me by Volume mode</h1>
</html>

此外,我們還可以在掛載時設定容器只能讀取卷,無法進行寫操作,這種方式多用於容器讀取配置文件的場景:

$ docker run --mount type=volume,source=nginx-volume,destination=/usr/share/nginx/html,readonly -p 82:80 -d --name nginx_volume nginx:latest
$ docker exec -it nginx_volume bash
root@782b11b3cc43:/#
# 當我們再次修改時報錯
root@782b11b3cc43:/# echo "hello" > /usr/share/nginx/html/index.html
bash: /usr/share/nginx/html/index.html: Read-only file system
  1. tmpfs

tmpfs 掛載是臨時的,僅保留在主機內存中。當容器停止時,tmpfs 掛載被移除,寫入的文件不會被持久化

$ docker run --mount type=tmpfs,destination=/usr/share/nginx/html -p 83:80 -d --name nginx_tmpfs nginx:latest

$ docker inspect nginx_tmpfs
{...
"Mounts": [
            {
                "Type": "tmpfs",
                "Source": "",
                "Destination": "/usr/share/nginx/html",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
...}

進入容器 nginx_tmpfs 修改數據

$ docker exec -it nginx_tmpfs bash
root@68b03d8d3ec4:/# echo "<html>                                    
<title>Hi, Docker</title>
<h1> You mount me by tmpfs mode</h1>
</html>" > /usr/share/nginx/html/index.html
root@68b03d8d3ec4: exit
exit

# 驗證
$ curl localhost:83
<html>                                    
<title>Hi, Docker</title>
<h1> You mount me by tmpfs mode</h1>
</html>

tmpfs 無法對容器內產生的數據持久化,一般不使用。

總結

  1. 對比 Docker 三種掛載方式:
Bind Volume tmpfs
volume 位置 可指定任意位置 /var/lib/docker/volumes/... 宿主機內存中
對已有mount point 影響 隱藏並替換為 volume 原有數據復制到 volume -
是否支持單個文件 支持 不支持,只能是目錄 -
權限控制 可設置為只讀,默認為讀寫權限 可設置為只讀,默認為讀寫權限 -
移植性 移植性弱,與 host path 綁定 移植性強,無需指定 host 目錄 -
是否支持持久化 支持 支持 不支持
  1. 關於 Volume
    Volume 模式並不是 Docker 一開始就有的,Docker 最初認為 Volume 就只是一種“外部宿主機的磁盤存儲到內部容器的映射關系”,但后來發現事情並沒有那么簡單:存儲的位置並不局限於外部宿主機,存儲的介質並不局限於物理磁盤,存儲的管理也並不局限於映射關系。Bind 模式無法很好地解決多跨宿主機共享存儲的問題、Bind 模式的管理問題等。
    提出 Volume 的最核心的目的是提升Docker對不同存儲介質的支撐能力,這同時也可以減輕Docker本身的工作量。存儲不僅有掛載在宿主機上的物理存儲,還有網絡存儲,Docker 抽象出了存儲啟動(Sotroage Driver)來去解決對網絡存儲的讀寫問題。


免責聲明!

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



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