docker数据量vs挂载的主机目录


74

我们可以在docker中拥有一个数据量:

$ docker run -v /path/to/data/in/container --name test_container debian
$ docker inspect test_container
...
Mounts": [
    {
        "Name": "fac362...80535",
        "Source": "/var/lib/docker/volumes/fac362...80535/_data",
        "Destination": "/path/to/data/in/container",
        "Driver": "local",
        "Mode": "",
        "RW": true
    }
]
...

但是,如果数据量存在/var/lib/docker/volumes/fac362...80535/_data,则与使用装入文件夹中的数据有何不同-v /path/to/data/in/container:/home/user/a_good_place_to_have_data

Answers:


50

它与使用-v / path / to / data / in / container:/ home / user / a_good_place_to_have_data装入文件夹中的数据有何不同?

这是因为,如“将主机目录安装为数据卷”中所述

主机目录本质上是依赖于主机的。因此,您不能从Dockerfile挂载主机目录,因为构建的映像应该是可移植的。主机目录并非在所有潜在主机上都可用。

如果您要在容器之间共享某些持久性数据,或者要从非持久性容器中使用某些持久性数据,则最好创建一个命名的数据卷容器,然后从中装入数据。

您可以将两种方法结合使用:

 docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

在这里,我们启动了一个新容器,并从该dbdata容器装入了卷。
然后,我们将本地主机目录挂载为/backup
最后,我们传递了一个命令,该命令用于tardbdata卷的内容备份到目录backup.tar内的/backup文件中。当命令完成并且容器停止时,我们将获得dbdata卷的备份。


2
您能否阐明Docker文档表示主机目录是与主机相关的?文件权限是否是因为在某些情况下将容器和已装载目录移动到另一台主机时很难在另一台主机上进行复制而造成的?另外,命名卷和装入目录之间有什么区别?我知道,尤其是在多个容器之间共享持久数据是数据卷容器的用例。但是在持久性数据仅与单个容器相关的情况下,我有点迷失了:-)。
PermaFrost

3
@PermaFrost依赖于主机的方式意味着您无法编写带有来自主机的卷路径的Dockerfile,因为该Dockerfile可以构建在任何具有自己特征的主机上:在一个主机上有效的路径可能在另一个主机上不可用。这就是为什么挂载主机文件夹是运行时操作(docker运行),而不是编译时(docker构建)的原因
VonC

3
@PermaFrost命名卷与主机无关,并且是持久的。即使仅针对一个容器,这也意味着我可以在任何主机上导出和还原命名卷。参见madcoda.com/2016/03/docker-named-volume-explained
VonC

感谢您的解释和链接,我将看一下该文章!:)
PermaFrost

@VonC:您能澄清一下在主机系统上创建lvm并在docker上挂载与使用docker插件创建lvm并进行挂载之间有什么区别吗?应该优先于另一个吗?
user1050619

82

尽管使用卷和绑定挂载的感觉相同(唯一的变化是目录的位置),但是行为上有所不同。

卷与绑定安装

  • 使用Bind Mount,可以将主机上的文件或目录 安装到容器中。该文件或目录由主机上的完整或相对路径引用。
  • 使用Volume,在主机上Docker的存储目录中创建一个新目录,并且Docker管理该目录的内容。

与绑定安装相比,卷具有以下优势:

  • 与绑定安装相比,卷更易于备份或迁移。
  • 您可以使用Docker CLI命令或Docker API管理卷。
  • 卷在Linux和Windows容器上均可工作。
  • 可以在多个容器之间更安全地共享卷。
  • 卷驱动程序使您可以将卷存储在远程主机或云提供程序上,以加密卷内容或添加其他功能。
  • 可以通过容器预先填充新卷的内容。

编辑(9.9.2019):
根据@ Sebi2020注释,绑定安装更加容易备份。Docker不提供任何命令来备份卷。您必须使用带有绑定安装的临时容器来创建备份。

卷数

由Docker创建和管理。您可以使用docker volume create命令显式创建卷,或者Docker可以在容器或服务创建期间创建卷。

创建卷时,它存储在Docker主机上的目录中。将卷装入容器时,此目录就是装入容器的目录。这类似于绑定挂载的工作方式,除了卷由Docker管理并且与主机的核心功能隔离。

给定的体积可以同时安装到多个容器中。当没有正在运行的容器使用卷时,该卷仍可用于Docker,并且不会自动删除。您可以使用docker volume prune删除未使用的卷。

挂载卷时,它可能是命名的或匿名的。匿名卷首次安装到容器中时,不会为其指定显式名称,因此Docker为它们提供一个随机名称,该名称在给定的Docker主机中保证是唯一的。除了名称之外,命名卷和匿名卷的行为也相同。

卷还支持使用卷驱动程序,这使您可以将数据存储在远程主机或云提供商上。

在此处输入图片说明

绑定坐骑

