2.2.3、管理容器里的数据

来源:互联网 发布:清华紫光档案软件 编辑:程序博客网 时间:2024/05/16 16:18

管理容器里的数据

到目前为止,我们已经介绍了一些docker基本概念,也明白怎样使用Docker的镜像,而且学习有关容器之间的网络和链接。在这个章节里,我们将讨论你应该如何管理容器内部和容器之间共享的数据。

接下来,我们将介绍docker内部数据管理两个主要方法。

  • 数据卷
  • 数据卷容器

数据卷

数据卷是指在存在于一个或多个容器中的特定目录。它可以绕开联合文件系统(Union File System),为数据的持续化或共享提供一些有用的特性:

  • 在容器被创建的时候,数据也被初始化。如果容器的基础镜像包含一个指定的数据挂载点,在数据卷初始化的时候,挂载点的数据会被复制到新的数据卷中。
  • 数据卷可以在容器之间共享和重用。
  • 数据卷中的更改可以直接生效。
  • 数据卷丢失掉你在更新镜像期间的数据。
  • 数据卷持久化,甚至与之关联的容器被删除后。

数据卷设计的初衷就是持久化数据,与容器的生命周期是独立关系。因此,当你删除一个容器的时候,Docker不会自动删除与之关联的数据卷,就算这个数据卷已经没有任何容器与之关联,“垃圾回收”也不会回收它(删除)。

添加一个数据卷

在使用 docker create 和 docker run 命令时,你可以使用 -v 标志为即将创建的容器添加一个数据卷。你可以多次使用 -v 标志来挂载多个数据卷。现在,让我们为web 应用挂载一个单一的数据卷。

$ docker run -d -P --name web -v /webapp training/webapp python app.py

这会在容器内部创建一个新的卷 /webapp

注意:你也可以在Dockerfile 文件里使用 VOLUME 指令,为即将创建的容器添加一个或多个新的数据卷。

Docker数据卷的默认挂载模式是“可读写”(read-write),但是,你也可以设置它为“仅可读”(read-only)模式。

$ docker run -d -P --name web -v /opt/webapp:ro training/webapp python app.py

查找数据卷路径

通过 docker inspect 命令,你可以查找到数据卷在宿主机上的路径。

$ docker inspect web

这段输出提供了容器的配置(包括数据卷)的详细说明。类似如下信息:

...Mounts": [    {        "Name": "fac362...80535",        "Source": "/var/lib/docker/volumes/fac362...80535/_data",        "Destination": "/webapp",        "Driver": "local",        "Mode": "",        "RW": true    }]...

你可以注意到上述信息,Source “Source”指定一个宿主机的路劲,Desination 指定容器内部的路径。RW 用来设置数据卷的读写模式。

挂载一个主机目录作为卷

使用 -v ,除了可以创建一个数据卷,还可以挂载本地主机目录到容器中:

注意: 如果你在Mac或Windows上使用Docker Machine,Docker会被限制访问操作系统的文件系统。Docker Machine尝试自动共享你的/Users (OS X) 或 C:\Users (Windows) 文件夹,所以,你可以使用docker run -v /Users/<path>:/<container path> ... (OS X) 或 docker run -v /c/Users/<path>:/<container path ... (Windows)来挂载你的文件或文件夹。所有的其他路径都来自你的虚拟机文件系统。

$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py 

这将会把本地目录/src/webapp挂载到容器的/opt/webapp目录。

注意:如果路径 /opt/webapp 在容器的镜像中已经存在,它的内容会被宿主机的 /src/webapp 内容覆盖,以保证连个挂载点的内容保持一致。

当在Windows上通过Git bash 使用Boot2Docker 时,这里可能会出现一个源目录名称解析的问题。你可以在源目录的开始添加一个双斜杠来修复这个问题。具体的解释在问题#12751里。

这在做测试时是非常有用的,例如我们可以挂载宿主机的源代码到容器内部,这样我们就可以看到改变源代码时的应用时如何工作的。宿主机上的目录必须是绝对路径,如果目录不存在docker会自动创建它。

