Docker数据管理

2015/06/05 10:25 am posted in  Docker

用户在使用Docker的过程中,往往需要能查看容器内应用产生的数据,或者需要把容器内的数据进行备份,甚至多个容器之间进行数据共享,这必然涉及到Docker的数据管理。 容器中管理数据主要有两种方式:

  • 数据卷(Data Volumes)
  • 数据卷容器(Data Volumes Dontainers)

数据卷

数据卷是一个可供容器使用的特殊目录,他绕过文件系统,可以提供很多有用的特性:

  • 数据卷可以在容器之间共享和重用
  • 对数据卷的修改会立马生效
  • 对数据卷的更新,不会影响到镜像
  • 卷会一直存在,直到没有容器使用

数据卷的使用,类似于Linux下对目录或文件进行mount操作。

创建一个数据卷

在使用docker run命令的时候,使用-v参数可以在容器内创造一个数据卷,如果多次使用-v参数可以创造多个数据卷。 比如创建一个私有仓库的时候:

docker run -d -p 5000:5000 --name registry -v /tmp/registry registry

创建一个/tmp/registry数据卷挂在到这个容器里。

挂在一个主机目录作为数据卷

使用-v参数也可以制定挂在一个本地已有的目录到容器中作为数据卷,还是举创建私有仓库的例子:

docker run -d -p 5000:5000 --name registry -v /data/registry:/tmp/registry registry

这样便是把本地的/data/registry挂在到容器中作为/tmp/registry。不过本地目录一定要是绝对路径,如果,目录不存在Docker会自动创建。 另外,Docker挂在数据卷的默认权限是读写(rw),也可以使用(ro)指定为只读权限:

docker run -d -p 5000:5000 --name registry -v /data/registry:/tmp/registry:ro registry

这样容器就没有写入的权限了。

挂在一个主机文件作为数据卷

也是可以把主机的一个文件挂在到容器中作为数据卷,使用命令和挂在目录一样。 不过直接挂在一个文件到容器中,又在外部编辑文件有可能导致文件inode信息的改变,从Docker1.1.0起,这回导致错误信息。 所以建议挂在目录以达到访问文件的目的。

数据卷容器

如果需要在容器之间共享一些持续的更新的数据,最简单的方式是使用数据卷容器。数据卷容器其实就是一个普通的容器,专门用它提供数据卷提供其他容器挂载。使用方法如下: 首先,创建一个数据卷容器比如dbdata,并在其中创建一个数据卷并挂在到/dbdata。

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

然后可以在其他容器使用--volumes-from来挂载dbdata容器中的数据卷。例如创建db1和db2两个容器,并从dadata容器挂在数据卷。

docker run -it --volumes-from dbdata --name db1 ubuntu
docker run -it --volumes-from dbdata --name db2 ubuntu

完成后,db1和db2都挂载同一个数据卷到相同的/dbdata目录。三个容器任何一方在该目录下的写入,其他容器都可以看得到。 可以多次使用--volumes-from从而从多个容器中获得多个数据卷,也可以从其他已经挂在容器卷的容器挂在数据卷。 使用--volumes-from参数所挂载的容器自身不需要保存在运行状态。

删除数据卷容器

如果删除了挂载的容器比如删除了dbdata,db1,数据卷并不会被自动删除,因为此时还有一个db2正在使用这个数据卷容器。 如果想删除一个数据卷必须在删除最后一个还挂载着它的容器时显式使用docker rm-v命令来制定同时删除关联的容器。

利用数据卷容器迁移数据

可以利用数据卷容器对其中的数据卷进行备份、回复,以实现数据的迁移。

备份

使用下面的命令来备份dbdata数据卷容器内的数据卷:

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

很长,慢慢分析,首先是要建立一个利用ubuntu镜像容器,把本地当前路径挂在到容器的/backup下,容器执行的命令是tar cvf /backup/backup.tar /dbdata,命令达到的效果就是吧/dbdata压缩并保存到/backup下。 因为/backup是由本地当前路径挂载的,因此就是保存到当前路径下,从而实现备份的效果。

恢复

如果要恢复数据到容器中,可以按照下面的操作。 首先创建一个带有数据卷的容器dbdata2:

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

然后创建另一个新容器,挂在dbdata2容器,使用tar解压备份文件到所挂载的容器卷中即可:

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

容器是廉价的,数据是宝贵的,根据数据卷和本地的挂载以及容器之间容器卷的共享实现数据备份和还原很方便(说的好违心),总之,数据备份和恢复是没有问题了。