如果容器是隔離的,那麼它們如何與主機進行通信,例如存儲數據?因為當我們從映像創建容器時,容器被移除時生成的任何數據都會丟失。
因此,我們需要一種方式來實現永久性存儲。
我們可以使用 Bind Mounts 和 Volumes 來實現。
兩者之間沒有太大的區別,除了 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 prune
或 docker system prune --volumes
命令來刪除所有未使用的 Volumes。
要創建一個 Volume,首先需要運行命令 docker volume create
:
docker volume create logs
現在,您可以使用 docker volume ls
和 docker volume inspect
命令來獲取有關系統 Volumes 的更多數據:
現在運行 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。