如何在Docker容器之间共享数据

117 阅读5分钟

如何在Docker容器之间共享数据

容器是一种使程序在从一个环境移到另一个环境时独立运行的方式。容器化则是包装容器的过程,使其更容易扩展,并增强其可移植性。

Docker容器使你能够从你的环境中快速开发和运行你的应用程序。

先决条件

为了开始工作,我们必须在我们的系统上安装Docker。

请注意,我们将在本教程中使用Ubuntu 20.04

创建一个独立的卷

Docker卷是附属于容器的系统文件,有助于持久保存数据。当人们想在不同的容器之间共享数据时,Docker卷也是至关重要的。

让我们开始吧。

我们将使用docker volume create 命令来创建一个卷,而不把它与任何容器联系起来。

让我们创建一个名为NewVol1 的卷。

docker volume create NewVol1

如果我们列出我们的输出,我们可以看到创建的卷。

docker volume ls
DRIVER    VOLUME NAME
local     NewVol1

接下来,我们需要从Ubuntu image 中设置一个新的容器。我们使用--rm 标志在用户退出时删除该容器。-v 标志将新的卷挂载起来。

卷的名称必须在冒号和绝对路径之后指定,如下所示。

docker run -ti --rm -v NewVol1:/newvol1 ubuntu

下面的代码段向你展示了如何在容器中向Docker卷写入数据。

root@77a92a143828:/# echo "Example1" > /newvol1/Example1.txt

我们使用下面的代码片断退出根目录。

root@77a92a143828:/# exit

为了检查我们的卷是否仍然驻留在我们的环境中,我们使用docker volume inspect

docker volume inspect NewVol1

输出结果是。

[
    {
        "CreatedAt": "2021-05-12T20:20:24+03:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/NewVol1/_data",
        "Name": "NewVol1",
        "Options": {},
        "Scope": "local"
    }
]

输出是JSON数组的格式。它显示了检查的timestampDriverScope 都在我们的本地系统中。

然而,LabelsOptions 是空的,因为我们没有指定它们。Mountpoint 显示了卷所处的路径。name 属性表示我们正在检查的卷。

接下来,让我们启动一个新的容器并附加NewVol1

docker run -ti --rm -v NewVol1:/newvol1 ubuntu

你可以检查内容,如下图所示。

docker run -ti --rm -v NewVol1:/newvol1 ubuntu
root@b4a69fffc60a:/# cat /newvol1/Example1.txt
Example1
root@b4a69fffc60a:/# exit
exit

从一个现有的带数据的目录创建一个卷

在这一步,我们将在一个带有数据的容器内创建一个卷。

/var 路径,让我们建立一个容器并添加一个Docker卷。

docker run -ti --rm -v NewVol2:/var ubuntu
root@976fbd71c0a7:/# exit
exit

注意,/var 目录中的内容在Docker卷中是重复的。我们还将卷附加到最新的容器中,并退出当前目录。

我们正在使用ls ,而不是默认的bash ,以启动shell。

docker run --rm -v NewVol2:/newvol2 ubuntu ls newvol2
backups  cache	lib  local  lock  log  mail  opt  run  spool  tmp

newvol2 索引复制了/var 目录中的组件。

使用这种方法来附加/var/ ,有助于渲染图像。

在多个Docker容器之间共享数据

更多的时候,我们会希望各种容器挂载到类似的Docker卷。然而,Docker并不处理文件锁。为了将各种容器写入卷,容器的当前环境应该是一个支持共享数据存储的设备。

创建容器3和DataVolume3

我们使用docker run ,建立一个新的容器,名为Container3 ,如下图。

docker run -ti --name=Container3 -v NewVol3:/newvol3 ubuntu

然后我们在一个新文件中添加一些文本,如下图所示。

root@1ef4d68f08b2:/# echo "Shared container file" > /newvol3/Example3.txt
root@1ef4d68f08b2:/# exit
exit

然后我们退出容器并导航到主机终端,在那里我们创建一个新的容器,附加来自Container3 的数据卷。

创建容器4并附加来自容器3的卷

让我们把Container3 附加到新创建的Container4 ,如下图所示。

docker run -ti --name=Container4 --volumes-from Container3 ubuntu

如图所示,数据的一致性得到了检查。

root@d19c4e150495:/# cat /newvol3/Example3.txt
Shared container file
root@d19c4e150495:/#

在这一点上,让我们从Container4 附加一些文本,然后退出容器。

root@d19c4e150495:/# echo "Both containers can write to NewVol3" >> /newvol3/Example3.txt
root@d19c4e150495:/# exit
exit

随后,我们将检查我们的数据是否仍然存在于Container3 中。

容器4的变化

我们可以通过刷新Container3 来检查Docker卷中的变化。

docker start -ai Container3

下面的命令确认所有容器是否能够从Docker卷中读写,然后退出环境。

root@1ef4d68f08b2:/# cat /newvol3/Example3.txt
Shared container file
Both containers can write to NewVol3
root@1ef4d68f08b2:/# exit
exit

启动容器5并附加卷的只读性

如果一个容器已经被一个数据卷挂载,我们不会像典型的Linux文件那样卸载它。我们建立一个新的容器并使该卷成为只读。

在容器名称的后面加上:ro 标志,使其成为read-only ,如下图所示。

docker run -ti --name=Container5 --volumes-from Container3:ro ubuntu

我们通过尝试省略我们创建的文件来测试只读的突出性。

root@9b1678a2d548:/# rm /newvol3/Example3.txt
rm: cannot remove '/newvol3/Example3.txt': Read-only file system
root@9b1678a2d548:/# exit
exit

下面的命令清除了我们的测试容器和卷。

docker rm Container3 Container4 Container5
docker volume rm NewVol3

结论

在本教程中,我们已经学会了如何创建一个独立的Docker卷,当容器被删除时,它可以持续保存数据。它还有利于在不同的容器之间共享数据。

文件锁定机制可以减少数据损坏。最后,我们还学习了如何挂载一个共享卷并使其成为只读。