Docker資料卷—Volumes
- 一、引入Docker資料卷的必然性
- 二、Docker掛載容器資料卷
- 三、bind mounts的基本使用
- 四、volumes的基本使用
- 五、擴充套件(-volume)
- 六、tmpfs mounts的基本使用(很少用,稍微瞭解就行)
一、引入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