本文共 15977 字,大约阅读时间需要 53 分钟。
docker 容器共享数据
Docker is a popular containerization tool used to provide software applications with a filesystem that contains everything they need to run. Using Docker containers ensures that the software will behave the same way regardless of where it is deployed because its run-time environment is consistent.
Docker是一种流行的容器化工具,用于为软件应用程序提供一个文件系统,该文件系统包含它们需要运行的所有内容。 使用Docker容器可确保该软件的行为方式相同,而不管其部署在何处,因为其运行时环境是一致的。
In general, Docker containers are ephemeral, running just as long as it takes for the command issued in the container to complete. Sometimes, however, applications need to share access to data or persist data after a container is deleted. Databases, user-generated content for a web site, and log files are just a few examples of data that is impractical or impossible to include in a Docker image but which applications need to access. Persistent access to data is provided with .
通常,Docker容器是临时的,运行时间与容器中发出的命令完成所需的时间一样长。 但是,有时,在删除容器后,应用程序需要共享对数据的访问或保留数据。 数据库,用户为网站生成的内容以及日志文件只是不实际或不可能包含在Docker映像中但需要访问应用程序的数据的几个示例。 提供了对数据的持久访问。
Docker Volumes can be created and attached in the same command that creates a container, or they can be created independently of any containers and attached later. In this article, we’ll look at four different ways to share data between containers.
Docker Volumes可以在创建容器的同一命令中创建和附加,也可以独立于任何容器创建并随后附加。 在本文中,我们将研究在容器之间共享数据的四种不同方式。
To follow this article, you will need an Ubuntu 20.04 server with the following:
要遵循本文,您将需要具有以下内容的Ubuntu 20.04服务器:
A non-root user with sudo privileges. The guide explains how to set this up.
具有sudo特权的非root用户。 《 指南介绍了如何进行设置。
Docker installed with the instructions from Step 1 and Step 2 of
Docker已按照 步骤1和步骤2中的说明进行
Note: Even though the Prerequisites give instructions for installing Docker on Ubuntu 20.04, the docker
commands for Docker data volumes in this article should work on other operating systems as long as Docker is installed and the sudo user has been added to the docker
group.
注意:即使前提条件提供了在Ubuntu 20.04上安装Docker的说明,但只要安装了Docker且sudo用户已添加到docker
组中,本文中用于Docker数据卷的docker
命令就应在其他操作系统上运行。
Introduced in Docker’s 1.9 release, the docker volume create
command allows you to create a volume without relating it to any particular container. We’ll use this command to add a volume named DataVolume1
:
在Docker 1.9版本中引入的docker volume create
命令允许您创建卷而不将其与任何特定容器相关联。 我们将使用此命令添加一个名为DataVolume1
的卷:
The name is displayed, indicating that the command was successful:
显示名称,表明命令成功:
Output DataVolume1
To make use of the volume, we’ll create a new container from the Ubuntu image, using the --rm
flag to automatically delete it when we exit. We’ll also use -v
to mount the new volume. -v
requires the name of the volume, a colon, then the absolute path to where the volume should appear inside the container. If the directories in the path don’t exist as part of the image, they’ll be created when the command runs. If they do exist, the mounted volume will hide the existing content:
为了利用该卷,我们将从Ubuntu映像创建一个新容器,使用--rm
标志在退出时自动将其删除。 我们还将使用-v
挂载新卷。 -v
要求该卷的名称,冒号,然后是该卷应出现在容器内的绝对路径。 如果路径中的目录不作为映像的一部分存在,则将在命令运行时创建它们。 如果它们确实存在,那么已装载的卷将隐藏现有内容:
While in the container, let’s write some data to the volume:
在容器中时,让我们向卷中写入一些数据:
Because we used the --rm
flag, our container will be automatically deleted when we exit. Our volume, however, will still be accessible.
因为我们使用了--rm
标志,所以我们的容器在退出时将被自动删除。 但是,我们仍然可以访问我们的书。
We can verify that the volume is present on our system with docker volume inspect
:
我们可以使用docker volume inspect
验证系统上是否存在该卷:
Output [ { "CreatedAt": "2018-07-11T16:57:54Z", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/DataVolume1/_data", "Name": "DataVolume1", "Options": {}, "Scope": "local" }]
Note: We can even look at the data on the host at the path listed as the Mountpoint
. We should avoid altering it, however, as it can cause data corruption if applications or containers are unaware of changes.
注意:我们甚至可以在列为Mountpoint
的路径上查看主机上的数据。 但是,我们应该避免更改它,因为如果应用程序或容器不知道更改,它可能导致数据损坏。
Next, let’s start a new container and attach DataVolume1
:
接下来,让我们启动一个新容器并附加DataVolume1
:
Verify the contents:
验证内容:
Output Example1
Exit the container:
退出容器:
In this example, we created a volume, attached it to a container, and verified its persistence.
在此示例中,我们创建了一个卷,将其附加到一个容器上,并验证了其持久性。
In our next example, we’ll create a volume at the same time as the container, delete the container, then attach the volume to a new container.
在下一个示例中,我们将与容器同时创建一个卷,删除该容器,然后将该卷附加到新的容器上。
We’ll use the docker run
command to create a new container using the base Ubuntu image. -t
will give us a terminal, and -i
will allow us to interact with it. For clarity, we’ll use --name
to identify the container.
我们将使用docker run
命令使用基本的Ubuntu映像创建一个新容器。 -t
将为我们提供一个终端, -i
将使我们与其进行交互。 为了清楚起见,我们将使用--name
标识容器。
The -v
flag will allow us to create a new volume, which we’ll call DataVolume2
. We’ll use a colon to separate this name from the path where the volume should be mounted in the container. Finally, we will specify the base Ubuntu image and rely on the default command in the , bash
, to drop us into a shell:
-v
标志将允许我们创建一个新的卷,我们将其称为DataVolume2
。 我们将使用冒号将该名称与应在容器中装入卷的路径分开。 最后,我们将指定基本的Ubuntu映像,并依靠 bash
的默认命令将我们放入一个shell中:
Note: The -v
flag is very flexible. It can bindmount or name a volume with just a slight adjustment in syntax. If the first argument begins with a /
or ~/
you’re creating a bindmount. Remove that, and you’re naming the volume. For example:
注意: -v
标志非常灵活。 只需稍微调整一下语法,就可以绑定或命名卷。 如果第一个参数以/
或~/
开头,则说明您正在创建一个bindmount。 删除它,您正在命名该卷。 例如:
-v /path:/path/in/container
mounts the host directory, /path
at the /path/in/container
-v /path:/path/in/container
安装主机目录, /path
在/path/in/container
-v path:/path/in/container
creates a volume named path
with no relationship to the host.
-v path:/path/in/container
创建一个名为path
的卷,该卷与主机无关。
For more on bindmounting a directory from the host, see
有关从主机绑定挂载目录的更多信息,请参见
While in the container, we’ll write some data to the volume:
在容器中时,我们将一些数据写入卷:
Output Example2
Let’s exit the container:
让我们退出容器:
When we restart the container, the volume will mount automatically:
重新启动容器时,该卷将自动安装:
Let’s verify that the volume has indeed mounted and our data is still in place:
让我们验证该卷确实已装入并且我们的数据仍然存在:
Output Example2
Finally, let’s exit and clean up:
最后,让我们退出并清理:
Docker won’t let us remove a volume if it’s referenced by a container. Let’s see what happens when we try:
如果容器引用了Docker,则Docker不允许我们删除它。 让我们看看尝试时会发生什么:
The message tells us that the volume is still in use and supplies the long version of the container ID:
该消息告诉我们该卷仍在使用中,并提供了长版本的容器ID:
Output Error response from daemon: unable to remove volume: remove DataVolume2: volume is in use - [d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63]
We can use this ID to remove the container:
我们可以使用此ID删除容器:
docker rm d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
码头工人rm d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
Output d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
Removing the container won’t affect the volume. We can see it’s still present on the system by listing the volumes with docker volume ls
:
卸下容器不会影响体积。 通过使用docker volume ls
列出卷,我们可以看到它仍然存在于系统中:
Output DRIVER VOLUME NAMElocal DataVolume2
And we can use docker volume rm
to remove it:
我们可以使用docker volume rm
删除它:
In this example, we created an empty data volume at the same time that we created a container. In our next example, we’ll explore what happens when we create a volume with a container directory that already contains data.
在此示例中,我们在创建容器的同时创建了一个空的数据卷。 在我们的下一个示例中,我们将探索在创建具有包含数据的容器目录的卷时发生的情况。
Generally, creating a volume independently with docker volume create
and creating one while creating a container are equivalent, with one exception. If we create a volume at the same time that we create a container and we provide the path to a directory that contains data in the base image, that data will be copied into the volume.
通常,除了docker volume create
,独立创建一个卷以及在创建容器时创建一个卷是等效的,只有一个例外。 如果我们在创建容器的同时创建一个卷, 并且提供了在基础映像中包含数据的目录的路径,则该数据将被复制到该卷中。
As an example, we’ll create a container and add the data volume at /var
, a directory which contains data in the base image:
作为示例,我们将创建一个容器并将数据量添加到/var
,该目录在基础映像中包含数据:
All the content from the base image’s /var
directory is copied into the volume, and we can mount that volume in a new container.
基本映像/var
目录中的所有内容都将复制到该卷中,我们可以将该卷装入新容器中。
Exit the current container:
退出当前容器:
This time, rather than relying on the base image’s default bash
command, we’ll issue our own ls
command, which will show the contents of the volume without entering the shell:
这次,我们将不再使用基本映像的默认bash
命令,而是发出自己的ls
命令,该命令将显示卷的内容而无需进入shell:
The directory datavolume3
now has a copy of the contents of the base image’s /var
directory:
现在,目录datavolume3
具有基本映像的/var
目录的内容的副本:
Output backupscacheliblocallocklogmailoptrunspooltmp
It’s unlikely that we would want to mount /var/
in this way, but this can be helpful if we’ve crafted our own image and want an easy way to preserve data. In our next example, we’ll demonstrate how a volume can be shared between multiple containers.
我们不太可能希望以这种方式挂载/var/
,但是如果我们精心制作了自己的映像并想要一种简单的方法来保存数据,这可能会有所帮助。 在下一个示例中,我们将演示如何在多个容器之间共享卷。
So far, we’ve attached a volume to one container at a time. Often, we’ll want multiple containers to attach to the same data volume. This is relatively straightforward to accomplish, but there’s one critical caveat: at this time, Docker doesn’t handle file locking. If you need multiple containers writing to the volume, the applications running in those containers must be designed to write to shared data stores in order to prevent data corruption.
到目前为止,我们一次将一个卷附加到一个容器。 通常,我们希望多个容器连接到同一数据量。 这是相对容易实现的,但是有一个关键的警告:目前,Docker不处理文件锁定。 如果需要将多个容器写入卷,则必须将在这些容器中运行的应用程序设计为写入共享数据存储,以防止数据损坏。
Use docker run
to create a new container named Container4
with a data volume attached:
使用docker run
创建一个名为Container4
的新容器,并附加一个数据卷:
Next we’ll create a file and add some text:
接下来,我们将创建一个文件并添加一些文本:
Then, we’ll exit the container:
然后,我们将退出容器:
This returns us to the host command prompt, where we’ll make a new container that mounts the data volume from Container4
.
这将使我们返回到主机命令提示符,在此处将创建一个新容器,该容器将挂载Container4
的数据量。
We’re going to create Container5
, and mount the volumes from Container4
:
我们将创建Container5
,并从Container4
装载卷:
Let’s check the data persistence:
让我们检查数据持久性:
Output This file is shared between containers
Now let’s append some text from Container5
:
现在,让我们从Container5
附加一些文本:
Finally, we’ll exit the container:
最后,我们将退出容器:
Next, we’ll check that our data is still present to Container4
.
接下来,我们将检查我们的数据是否仍存在于Container4
。
Let’s check for the changes that were written to the data volume by Container5
by restarting Container4
:
让我们通过重新启动Container4
来检查Container5
写入数据卷的更改:
Check for the changes:
检查更改:
Output This file is shared between containersBoth containers can write to DataVolume4
Now that we’ve verified that both containers were able to read and write from the data volume, we’ll exit the container:
现在,我们已经验证了两个容器都可以从数据量读取和写入数据,我们将退出该容器:
Again, Docker doesn’t handle any file locking, so applications must account for the file locking themselves. It is possible to mount a Docker volume as read-only to ensure that data corruption won’t happen by accident when a container requires read-only access by adding :ro
. Let’s look at how this works.
同样,Docker不处理任何文件锁定,因此应用程序必须自行解决文件锁定问题。 通过添加:ro
可以将Docker卷安装为只读,以确保在容器需要只读访问时不会偶然发生数据损坏。 让我们看看它是如何工作的。
Once a volume has been mounted in a container, rather than unmounting it like we would with a typical Linux file system, we can instead create a new container mounted the way we want and, if needed, remove the previous container. To make the volume read-only, we append :ro
to the end of the container name:
一旦将卷安装到容器中,而不是像使用典型的Linux文件系统那样卸载卷,我们可以创建一个新容器以所需的方式安装,并在需要时删除以前的容器。 为了使该卷为只读,我们在容器名称的末尾附加:ro
:
We’ll check the read-only status by trying to remove our example file:
我们将通过尝试删除示例文件来检查只读状态:
Output rm: cannot remove '/datavolume4/Example4.txt': Read-only file system
Finally, we’ll exit the container and clean up our test containers and volumes:
最后,我们将退出容器并清理测试容器和卷:
Now that we’re done, let’s clean up our containers and volume:
现在我们完成了,让我们清理容器和卷:
In this example, we’ve shown how to share data between two containers using a data volume and how to mount a data volume as read-only.
在此示例中,我们展示了如何使用数据卷在两个容器之间共享数据以及如何将数据卷安装为只读。
In this tutorial, we created a data volume which allowed data to persist through the deletion of a container. We shared data volumes between containers, with the caveat that applications will need to be designed to handle file locking to prevent data corruption. Finally, we showed how to mount a shared volume in read-only mode. If you’re interested in learning about sharing data between containers and the host system, see .
在本教程中,我们创建了一个数据卷,该数据卷允许通过删除容器来保留数据。 我们在容器之间共享数据量,但需要警告的是,将应用程序设计为处理文件锁定以防止数据损坏。 最后,我们展示了如何以只读模式挂载共享卷。 如果您对学习在容器和主机系统之间共享数据感兴趣,请参阅 。
翻译自:
docker 容器共享数据
转载地址:http://xlhgb.baihongyu.com/