使用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命令查看该容器数据卷实际关联目录。
例:
其中,-d代表守护态;-P是将容器暴露的所有端口随机映射到主机的端口上;-v代表在容器中创建一个数据卷目录。docker run -d -P --name web -v /webapp training/webapp python app.py
2. 挂载一个本地主机目录作为数据卷
功能:指定本地一个目录挂在到容器中去,作为某个数据卷目录。
例:挂载本地的/src/webapp目录到容器的/opt/webapp目录。docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
3.挂载一个本地主机文件作为数据卷(不推荐)
例:将.bash_history文件挂在到容器中
其中docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
--rm参数表示容器退出后自动删除。
这种方式在修改挂载文件时,可能造成文件inode改变,进而导致容器报错。所以不推荐。
6.2 数据卷容器
如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,但是它的目的是专门用来提供数据卷供其它容器挂载。
使用示例:
1.创建一个容器dbdata,并在其中创建一个数据卷:
docker run -it -v /dbdata --name dbdata ubuntu
2.创建另外的容器,从dbdata容器导入数据卷:
docker run -it --volume-from dbdata --name db1 ubuntudocker run -it --volume-from dbdata --name db2 ubuntu
此时dbdata、db1、db2三个容器共享同一个/dbdata数据卷。任意一个容器修改了该目录下的内容,其他容器都能同步获取到。
可以多次使用—volumes-from参数来从多个容器挂载多个数据卷。还可以从其他已经挂载了别的容器数据卷的容器来挂载数据卷。
docker run -it --volume-from db1 --name db3 ubuntu
—volumes-from参数指定的目标容器,并不需要处于运行状态。这说明volume-from只是复制目标容器的volume配置而已,并不依赖于目标容器提供什么服务。
如果删除了挂载了数据卷的容器,数据卷并不会自动删除。**如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时显式指定 -v 参数**:
docker rm -v dbdata
6.3 利用数据卷容器迁移数据
可以利用数据卷容器对其中的数据进行备份、恢复,以实现数据的迁移。其原理就是找到数据卷目录所对应的实际本机目录,然后备份其中的数据。
备份
docker run \--volume-from dbdata-v ${pwd}:/backup \--name worker \ubuntu \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。至此完成了备份。
恢复
将上一步备份的数据恢复到一个数据卷容器中的步骤:
创建一个带有数据卷的容器,作为数据卷容器:
docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
创建另一个容器,它从dbdata2导入数据卷,同时再将本机当前目录挂载到它的/backup数据卷上。此时该容器有两个数据卷,一个是与dbdata2共享的/dbdata,另一个是与本机当前目录关联的/backup。由于是与本机当前目录关联,自然/backup目录下就有backup.tar这个文件。因此在容器中执行解压命令,将其从/backup目录解压到/dbdata目录,即完成了恢复。
docker run \--volumes-from dbdata2 \-v ${pwd}:/backup \busybox \tar xvf /backup/backup.tar
