Volume 是 docker 容器生成持久化數據的首選機制。bind mounts 依賴主機機器的目錄機構,volume 徹底由 docker 管理。volume 較 bind mounts 有幾個優點:
1. volume 比 bind mounts 更易備份和遷移。
2. 可使用 docker cli 命令和 API 管理 volume。
3. volume 工做在 linux 和 windows 容器上。
4. volume 在多個容器間共享能夠更安全。
5. volume 驅動容許存儲 volume 到主機和雲,加密 volume 內容,或者添加其它功能。
6. 新的 volume 能夠含有容器預放置的內容。
另外,volume 一般與持久化數據到容器的可寫層相比是更好的選擇,由於 volume 不增大容器的大小,而且 volume 的內容在容器的生命週期以外存在。
若是容器產生不持久化的狀態數據,考慮使用 tmpfs mount 來避免永久存儲,而且經過避免寫入容器的可寫層來增長容器性能。
選擇 -v 仍是 --mount
最初,-v 或 --volume 用於獨立的容器,--mount 用於 swarm 服務。
而自 Docker 17.06 開始,你能夠將 --mount 用於獨立的容器。通常而言,--mount 更明確和冗長。
最大的不一樣是,-v 語法把全部的選項綁定到一行,而 --mount 語法把它們分開。
若是須要指定 volume 驅動選項,你必須使用 --mount。
-v 或 --volume: 包含三個字段,由冒號分割。字段必須保持正確順序,每一個字段的含義不是很明顯。
1. 在有名字的 volume 中,第一個字段是 volume 的名字,在主機上惟一。對於匿名的 volume,第一個字段能夠省略。
2. 第二個字段是文件或目錄掛載到容器中的路徑。
3. 第三個字段是可選的,是逗號分隔的選項列表,好比 ro 。
--mount : 包含多個鍵值對,由逗號隔開,每個是 <key>=<value>對。--mount 語法比 -v 或 --volume 更冗餘,但鍵的順序並不重要,value 更容易理解。
1. 掛載的 type 能夠是 bind, volume, tmpfs。本節討論 volume,因此類型老是 volume。
2. 掛載的 source。對於有名字的 volume,它是 volume 的名字,對於匿名的 volume,這個字段能夠省略,能夠指定爲 source 或 src。
3. destination 的值表示文件或目錄 掛載到容器中的路徑。能夠指定爲 destination,dst,target。
4. reanonly 選項,若是存在,致使做爲只讀掛載到容器中。
5. volume-opt 選項,能夠指定不止一次,有一個含選項名和值的鍵值對。
-v 和 --mount 的行爲差別
相對 bind mounts,全部 volume 的選項對 --mount 和 -v 均可用。
當與 service 一塊兒使用 volume 時,只有 --mount 是支持的。
建立和管理 volume
不像 bind mount, 你能夠在容器外面建立和管理 volume。
$ docker volume create myvol
$ docker volume ls
$ docker inspect myvol
$ docker volume rm myvol
帶着 volume 啓動 container
若是啓動容器時帶的容器不存在,那麼 docker 會建立一個。
# -v 將主機 /var/lib/docker/volumes/volume_os 掛在到容器中 /var/lib/docker/volume_os,如下兩條等同。
docker run --rm -it -v volume_os:/var/lib/docker/volume_os 5e8b97a2a082
docker run --rm -it --mount 'type=volume,src=volume_os,dst=/var/lib/docker/volume_os,volume-driver=local' 5e8b97a2a082
帶着 volume 啓動 service
當你啓動一個 service 而且定義了一個 volume,每個 service 容器使用它本身的本地 volume。
若是你使用 volume 的 local 驅動,沒有一個容器能夠共享它的數據。
示例啓動四個複製的 nginx 服務,每個使用本地 volume 叫 myvol2。
$ docker service create -d \
--replicas=4 \
--name devtest-service \
--mount source=myvol2,target=/app \
nginx:latest
驗證服務正在運行:docker service ps devtest-service
移除服務:docker service rm devtest-service,移除 service 不會移除任何 service 建立的 volume。volume 移除是獨立的步驟。
docker service create 命令不支持 -v 或 --volume 標記,必須使用 --mount 標記。
使用容器放置 volume
若是啓動一個容器,容器中被掛載的目錄有文件或目錄,那麼目錄的內容會被拷貝到 volume 中。
$ docker run -d --name=nginxtest -v nginx-vol:/usr/share/nginx/html nginx:latest
使用只讀 volume
$ docker run -d --name=nginxtest -v nginx-vol:/usr/share/nginx/html:ro nginx:latest
在機器間共享數據
當構建容錯性應用時,你可能須要配置多個複製的相同服務來訪問相同的文件。
當開發應用時,有多種方式能夠取得。第一種是應用把文件存到雲對象系統中,好比 Amazon S3,另外一種是建立一個支持把文件寫到外部存儲系統(如NFS)的 volume 驅動。
volume 驅動容許你從應用層抽象底層存儲系統。例如,若是 service 使用一個 NFS 驅動的 volume,你能夠更新 service 使用不一樣的驅動,好比把數據存儲到雲中,而不須要改變應用邏輯。
使用一個 volume 驅動
初始化安裝
$ docker plugin install --grant-all-permissions vieux/sshfs
使用一個 volume 驅動建立 volume
$ docker volume create --driver vieux/sshfs \
-o sshcmd=test@node2:/home/test \
-o password=pwd sshvolume \
sshvolume
啓動容器時建立使用 volume 驅動的 volume
$ docker run -d \
--name sshfs-container \
--volume-driver vieux/sshfs \
--mount src=sshvolume,target=/app, volume-opt=sshcmd=test@node2:/home/test, volume-opt=password=pwd \
nginx:latest
備份,恢復,遷移 data volume
volume 對備份,恢復,遷移 有用。使用 --volumes-from 標記來建立一個新的容器掛載到 volume.
備份一個容器
# 啓動新容器,從 dbstore 容器中掛載 volume,掛載一個本地目錄叫 backup,傳遞一個命令壓縮 dbdata volume 的內容到 /backup 目錄的 backup.tar
docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
從備份中恢復容器
# 建立一個容器 dbstore2:
docker run -v /dbdata --name dbstore2 ubuntu /bin/bash
# 解壓縮備份文件到新容器的數據 volume 中:
docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bach -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
你可使用以上技術來自動備份、遷移、恢復來測試。
移除 volume
docker 數據 volume 在容器被刪除後依舊存在。有兩種類型的 volume。
1. 有名字的 volume:有一個指定的容器外的來源。
2. 匿名的 volume:沒有指定來源,因此當容器被刪除時會指示 docker 守護進程引擎移除它們。
移除匿名 volume
要自動移除匿名容器使用 --rm 選項。例子中,命令建立一個匿名 volume /foo 。當容器移除時,docker 引擎移除 /foo volume,但不會移除 awesome volume
$ docker run --rm -v /foo -v awesome:/bar busybox top
移除全部未使用的 volume
$ docker volume prune
Guide:https://docs.docker.com/storage/volumes/html
Link:http://www.javashuo.com/article/p-rnbepqyb-ct.htmlnode