当您使用 Docker 容器构建微服务架构时,需要创建多个 Docker 容器来创建和测试应用程序的不同组件。现在,其中一些组件可能需要共享文件和目录。如果您将相同的文件分别复制到所有容器中,可能会导致镜像大小不必要的增加,而且,在一个容器中更改文件不会在其他容器中对同一文件进行相应的更改。
因此,您需要一个可以挂载到多个Docker 容器上的共享目录或卷,并且所有容器都对某个文件或目录拥有共享访问权限。Docker 允许您在多个容器中挂载共享卷。在本文中,我们将把一个卷挂载到不同的容器,并检查文件中的更改是否在所有容器之间共享。
卷
在 Docker 中,卷是以容器形式部署有状态集应用程序的首选方式。您可以在 Docker 生命周期之外管理和持久化 Docker 数据。与绑定挂载不同,卷完全由 Docker 管理。Docker 卷允许您在 Docker 容器和 Docker 主机之间共享数据。它们是 Docker 中的两种卷类型。您将数据存储在 Docker 中。
-
命名卷。
-
绑定卷。
创建和管理卷 | 分步说明
要了解有关 Docker 命令的更多信息,请参阅Docker – 指令命令。
步骤 1:显示所有现有的 Docker 卷
要显示所有现有的Docker 卷,可以使用如下 list 命令。
sudo docker volume ls
步骤2:创建卷
要创建新的 Docker 卷,可以使用卷创建命令。
sudo docker volume create geeksforgeeks
步骤3:检查Docker卷
要获取已创建的卷的详细信息,您可以使用卷检查命令。
sudo docker volume inspect geeksforgeeks
步骤4:安装Docker卷
创建卷后,下一步是将卷挂载到 Docker 容器。我们将使用您在Dockerfile中提到的 Ubuntu 基础镜像创建一个 Docker 容器,并使用 -v 标志将_geeksforgeeks_卷挂载到该容器。您可以使用 Dockerfile安装 Linux 软件包。
sudo docker run -it -v geeksforgeeks:/shared-volume --name my-container-01 ubuntu
上述命令将_geeksforgeeks_卷挂载到名为my-container-01的 Docker 容器内名为shared-volume****的目录。
步骤 5:在 Docker 卷内创建文件
在容器的 bash 中,创建一个新文件并添加一些内容。
ls
cd /shared-volume
echo “GeeksforGeeks” > geeksforgeeks.txt
ls
exit
步骤 6:创建另一个容器并挂载卷
在容器内创建另一个名为my-container-02 geeks for geeks 的Docker 容器。
sudo docker run -it -v geeksforgeeks:/shared-volume --name my-container-02 ubuntu
如果你进入共享卷目录并列出文件,你会发现之前在同一个卷中创建但之前挂载在my-container-01中的geeksforgeeks.txt文件,并且它里面也包含相同的内容。这是因为该卷在两个容器之间共享。
步骤 7:删除卷
在删除卷之前,请确保已备份该卷,因为删除卷将永久删除其中存储的数据。使用以下命令可以删除 Docker 卷。要了解更多 Docker 命令,请参阅 Docker 命令。
docker volume rm volume_name_or_id
在volume_name或id的位置,您应该使用您的卷名称和卷id。
步骤 8:使用卷启动容器
在利用卷启动容器之前,您应该先创建卷。之后,使用以下命令创建容器。创建容器之前,您需要一个Docker 镜像。
docker run -d --name mongo -v mongovol:/data/db -e MONGO_INITDB_ROOT_USERNAME=devdb -e MONGO_INITDB_ROOT_PASSWORD=devdb123
“-v mongovol:/data/db” 代表卷的名称,“ /data/db”代表要挂载卷的目录“-e”代表由开发人员自己编写的环境变量,可以是“用户名和密码”。
步骤 9:使用 Docker Compose 卷
在编写docker-compose文件时,您可以挂载为存储数据而创建的卷,如下所示。
services:
frontend:
image: node:lts
volumes:
- mongovol:/data/db
volumes:
mongovol:
-
`services`:****此部分定义组成应用程序的服务或容器。在本例中,有一个名为“ frontend ”的服务。
-
`frontend`:****这是服务的名称。它可以是任何你在应用程序中用来表示此容器的名称。
-
`image:`
node:lts
:指定用于创建容器的 Docker 镜像。此处,我们使用带有“lts”(长期支持)标签的官方 Node.js 镜像,该镜像通常包含最新的 LTS 版本的 Node.js。 -
`volumes`:****本小节指定应挂载到容器中的任何卷。卷允许持久数据存储,即使容器被移除,数据仍会保留。
-
`– mongovol:/data/db`:****此行定义了名为“mongovol”的卷,该卷将被挂载到容器的“/data/db”路径下。此处,“/data/db”很可能代表MongoDB 容器的默认数据目录。此卷挂载可确保存储在容器“/data/db”路径下的数据在容器生命周期之外持久化。
-
`volumes`:****本节定义可由上述定义的服务使用的命名卷。
-
`mongovol`:****此行定义了一个名为“mongovol”的命名卷。命名卷提供了一种在单个容器生命周期之外持久保存数据的方法。该卷可以在多个容器或服务之间共享,从而允许在它们之间共享和持久保存数据。
在上面撰写的文件中,您可以看到“卷”列,在该区域中,您应该提及卷和目录的名称或您应该提及的卷的路径。
-v 和 –mount 行为之间的差异
-v
Docker 中的和选项--mount
均用于将卷附加到容器,但它们在行为和功能上存在一些关键差异:
-
句法:
-
-v:该
-v
选项是指定卷附件的简写语法。它接受两个参数:卷名称或主机目录路径,以及容器目录路径。 -
–mount:该
--mount
选项提供了一种更明确、更灵活的卷挂载方式。它允许对卷选项进行更精细的控制,并可用于从各种来源挂载卷。
-
-
功能:
-
-v:该
-v
选项更简单,适用于基本卷挂载。它支持从本地主机或使用 创建的命名卷挂载docker volume create
。 -
–mount:该
--mount
选项功能更丰富、更强大。它允许指定各种选项,例如卷驱动程序、只读挂载、挂载传播等等。此选项可以从不同的来源挂载卷,例如本地目录、命名卷或远程卷服务(例如AWS EBS或Azure 文件存储)。
-
-
Volume选项:
-
-v:使用该
-v
选项,您只能指定基本卷选项,例如只读挂载和缓存行为。 -
–mount:该
--mount
选项提供了更广泛的卷选项,包括指定卷驱动程序、只读挂载、挂载传播模式以及更高级的选项,如指定卷标签和设置自定义卷权限。
-
-
灵活性:
-
-v:该
-v
选项更简洁,更易于用于简单的卷安装任务。 -
–mount:该
--mount
选项提供了更多的灵活性和控制力,使其适用于需要特定配置的复杂卷安装场景。
-
使用容器填充卷
您可以按照以下步骤填充卷。
步骤1:创建一个docker卷。
docker volume create my_volume
第 2 步:创建一个容器来填充卷。
docker run -d --name mongo -v mongovol:/data/db
\-e MONGO\_INITDB\_ROOT\_USERNAME=devdb MONGO\_INITDB\_ROOT\_PASSWORD=devdb123
步骤 3:验证已填充的卷。
docker run --rm -v mongovol:/data/db busybox ls /data/db
在机器之间共享数据
部署容错应用程序时,您需要授予同一服务的多个副本对同一文件的权限,以便您可以使用某些服务,如S3、NFS等,如下图所示。
使用卷驱动程序
您可以在创建容器之前使用以下命令创建 Docker 卷。如果您想在创建容器时创建卷,可以使用 Docker 中的卷驱动程序来实现。您可以使用卷驱动程序创建卷,如下所示。
docker volume create --driver vieux/sshfs <name of the vlome you want to create>
创建创建 NFS 卷的服务
您可以在创建服务时创建 NFS 卷,如下所述。
version: '3'
services:
nfs-server:
image: tomact:latest
container_name: nfs_container
volumes:
- /data:/nfs_share
nfs-client:
image: busybox
container_name: nfs_client
command: tail -f /dev/null
volumes:
- nfs-data:/data
volumes:
nfs-data:
driver_opts:
type: nfs
-
NFS 服务器:
-
图像:使用最新版本的名为“ tomact ”(可能是“tomcat”的拼写错误)的图像。
-
容器名称:将运行 NFS 服务器的容器名称设置为“nfs_container”。
-
Volumes:将主机目录“/data”映射到容器目录“/nfs_share”,允许主机和容器之间共享数据。
-
-
NFS 客户端:
-
图像:使用“busybox”图像,它提供了一个最小的Linux环境。
-
容器名称:将运行 NFS 客户端的容器名称设置为“nfs_client”。
-
命令:指定一个命令来保持容器运行(“tail -f /dev/null”)。
-
卷:创建一个名为“nfs-data”的卷,并将其挂载到容器内的“/data”目录。该卷使用 NFS 驱动程序与 NFS 服务器共享数据。
-
-
卷:
-
nfs-data:定义一个名为“nfs-data”的命名卷。
-
驱动程序选项:指定卷驱动程序的选项,将类型设置为“nfs”。这表示该卷将由NFS(网络文件系统)驱动程序管理,从而允许容器访问远程存储在 NFS 服务器上的文件。
-
如何使用 Docker 卷来保存更改
使用 Docker 卷是持久化容器内变更的基本技术。具体操作如下:
- 创建卷:首先,使用以下命令创建一个 Docker 卷
docker volume create
。例如:
docker volume create my_volume
- 将卷挂载到容器:运行容器时,使用
-v
标志将卷挂载到容器内的特定目录。例如:
docker run -d -v my_volume:/app my_image
-
在容器内部进行更改:使用 或类似命令访问正在运行的容器
docker exec -it <container_id> /bin/bash
。然后,更改已挂载卷内的文件或目录。 -
验证持久性:退出容器并使用同一卷启动另一个实例。验证在前一个容器中所做的更改是否已持久化。例如:
docker run -d -v my_volume:/app my_image
结论
总而言之,在本文中,我们讨论了如何创建和检查卷并将其挂载到多个 Docker 容器。当你需要在多个 Docker 容器之间共享文件和目录访问权限时,这非常有用。