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

news/2024/7/3 2:42:06

docker 容器共享数据

介绍 (Introduction)

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 Volumes.

通常,Docker容器是临时的,运行时间与容器中发出的命令完成所需的时间一样长。 但是,有时,在删除容器后,应用程序需要共享对数据的访问或保留数据。 数据库,用户为网站生成的内容以及日志文件只是不实际或不可能包含在Docker映像中但需要访问应用程序的数据的几个示例。 Docker Volumes提供了对数据的持久访问。

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可以在创建容器的同一命令中创建和附加,也可以独立于任何容器创建并随后附加。 在本文中,我们将研究在容器之间共享数据的四种不同方式。

先决条件 (Prerequisites)

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 Initial Server Setup with Ubuntu 20.04 guide explains how to set this up.

    具有sudo特权的非root用户。 《 使用Ubuntu 20.04进行服务器初始设置》指南介绍了如何进行设置。

  • Docker installed with the instructions from Step 1 and Step 2 of How To Install and Use Docker on Ubuntu 20.04

    Docker已按照如何在Ubuntu 20.04上安装和使用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命令就应在其他操作系统上运行。

第1步-创建独立卷 (Step 1 — Creating an Independent Volume)

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的卷:

  • docker volume create --name DataVolume1

    码头工人卷创建-名称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要求该卷的名称,冒号,然后是该卷应出现在容器内的绝对路径。 如果路径中的目录不作为映像的一部分存在,则将在命令运行时创建它们。 如果它们确实存在,那么已装载的卷将隐藏现有内容:

  • docker run -ti --rm -v DataVolume1:/datavolume1 ubuntu

    docker运行-ti --rm -v DataVolume1:/ datavolume1 ubuntu

While in the container, let’s write some data to the volume:

在容器中时,让我们向卷中写入一些数据:

  • echo "Example1" > /datavolume1/Example1.txt

    回声“ Example1”> /datavolume1/Example1.txt

Because we used the --rm flag, our container will be automatically deleted when we exit. Our volume, however, will still be accessible.

因为我们使用了--rm标志,所以我们的容器在退出时将被自动删除。 但是,我们仍然可以访问我们的书。

  • exit

    出口

We can verify that the volume is present on our system with docker volume inspect:

我们可以使用docker volume inspect验证系统上是否存在该卷:

  • docker volume inspect DataVolume1

    码头工人卷检查DataVolume1

   
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

  • docker run --rm -ti -v DataVolume1:/datavolume1 ubuntu

    泊坞窗运行--rm -ti -v DataVolume1:/ datavolume1 ubuntu

Verify the contents:

验证内容:

  • cat /datavolume1/Example1.txt

    猫/datavolume1/Example1.txt

   
Output
Example1

Exit the container:

退出容器:

  • exit

    出口

In this example, we created a volume, attached it to a container, and verified its persistence.

在此示例中,我们创建了一个卷,将其附加到一个容器上,并验证了其持久性。

步骤2 —创建在删除容器后仍存在的卷 (Step 2 — Creating a Volume that Persists when the Container is Removed)

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 Ubuntu base image’s Docker file, bash, to drop us into a shell:

-v标志将允许我们创建一个新的卷,我们将其称为DataVolume2 。 我们将使用冒号将该名称与应在容器中装入卷的路径分开。 最后,我们将指定基本的Ubuntu映像,并依靠Ubuntu基本映像的Docker文件 bash的默认命令将我们放入一个shell中:

  • docker run -ti --name=Container2 -v DataVolume2:/datavolume2 ubuntu

    docker运行-ti --name = Container2 -v DataVolume2:/ datavolume2 ubuntu

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 How To Share Data between a Docker Container and the Host

有关从主机绑定挂载目录的更多信息,请参见如何在Docker容器和主机之间共享数据

While in the container, we’ll write some data to the volume:

在容器中时,我们将一些数据写入卷:

  • echo "Example2" > /datavolume2/Example2.txt

    回声“ Example2”> /datavolume2/Example2.txt
  • cat /datavolume2/Example2.txt

    猫/datavolume2/Example2.txt

   
Output
Example2

Let’s exit the container:

让我们退出容器:

  • exit

    出口

When we restart the container, the volume will mount automatically:

重新启动容器时,该卷将自动安装:

  • docker start -ai Container2

    docker start -ai Container2

