1. 程式人生 > 其它 >Docker資料卷—Volumes

Docker資料卷—Volumes

目錄

一、引入Docker資料卷的必然性

為了實現容器與主機之間、容器與容器之間共享檔案,容器中資料的持久化,將容器中的資料備份、遷移、恢復等,Docker加入了資料卷(volumes)機制。簡單的講,就是做了一個資料夾的實時共享,有點像區域網的檔案共享。

二、Docker掛載容器資料卷

目前Docker提供了三種不同的方式將資料從宿主機掛載到容器中:bind mounts、tmpfs mounts、Volumes三種方式。其實嚴格來講tmpfs mounts不會掛載到宿主機上的。下面有講解。

2.1、方式一:bind mounts

意為著可以儲存在宿主機系統的任意位置。

但是,bind mount在不同的宿主機系統時不可移植的,比如Windows和Linux的目錄結構是不一樣的,bind mount所指向的host目錄也不能一樣。這也是為什麼bind mount不能出現在Dockerfile中的原因,因為這樣Dockerfile就不可移植了。

2.3、方式三:volumes

Docker管理宿主機檔案系統的一部分,預設位於 /var/lib/docker/volumes 目錄中;最常用的方式

2.3、方式二:tmpfs mounts

其中tmpfs是一種基於記憶體的臨時檔案系統。tmpfs mounts掛載儲存在宿主機系統的記憶體中,而不會寫入宿主機的檔案系統。
三種方式掛載圖解

三、bind mounts的基本使用

2.1、示例講解
這裡指定了將宿主機上的 /opt/wwwroot目錄掛載到/usr/share/nginx/html

$ mkdir -p  /opt/wwwroot
$ docker run -itd --name=nginx-v1 -v /opt/wwwroot:/usr/share/nginx/html nginx

-v指定具體路徑,如果不指定,那就在預設路徑下/var/lib/docker/volumes/目錄下隨機產生一個掛載目錄

可以看到,bind mounts的方式會隱藏掉被掛載目錄裡面的初始內容,這裡是/usr/share/nginx/html目錄下的內容被隱藏掉了,因此我們看不到。

然後我們建立新檔案,就可以在容器裡看到新建立的檔案了。
宿主機:

容器裡

2.2、檢視容器詳情,就可以看到我們繫結的路徑

$ docker inspect nginx-v1

2.3、清理

$ docker stop nginx-v1
$ docker rm  nginx-v1
# 檢視掛在目錄
$ ll /opt/wwwroot/

通過圖上所示,掛載目錄裡面的檔案仍然還在,不會隨著容器的結束而消失,從而實現資料持久化。

四、volumes的基本使用

4.1、管理卷

# 建立一個自定義容器卷,在/var/lib/docker/volumes/目錄下建立
$ docker volume create nginx-vol1
# 檢視所有容器卷
$ docker volume ls 
# 檢視指定容器卷詳情資訊
$ docker volume inspect nginx-vol1 

4.2、建立使用指定卷的容器
有了自定義容器卷,我們可以建立一個使用這個資料卷的容器,這裡我們以nginx為例:

$ docker run -itd --name=nginx-v1 -p 8080:80 -v nginx-vol1:/usr/share/nginx/html nginx

其中,-v代表掛載資料卷,這裡使用自定資料卷nginx-vol1,並且將資料卷掛載到 /usr/share/nginx/html。
與bind mounts的區別在於不用自己建立目錄,只有建立卷就行,卷其實也是目錄,還有一點volumes就是可以檢視/usr/share/nginx/html自帶檔案。

4.3、如果不加-v,則不會在預設路徑下掛載目錄

$ docker run -itd --name=nginx-v2 -p 8081:80  nginx
$ ls -l /var/lib/docker/volumes/

4.3、如果加-v,但是不指定宿主機的掛載目錄,則會自動建立一個隨機的掛載目錄,這種方式是bind mounts,也看不到預設檔案

$ docker run -itd --name=nginx-v4 -p 8084:80 -v :/usr/share/nginx/html nginx

4.4、刪除容器

$ docker stop nginx-v1
$ docker rm nginx-v1

資料也不會因為容器被刪除而刪除,達到資料持久化的效果。

五、擴充套件(-volume)

高於17.06的docker可以將--mount用於為單一容器建立資料卷,兩者的差別如下:

5.1、-v或是-volume包括三個區域,以分號分割

  • 第一個區域用於定義卷的名稱,如果不指定,表明使用匿名卷,實名卷的名稱在一臺主機上唯一
  • 第二個區域指定卷對應容器中的哪個檔案
  • 第三個區域是可選的,是用逗號分割的選項列表