从Docker早期开始可用。与卷相比,绑定安装的功能有限。使用绑定安装时,主机上的文件或目录将安装到容器中。文件或目录由主机上的完整路径引用。该文件或目录不需要在Docker主机上已经存在。如果尚不存在,则按需创建。绑定挂载性能非常好,但是它们依赖于具有特定目录结构可用的主机文件系统。如果要开发新的Docker应用程序,请考虑使用命名卷。您不能使用Docker CLI命令直接管理绑定安装。

在此处输入图片说明

也有tmpfs mounts
tmpfs坐骑

tmpfs挂载不会持久化在磁盘上,无论是在Docker主机上还是在容器内。容器在其生存期内可以使用它来存储非持久状态或敏感信息。例如,在内部,群集服务使用tmpfs挂载将机密安装到服务的容器中。
在此处输入图片说明

参考:https :
//docs.docker.com/storage/


7
绑定挂载更容易备份。不幸的是,Docker没有提供任何命令来备份卷。您必须使用带有绑定安装的临时容器来创建备份
Sebi2020

2
我只是想问问如何轻松备份卷,但是@ Sebi2020首先问。我认为编辑答案很公平。
Bora M. Alper

我第二个@ Sebi2020。当我在寻找备份卷的方法时来到了这里,发现它们不必要地使备份变得复杂(不同于我直觉的想法)。绑定挂载更容易备份。
Dojo

我也来这里寻找同样的东西。我确实认为卷安装的一个主要缺点是对于较旧版本的docker,当我想升级它时必须先删除当前版本。这也删除了所有docker数据(图像,容器,卷)。我不确定升级不会再发生这种情况。我同意绑定挂载更容易备份。您确切地知道数据在哪里。如果docker文档详细说明卷相对于绑定安装的优势,那将是很好的。
塔兰特里

就Windows docker卷而言,就卷而言,在Windows docker主机上有很多不起作用的地方。所以这也不是一个优势。
Tallandtree

17

是的,从几个角度来看,这是完全不同的。就像您在问题标题中所写的那样,它是关于理解为什么我们需要数据卷而不是将绑定绑定到主机。

第1部分-带有示例的基本方案

让我们采取两种情况。

情况1:Web服务器
我们想为我们的Web服务器提供一个可能经常更改的配置文件。
例如:根据当前环境公开端口。
我们可以每次使用相关的设置来重建映像,或者为每个环境创建2个不同的映像。这两种解决方案都不是很有效。

通过Bind挂载, Docker将给定的源目录挂载到容器内的某个位置。
(联合文件系统内部只读层中的原始目录/文件将被覆盖)。

例如-将动态端口绑定到nginx:

version: "3.7"
services:
  web:
    image: nginx:alpine
    volumes:
     - type: bind #<-----Notice the type
       source: ./mysite.template
       target: /etc/nginx/conf.d/mysite.template
    ports:
     - "9090:8080"
    environment:
     - PORT=8080
    command: /bin/sh -c "envsubst < /etc/nginx/conf.d/mysite.template > 
        /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"

(*)注意,此示例也可以使用Volumes解决。

案例2:数据库
Docker容器不存储持久性数据-一旦容器停止运行,将被写入容器的联合文件系统中可写层的任何数据都将丢失。

但是,如果我们有一个在容器上运行的数据库,而该容器停止了,那意味着所有数据都将丢失,该怎么办?

来救援。
这些被称为文件系统树,由Docker为我们管理。

例如-持久化Postgres SQL数据:

services:    
  db:
    image: postgres:latest
    volumes:
      - "dbdata:/var/lib/postgresql/data"
    volumes:
     - type: volume #<-----Notice the type
       source: dbdata
       target: /var/lib/postgresql/data
volumes:
  dbdata:

请注意,在这种情况下,对于命名卷,源是卷的名称(对于匿名卷,将省略此字段)。

第2部分-比较

主机管理和隔离方面的差异

绑定挂载 存在于主机文件系统上,并由主机维护者管理。
Docker外部的应用程序/进程也可以对其进行修改。

也可以在主机上实现,但是Docker将为我们管理它们,并且无法在Docker之外访问它们。

卷是一个更广泛的解决方案

尽管这两种解决方案都可以帮助我们将数据生命周期与容器分开,但是通过使用卷,您可以在系统上获得更多的功能和灵活性。

借助Volumes,我们可以通过将数据存储在专用的远程位置(例如,在云中)并将其与诸如备份,监视,加密和硬件管理之类的外部服务集成,来有效地设计数据并将其与系统的其他部分分离。


2
我感谢您提供使用示例,尤其是docker-compose ymls
Robino

4

主机目录和数据量之间的区别在于,Docker通过将其放置在$DOCKER-DATA-DIR/volumes目录中并对其附加一个引用(名称或随机生成的ID)来管理后者。那就是您得到一些便利。

主机目录和数据卷都是主机上的目录。两者均取决于主机。您不能在Dockerfile;中引用它们中的任何一个。VOLUME每次启动新容器时,该指令都会创建一个新的无名(具有随机生成的ID)卷,并且无法引用现有卷。

* $DOCKER-DATA-DIR/var/lib/docker此处,除非您更改了默认设置。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.