如果容器是隔離的,那麼它們如何與主機進行通信,例如存儲數據?因為當我們從映像創建容器時,容器被移除時生成的任何數據都會丟失。

因此,我們需要一種方式來實現永久性存儲。

我們可以使用 Bind MountsVolumes 來實現。

兩者之間沒有太大的區別,除了 Bind Mounts 可以指向主機計算機上的任意文件夾,並且不由 Docker 直接管理。

讓我們首先看看 Bind Mounts。一個典型的例子是日誌文件。假設您的應用在容器內的 /usr/src/app/logs 文件夾中創建了一個日誌文件,您可以使用 docker run 命令的 -v(與 --volume 相同)選項將其映射到主機計算機上的一個文件夾中,例如 -v ~/logs:/usr/src/app/logs

這將把該文件夾映射到用戶的主目錄下的 logs 子文件夾中。

注意:-m--mount 選項的使用方法非常相似。

以下是我們以前創建的 examplenode 映像的命令示例:

docker run -d -p 80:3000 -v ~/logs:/usr/src/app/logs --name node-app examplenode

現在我們可以運行我們的 Node 應用程序,並將任何日誌存儲在主機計算機中,而不是 Docker 容器內部。

請注意,examplenode 應用程序不會在 /usr/src/app/logs 中生成任何日誌,這只是一個示例,您需要首先設置該日誌。

有關該卷的詳細信息將在運行 docker inspect 命令時列出,可以在容器名稱下的“Mounts”部分找到:

"Mounts": [
 {
 "Type": "bind",
 "Source": "/Users/flavio/logs",
 "Destination": "/usr/src/app/logs",
 "Mode": "",
 "RW": true,
 "Propagation": "rprivate"
 }
],

您能看到 "Type": "bind" 嗎?這表示我們創建了一個 bind mount

現在,讓我們談談 Volumes

Bind Mounts 和 Volumes 的區別在於,通過創建 Volumes,Docker 將數據存儲在它管理的文件夾中,這意味著 Docker 將負責文件權限和所有權,並為您提供管理這些 Volumes 的工具。而 Bind Mounts 基於文件系統路徑,Docker 不能提供有關它們的工具。

例如,Docker 可以通過運行 docker volume prunedocker system prune --volumes 命令來刪除所有未使用的 Volumes。

要創建一個 Volume,首先需要運行命令 docker volume create

docker volume create logs

現在,您可以使用 docker volume lsdocker volume inspect 命令來獲取有關系統 Volumes 的更多數據:

image

現在運行 docker run 命令時,使用選項 -v logs:/usr/src/app/logs(使用 Volume 名稱而不是文件夾名稱):

docker run -d -p 80:3000 -v logs:/usr/src/app/logs --name node-app examplenode

現在,在映像上運行 docker inspect 命令將顯示已掛載的 Volume:

"Mounts": [
 {
 "Type": "volume",
 "Name": "logs",
 "Source": "/var/lib/docker/volumes/logs/_data",
 "Destination": "/usr/src/app/logs",
 "Driver": "local",
 "Mode": "z",
 "RW": true,
 "Propagation": ""
 }
],

看到了嗎?現在日誌將存儲在 /var/lib/docker/volumes/logs/_data 文件夾中。

在將容器部署在雲服務上時,Volumes 將是必不可少的。

您可以運行 docker volume rm <name> 命令來刪除一個 Volume。