注意:为了构建镜像的移植性和分享的目的,在Dockerfile 中不能采用这用方法。因为这种方式依赖了宿主机的特定目录,部署的环境千差万别,不能保证Dockerfile 在所有的环境下都能正常运行。

Docker数据卷的默认挂载模式是“可读写”(read-write),但是,你也可以设置它为“仅可读”(read-only)模式。

$ docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py

这里我们挂载同样的 /src/webapp 目录,只是添加了 ro选项来指定挂载模式为只读。 

挂载一个宿主机的文件作为数据卷

-v 标志不仅可以挂载目录,也可挂载单一的文件作为数据卷。

$ docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash

上述命令会在容器中运行一个 bash shell ,即使退出容器后,在主机上也能够看到容器中 bash shell 的命令历史。

注意: 很多文件编辑工具如 vi  sed --in-place 会导致inode 改变。Docker v1.1.0之后的版本,会产生一个错误:“sed cannot rename ./sedKdJ9Dy: Device or resource busy”。这种情况下如果想要更改挂载的文件,最好是直接挂载它的父目录。

创建、挂载数据卷容器

如果你想要容器之间数据共享,或者从非持久化容器中使用一些持久化数据,最好创建一个指定名称的数据卷容器,然后用它来挂载数据。

让我们创建一个新名字的数据容器去做数据共享。虽然这个容器里没有运行一个应用,它重用了 training/postgres 镜像,基于这个镜像创建的所有容器共享这层,节省硬盘空间。

$ docker create -v /dbdata --name dbdata training/postgres /bin/true

然后,你可以使用 --volumes-from 标志挂载 /dbdata 卷到其他的容器里。

$ docker run -d --volumes-from dbdata --name db1 training/postgres

另外容器:

$ docker run -d --volumes-from dbdata --name db2 training/postgres

如果 postgres 镜像包含一个名为 /dbdata 的目录,则 dbdata 容器挂载的数据会隐藏来自镜像的 /dbdata 文件,只能看到 dbdata 容器书卷中的文件。

你可以使用多个 --volumes-from 参数来联合多个容器的数据卷。

你也可以通过联结已经联结过的容器来扩展数据卷链。例如,通过联结 db1 或db2 容器进行链式的扩展。

$ docker run -d --name db3 --volumes-from db1 training/postgres

如果你删除了容器,包括初始化数据卷的 dbdata 或  db1 和db2,数据卷一个不会被删除的。假如你想要删除数据卷,必须在删除最后一个与之关联的容器时,显示的执行 docker rm -v 命令。方便你的容器升级或数据卷的有效迁移。

注意:当你在删除一个容器且没有指定删除它的数据卷选项-v 时,Docker不会有任何的警告提示。如果你删除容器时没有使用-v 选项,你可能会得到一个“悬空”的数据卷;这个数据卷没有任何容器与之关联。悬空的数据卷的产生很难避免且占用大量的硬盘空间。我们已经在努力的改进数据卷的管理,你可以在#14214里查看这项工作的最新进展

备份、恢复或者迁移数据卷

数据卷还有另外一个有用的功能,我们可以用它来执行备份、恢复或迁移数据。为此我们使用/--volumes-from来创建一个挂载数据卷的容器,像这样:

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

这里我们启动了一个挂载 dbdata卷的新容器,并且挂载了一个本地目录作为/backup卷。最后,我们通过使用 tar 命令将 dbdata 数据卷的内容备份到容器中的 /backup 目录下的 backup.tar 文件中。当命令完成或者容器停止,我们将会得到dbdata 数据卷的的备份。

你可以在同一容器或其他地方的容器中恢复此数据。创建一个新的容器。

$ docker run -v /dbdata --name dbdata2 ubuntu /bin/bash

然后,把刚刚备份的数据卷数据解压到新创建的容器的数据卷中。

$ docker run --volumes-from dbdata2 -v $(pwd):/backup ubuntu cd /dbdata && tar xvf /backup/backup.tar

你可以使用上述的方法结合你偏爱的工具,测试数据卷的自动化备份、迁移、恢复。

来源: <https://docs.docker.com/userguide/dockervolumes/>
 
0 0
原创粉丝点击