5.2、-mount使用鍵值對=,以逗號分割,對應的值如下

  • type:可以是bind、volume、tmpfs,建立資料卷使用volume
  • source:掛載點的名字,對於實名卷,為實名卷的名字,匿名卷不需要使用這個關鍵字
  • destination:指定卷對應容器中的哪個檔案
  • readonly:指定資料卷只可讀
  • volume-opt:可以出現多次,其值為一個鍵值對(有什麼用我還不知道)

-mount引數的值用單引號包含起來,將關鍵字對應值中出現的volume-opt用雙引號括起來,如下:

$ docker service create \
     --mount 'type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=local,volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>,"volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"'
    --name myservice \
    <IMAGE>

5.2、-v與-mount的區別

-mount可以支援建立叢集服務的資料卷,而-v不行,其餘基本沒差;怎麼建立叢集的話,會面寫docker swarm會講到。

5.3、建立、檢視、刪除資料卷:

# 建立實名資料卷
$ docker volume create my-vol
 
# 建立匿名卷
$ docker volume create
 
# 檢視資料卷列表
$ docker volume ls
 
# 檢視具體的資料卷
$ docker volume inspect my-vol
 
# 刪除資料卷
$ docker volume rm my-vol 

5.4、示例,資料卷會自動建立
1)在建立容器時指定資料卷

# 建立容器
$ docker run -d \
  --name devtest \
  --mount source=myvol1,target=/usr/share/nginx/html \
  nginx:latest

2)使用只讀資料卷

#ro表示只讀(readonly),-v==--mount
$ docker run -d \
  --name=nginxtest \
  -v nginx-vol:/usr/share/nginx/html:ro \
  nginx:latest
#  等價於下面命令
$ docker run -d \
  --name=nginxtest2 \
  --mount source=nginx-vol2,destination=/usr/share/nginx/html,readonly \
  nginx:latest

5.5、刪除資料卷

$ docker volume ls
$ docker volume rm nginx-vol1
$ docker volume ls
# 刪除所有卷,慎用
$ docker volume prune

注意:docker規定,沒有容器正在使用資料卷後才允許刪除該資料卷

六、tmpfs mounts的基本使用(很少用,稍微瞭解就行)

如果在 Linux 上執行 Docker,那麼還有第三種選擇:tmpfs 掛載不會持久化到宿主機目的是為了避免寫入資料到容器儲存層還有一個方案

與卷和繫結掛載不同,tmpfs 掛載是臨時的,只存留在主機記憶體中。當容器停止時,tmpfs 掛載將被刪除,在那裡寫入的檔案不會被持久化

6.1、tmpfs 掛載的侷限性

  • 不同於卷和繫結掛載,不能在容器之間共享 tmpfs 掛載。
  • 這個功能只有在 Linux 上執行 Docker 時才可用。

6.2、--tmpfs 和 --mount 行為之間的差異

  • --tmpfs 標記不允許指定任何可配置選項。
  • --tmpfs 標記不能用於叢集服務。對於叢集服務,您必須使用 --mount。

6.3、在容器中使用 tmpfs 掛載

要在容器中使用 tmpfs 掛載, 請使用 --tmpfs 標記, 或者使用帶有 type=tmpfs 和 destination 選項的 --mount 標記。沒有用於 tmpfs 掛載的源(source)。

示例1:(--mount),在 Nginx 容器中的 /usr/share/nginx/html 建立一個 tmpfs 掛載

$ docker run -d \
  -it \
  --name tmptest \
  --mount type=tmpfs,destination=/usr/share/nginx/html \
  nginx:latest
$ docker exec -it tmptest /bin/bash
$ df -h

示例2:(--tmpfs)

$ docker run -d \
  -it \
  --name tmptest2 \
  --tmpfs /usr/share/nginx/html \
  nginx:latest

通過執行 docker inspect tmptest 來驗證掛載是否是 tmpfs 掛載,檢視 Mounts 部分:

$ docker inspect tmptest|grep -i -C3 Tmpfs

6.4、指定 tmpfs 選項

tmpfs 掛載允許兩個配置選項,兩個選項都不是必需的。 如果需要指定這些選項,則必須使用 --mount 標記,因為 --tmpfs 標記不支援。

tmpfs-size	tmpfs 掛載的大小(以位元組為單位)。預設無限制。
tmpfs-mode	tmpfs 的八進位制檔案模式。例如,700 或 0770。預設為 1777 或全域性可寫。

示例:下面的示例將 tmpfs-mode 設定為 1770,因此在容器中它不是全域性可讀的。

$ docker run -d \
  -it \
  --name tmptest3 \
  --mount type=tmpfs,destination=/usr/share/nginx/html,tmpfs-mode=1770 \
  nginx:latest