数据卷
Docker volume 介绍
Docker 中的数据可以存储在类似于虚拟机磁盘的介质中,在 Docker 中称为数据卷(Data Volume)。数据卷可以用来存储 Docker 应用的数据,也可以用来在 Docker 容器间进行数据共享。
数据卷呈现给 Docker 容器的形式就是一个目录,支持多个容器间共享,修改也不会影响镜像。使用 Docker 的数据卷,类似在系统中使用 mount 挂载一个文件系统。
1)一个数据卷是一个特别指定的目录,该目录利用容器的 UFS 文件系统可以为容器提供一些稳定的特性或者数据共享。数据卷可以在多个容器之间共享。
2)创建数据卷,只要在 docker run 命令后面跟上 -v 参数即可创建一个数据卷,当然也可以跟多个 -v 参数来创建多个数据卷,当创建好带有数据卷的容器后,
就可以在其他容器中通过–volumes-froms 参数来挂载该数据卷了,而不管该容器是否运行。也可以在 Dockerfile 中通过 VOLUME 指令来增加一个或者多个数据卷。
3)如果有一些数据想在多个容器间共享,或者想在一些临时性的容器中使用该数据,那么最好的方案就是你创建一个数据卷容器,然后从该临时性的容器中挂载该数据卷容器的数据。
这样,即使删除了刚开始的第一个数据卷容器或者中间层的数据卷容器,只要有其他容器使用数据卷,数据卷都不会被删除的。
4)不能使用 docker export、save、cp 等命令来备份数据卷的内容,因为数据卷是存在于镜像之外的。备份的方法可以是创建一个新容器,挂载数据卷容器,同时挂载一个本地目录,
然后把远程数据卷容器的数据卷通过备份命令备份到映射的本地目录里面。如下:
docker run -rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
5)也可以把一个本地主机的目录当做数据卷挂载在容器上,同样是在 docker run 后面跟 -v 参数,不过 -v 后面跟的不再是单独的目录了,它是 [host-dir]:[container-dir]:[rw|ro] 这样格式的,
host-dir 是一个绝对路径的地址,如果 host-dir 不存在,则 docker 会创建一个新的数据卷,如果 host-dir 存在,但是指向的是一个不存在的目录,则 docker 也会创建该目录,然后使用该目录做数据源。
Docker Volume 数据卷可以实现:
1)绕过“拷贝写”系统,以达到本地磁盘 IO 的性能,(比如运行一个容器,在容器中对数据卷修改内容,会直接改变宿主机上的数据卷中的内容,所以是本地磁盘 IO 的性能,而不是先在容器中写一份,最后还要将容器中的修改的内容拷贝出来进行同步。)
2)绕过“拷贝写”系统,有些文件不需要在 docker commit 打包进镜像文件。
3)数据卷可以在容器间共享和重用数据
4)数据卷可以在宿主和容器间共享数据
5)数据卷数据改变是直接修改的,数据卷修改会立即生效, 数据卷的更新不会影响镜像
6)数据卷是持续性的,直到没有容器使用它们。即便是初始的数据卷容器或中间层的数据卷容器删除了,只要还有其他的容器使用数据卷,那么里面的数据都不会丢失。
Docker 数据持久化:
容器在运行期间产生的数据是不会写在镜像里面的,重新用此镜像启动新的容器就会初始化镜像,会加一个全新的读写入层来保存数据。
如果想做到数据持久化,Docker 提供数据卷(Data volume)或者数据容器卷来解决问题,另外还可以通过 commit 提交一个新的镜像来保存产生的数据。
准备工作
创建一个目录,并在目录里面创建文件,文件内写入内容。
在容器内创建数据卷
在使用 docker run 的命令时,使用 -v 标记可以在容器内创建一个数据卷,并且可以指定挂在一个本地已有的目录到容器中作为数据卷:
docker run -d --name app1-it -v ${PWD}/webapp:/root/webapp ubuntu bash
通过目录跟容器内建立了一层关系,数据卷发生变化后,容器内和容器外都会随之发生改变。例如容器挂载一个文件,当容器挂了后,文件不会丢失。
注意:默认挂载的数据卷的权限是 rw(可读写),如果要求 ro(只读),则需要加上对应的 ro 参数,命令可改为:
docker run -d --name app1-it -v ${PWD}/webapp:/root/webapp:ro ubuntu bash
下面我们一起来操作一下:
创建 webapp 目录,在目录下新建文件 file,并在文件 file 中写入“hello my docker!!”。
echo ${PWD} 命令标识当前目录。
创建启动 app1 容器并挂载数据卷
进入容器找到 root 目录可查看到已挂载的数据卷。
数据卷目录与容器内目录有映射关系,所以不管是在容器内部修改数据卷还是在外部修改数据卷,相对应的数据卷都会发生改变。
只读的演示
数据卷容器
数据卷容器用于用户需要在容器间共享一些持续更新的数据,数据卷容器专门提供数据卷供其它容器挂载使用。
Example:
创建数据卷容器 db1
docker run -d --name db1 -v/dbdata -ti ubuntu bash
创建容器 db2 与 db1 共享 dbdata 的数据
docker run -d --name db2 --volumes-fromdb1 -ti ubuntu bash
在容器 db1 和容器 db2 任意一个容器修改 dbdata 的内容,在两个容器内均生效
数据卷容器的删除:
如果删除了挂载的容器,数据卷并不会被自动删除,如果要删除一个数据卷,必须在删除最后一个还挂载它的容器时显示使用 docker rm -v 命令指定同时删除关联的容器。在下图可看到即使删除 db1,db2 中仍然有 file 文件。
在 db1 中创建了文件 db1_file,db2 可以看到 db1_file,删除 db1 容器后,db1_file 在 db2 中还可以看到。
可以利用数据卷容器对其中的数据卷进行备份、恢复,以实现数据的迁移。
备份:
使用下面的命令来备份 dbdata 数据卷容器内的数据卷:
docker run --volumes-from dbdata -v ${PWD}:/backup --name worker ubuntu \tar cvf /backup/backup.tar /dbdata
说明:
利用 ubuntu 镜像创建一个容器 worker。使用–volumes-from dbdata 参数来让 worker 容器挂载 dbdata 的数据卷;使用 ${pwd}:/backup 参数来挂载本地目录到 worker 容器的 /backup 目录。
worker 启动后,使用 tar 命令将 /dbdata 下的内容备份为容器内的 /backup/backup.tar。
创建 dbdata 数据卷容器并写入文件:fileA、fileB、fileC
执行备份命令创建备份 tar 包:
恢复:
如果恢复数据到一个容器,可以参照下面的操作。首先创建一个带有数据卷的容器 dbdata2:
docker run -d -v /dbdata--name dbdata2 ubuntu /bin/bash
然后创建另一个新的容器,挂载 dbdata2 的容器,并使用 tar 命令解压备份文件到挂载的容器卷中即可:
docker run --volumes-fromdbdata2 -v ${pwd}:/backup ubuntu tar xvf /backup/backup.tar
***当你发现自己的才华撑不起野心时,就请安静下来学习吧***