使用Docker的过程中,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,这必然涉及容器的数据管理操作。
容器中管理数据主要有两种方式:

  • 数据卷(Data Volumes):容器内数据直接映射到本地主机环境。
  • 数据卷容器(Data Volume Containers):使用专门容器维护数据卷。

6.1 数据卷

数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似于Linux中的mount操作。
数据卷可以提供很多有用的特性:

  • 数据卷可以在多个容器之间共享和重用,方便容器间数据传递和共享。
  • 对数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作。
  • 对数据卷更新不会影响镜像,解耦了应用和数据。
  • 卷会一直存在,直到没有容器使用,可以安全地卸载它。

    1. 在容器内创建一个数据卷

    在使用 docker create/run 命令时,可以通过 --volume/-v 参数在容器内创建一个数据卷。多次重复添加--volume/-v 参数,可以创建多个数据卷。
    这种方式指定了数据卷名称,但没有指定与宿主主机上哪个目录关联,因此docker会自动在宿主主机的/var/lib/docker/volumes 。 目录下创建一个随机名称的目录,与该数据卷关联。可以通过 docker insppect 命令查看该容器数据卷实际关联目录。
    例:
    1. docker run -d -P --name web -v /webapp training/webapp python app.py
    其中,-d代表守护态;-P是将容器暴露的所有端口随机映射到主机的端口上;-v代表在容器中创建一个数据卷目录。

    2. 挂载一个本地主机目录作为数据卷

    功能:指定本地一个目录挂在到容器中去,作为某个数据卷目录。
    例:挂载本地的/src/webapp目录到容器的/opt/webapp目录。
    1. docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

    3.挂载一个本地主机文件作为数据卷(不推荐)

    例:将.bash_history文件挂在到容器中
    1. docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
    其中 --rm 参数表示容器退出后自动删除。
    这种方式在修改挂载文件时,可能造成文件inode改变,进而导致容器报错。所以不推荐。

6.2 数据卷容器

如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,但是它的目的是专门用来提供数据卷供其它容器挂载
使用示例:
1.创建一个容器dbdata,并在其中创建一个数据卷:

  1. docker run -it -v /dbdata --name dbdata ubuntu

2.创建另外的容器,从dbdata容器导入数据卷:

  1. docker run -it --volume-from dbdata --name db1 ubuntu
  2. docker run -it --volume-from dbdata --name db2 ubuntu

此时dbdata、db1、db2三个容器共享同一个/dbdata数据卷。任意一个容器修改了该目录下的内容,其他容器都能同步获取到。
可以多次使用—volumes-from参数来从多个容器挂载多个数据卷。还可以从其他已经挂载了别的容器数据卷的容器来挂载数据卷。

  1. docker run -it --volume-from db1 --name db3 ubuntu

—volumes-from参数指定的目标容器,并不需要处于运行状态。这说明volume-from只是复制目标容器的volume配置而已,并不依赖于目标容器提供什么服务。
如果删除了挂载了数据卷的容器,数据卷并不会自动删除。**如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时显式指定 -v 参数**:

  1. docker rm -v dbdata

6.3 利用数据卷容器迁移数据

可以利用数据卷容器对其中的数据进行备份、恢复,以实现数据的迁移。其原理就是找到数据卷目录所对应的实际本机目录,然后备份其中的数据。

备份

  1. docker run \
  2. --volume-from dbdata
  3. -v ${pwd}:/backup \
  4. --name worker \
  5. ubuntu \
  6. tar cvf /backup/backup.tar /dbdata

命令详解:

  • 首先利用ubuntu镜像创建了一个容器,名为worker。
  • 使用—volumes-from dbdata参数让worker容器挂在dbdata容器的数据卷(/dbdata)。
  • 使用-v ${pwd}:/backup参数来把本地的当前目录挂载到worker容器的/backup目录。(注意,此时worker容器中有两个数据卷,一个是/dbdata,和容器数据卷共享,实际关联的本机目录未知。另一个是/backup,实际关联的本机目录就是当前目录。)
  • worker容器启动后,使用tar cvf /backup/backup.tar /dbdata命令,将/dbdata下的内容打包到/backup/backup.tar。此时我们本机当前目录就有了backup.tar。至此完成了备份。

    恢复

    将上一步备份的数据恢复到一个数据卷容器中的步骤:
  1. 创建一个带有数据卷的容器,作为数据卷容器:

    1. docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
  2. 创建另一个容器,它从dbdata2导入数据卷,同时再将本机当前目录挂载到它的/backup数据卷上。此时该容器有两个数据卷,一个是与dbdata2共享的/dbdata,另一个是与本机当前目录关联的/backup。由于是与本机当前目录关联,自然/backup目录下就有backup.tar这个文件。因此在容器中执行解压命令,将其从/backup目录解压到/dbdata目录,即完成了恢复。

    1. docker run \
    2. --volumes-from dbdata2 \
    3. -v ${pwd}:/backup \
    4. busybox \
    5. tar xvf /backup/backup.tar

参考资料:http://dockone.io/article/128