Let’s verify that the volume has indeed mounted and our data is still in place:

让我们验证该卷确实已装入并且我们的数据仍然存在:

  • cat /datavolume2/Example2.txt

    猫/datavolume2/Example2.txt

   
Output
Example2

Finally, let’s exit and clean up:

最后,让我们退出并清理:

  • exit

    出口

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不允许我们删除它。 让我们看看尝试时会发生什么:

  • docker volume rm DataVolume2

    docker卷rm DataVolume2

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列出卷,我们可以看到它仍然存在于系统中:

  • docker volume ls

    docker卷ls

   
Output
DRIVER VOLUME NAME local DataVolume2

And we can use docker volume rm to remove it:

我们可以使用docker volume rm删除它:

  • docker volume rm DataVolume2

    docker卷rm DataVolume2

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.

在此示例中,我们在创建容器的同时创建了一个空的数据卷。 在我们的下一个示例中,我们将探索在创建具有包含数据的容器目录的卷时发生的情况。

第3步-从现有目录创建包含数据的卷 (Step 3 — Creating a Volume from an Existing Directory with 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 ,该目录在基础映像中包含数据:

  • docker run -ti --rm -v DataVolume3:/var ubuntu

    docker运行-ti --rm -v DataVolume3:/ var ubuntu

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:

退出当前容器:

  • exit

    出口

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:

  • docker run --rm -v DataVolume3:/datavolume3 ubuntu ls datavolume3

    泊坞窗运行--rm -v DataVolume3:/ datavolume3 ubuntu ls datavolume3

The directory datavolume3 now has a copy of the contents of the base image’s /var directory:

现在,目录datavolume3具有基本映像的/var目录的内容的副本:


   
Output
backups cache lib local lock log mail opt run spool tmp

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/ ,但是如果我们精心制作了自己的映像并想要一种简单的方法来保存数据,这可能会有所帮助。 在下一个示例中,我们将演示如何在多个容器之间共享卷。

步骤4 —在多个Docker容器之间共享数据 (Step 4 — Sharing Data Between Multiple Docker Containers)

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不处理文件锁定。 如果需要将多个容器写入卷,则必须将在这些容器中运行的应用程序设计为写入共享数据存储,以防止数据损坏。

创建Container4和DataVolume4 (Create Container4 and DataVolume4)

Use docker run to create a new container named Container4 with a data volume attached:

使用docker run创建一个名为Container4的新容器,并附加一个数据卷:

  • docker run -ti --name=Container4 -v DataVolume4:/datavolume4 ubuntu

    docker运行-ti --name = Container4 -v DataVolume4:/ datavolume4 ubuntu

Next we’ll create a file and add some text:

接下来,我们将创建一个文件并添加一些文本:

  • echo "This file is shared between containers" > /datavolume4/Example4.txt

    echo“此文件在容器之间共享”> /datavolume4/Example4.txt

Then, we’ll exit the container:

然后,我们将退出容器:

  • exit

    出口

This returns us to the host command prompt, where we’ll make a new container that mounts the data volume from Container4.

这将使我们返回到主机命令提示符,在此处将创建一个新容器,该容器将挂载Container4的数据量。

创建Container5并从Container4安装卷 (Create Container5 and Mount Volumes from Container4)

We’re going to create Container5, and mount the volumes from Container4:

我们将创建Container5 ,并从Container4装载卷:

  • docker run -ti --name=Container5 --volumes-from Container4 ubuntu

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

Let’s check the data persistence:

让我们检查数据持久性:

  • cat /datavolume4/Example4.txt

    cat /datavolume4/Example4.txt

   
Output
This file is shared between containers

Now let’s append some text from Container5:

现在,让我们从Container5附加一些文本:

  • echo "Both containers can write to DataVolume4" >> /datavolume4/Example4.txt

    回声“两个容器都可以写入DataVolume4” >> /datavolume4/Example4.txt

Finally, we’ll exit the container:

最后,我们将退出容器:

  • exit

    出口

Next, we’ll check that our data is still present to Container4.

接下来,我们将检查我们的数据是否仍存在于Container4

查看Container5中所做的更改 (View Changes Made in Container5)

Let’s check for the changes that were written to the data volume by Container5 by restarting Container4:

让我们通过重新启动Container4来检查Container5写入数据卷的更改:

  • docker start -ai Container4

    docker start -ai Container4

Check for the changes:

检查更改:

  • cat /datavolume4/Example4.txt

    cat /datavolume4/Example4.txt

   
Output
This file is shared between containers Both 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:

现在,我们已经验证了两个容器都可以从数据量读取和写入数据,我们将退出该容器:

  • exit

    出口

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卷安装为只读,以确保在容器需要只读访问时不会偶然发生数据损坏。 让我们看看它是如何工作的。

启动容器6并以只读方式安装卷 (Start Container 6 and Mount the Volume Read-Only)

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

  • docker run -ti --name=Container6 --volumes-from Container4:ro ubuntu

    docker run -ti --name = Container6 --volumes-from Container4:ro ubuntu

We’ll check the read-only status by trying to remove our example file:

我们将通过尝试删除示例文件来检查只读状态:

  • rm /datavolume4/Example4.txt

    rm /datavolume4/Example4.txt

   
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:

最后,我们将退出容器并清理测试容器和卷:

  • exit

    出口

Now that we’re done, let’s clean up our containers and volume:

现在我们完成了,让我们清理容器和卷:

  • docker rm Container4 Container5 Container6

    docker rm Container4容器5 Container6
  • docker volume rm DataVolume4

    泊坞窗卷rm DataVolume4

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.

在此示例中,我们展示了如何使用数据卷在两个容器之间共享数据以及如何将数据卷安装为只读。

结论 (Conclusion)

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 How To Share Data between the Docker Container and the Host.

在本教程中,我们创建了一个数据卷,该数据卷允许通过删除容器来保留数据。 我们在容器之间共享数据量,但需要警告的是,将应用程序设计为处理文件锁定以防止数据损坏。 最后,我们展示了如何以只读模式挂载共享卷。 如果您对学习在容器和主机系统之间共享数据感兴趣,请参阅如何在Docker容器和主机之间共享数据 。

翻译自: https://www.digitalocean.com/community/tutorials/how-to-share-data-between-docker-containers

docker 容器共享数据


http://www.niftyadmin.cn/n/3648134.html

相关文章

SpringBoot的官方英文介绍(中文译本)

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run". 翻译:SpringBoot可以很简单的创建一个基于项目的单机版,生产环境水平的Spring框架,从而让你的项目运行…

X Window研究笔记(20)

X Window研究笔记(20)转载时请注明出处和作者联系方式作者联系方式:李先静 20.X Window资源管理在X Window中,资源是一个广泛使用的概念。它包括图片、光标和窗口等对象,可以是内置的,也可以是注册的。每个资源都有一个ID&#xf…

SVN项目更新失败被锁定的解决方案

相关网址: 标题:svn更新项目提示该项目已锁定,svn“清理”解决问题 网址:https://blog.csdn.net/strwangfan/article/details/78748393 标题:SVN被锁定解决办法 网址:https://blog.csdn.net/strwangfan…

通过DigitalOcean Kubernetes扩展应用程序以实现增长

视频 (Video) 介绍 (Introduction) Effectively scaling your SaaS is imperative to business growth. Once you have built your application, it’s time to prepare for growth in usage. When to scale up? When to scale down? What metric to track for scaling? How…

X Window研究笔记(21)

X Window研究笔记(21)转载时请注明出处和作者联系方式作者联系方式:李先静 21.X Window 字符串与AtomAtom是X Window中的一大特色,不把它弄清楚,可能会对阅读其它代码形成障碍。X Window把常用的字串用一个hash表来管理,并给这些字…

react 实现滚动加载_如何在React中实现平滑滚动

react 实现滚动加载介绍 (Introduction) Smooth scrolling is when instead of clicking on a button and being instantly taken to a different part of the same page, the user is navigated there via a scroll animation. It’s one of those subtle UI features on a si…

jsp、freemarker、velocity、thymeleaf模板引擎优缺点

1、概述 在java领域,表现层技术主要有三种, (1)jsp; (2)freemarker; (3)velocity; (4)thymeleaf; 2、jsp 优点: 1、功能强大,可…

X Window研究笔记(22)

X Window研究笔记(22)转载时请注明出处和作者联系方式作者联系方式:李先静 22.X Window 简单示例对大多数linux程序员来说,很少有机会直接用Xlib去开发应用程序,那样开发效率太低,一般都是使用基于像GTK+和QT这样的too…