## 数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
* 数据卷可以在容器之间共享和重用
* 对数据卷的修改会立马生效
* 对数据卷的更新,不会影响镜像
* 数据卷默认会一直存在,即使容器被删除
>[info]注意:数据卷的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的数据卷。
## 创建数据卷
创建一个名为 web 的容器,并加载一个数据卷到容器的 `/webapp` 目录。
~~~
docker run -d -P --name web -v /webapp webapp
~~~
## 删除数据卷
数据卷是被设计用来**持久化数据**的,它的生命周期独立于容器,Docker不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 `docker rm -v`
## 挂载主机目录作为数据卷
使用 -v 标记也可以指定挂载一个本地主机的目录到容器中去。
~~~
docker run -d -P --name web -v /src/webapp:/opt/webapp webapp
~~~
Docker 挂载数据卷的默认权限是读写,用户也可以通过 :ro 指定为只读。
~~~
docker run -d -P --name web -v /src/webapp:/opt/webapp:ro webapp
~~~
>[info]注意:Dockerfile 中不支持这种用法,这是因为 Dockerfile 是为了移植和分享用的。然而,不同操作系统的路径格式不一样,所以目前还不能支持。
## 查看数据卷的具体信息
~~~
docker inspect --format "{{json .Mounts }}" dock_registry_1
~~~
## 挂载一个本地主机文件作为数据卷
记录在容器输入过的命令
~~~
sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
~~~
>[info]注意:如果直接挂载一个文件,很多文件编辑工具,包括 vi 或者 sed --inplace ,可能会造成文件 inode 的改变,从 Docker 1.1.0起,这会导致报错误信息。所以最简单的办法就直接挂载文件的父目录。
## 数据卷容器
如果你有一些持续更新的数据需要在**容器之间共享**,最好创建数据卷容器。
数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。
首先,创建一个名为 webapp_code 的数据卷容器
~~~
docker run -d -v /webapp --name webapp_code centos
~~~
在其他容器中使用 `--volumes-from` 来挂载 webapp_code 容器中的数据卷。`--volumes-from`支持级联挂载。
~~~
docker run -it --volumes-from webapp_code --name webapp_1 centos /bin/bash
docker run -it --volumes-from webapp_1 --name webapp_2 centos /bin/bash
~~~
>[info]数据卷的容器自己并不需要保持在运行状态。
## 借助于容器进行数据恢复
### 备份
![](https://box.kancloud.cn/974eb03b94ec2347334a9ea261280871_392x427.png)
首先使用 --volumes-from 标记来创建一个加载 **database 容器卷容器**,并从主机挂载**当前目录**到容器的 /backup 目录。命令如下:
~~~
docker run -d --volumes-from webapp_code -v $(pwd):/backup --name backup centos tar cf /backup/webapp.tar /webapp
~~~
容器启动后,使用了 tar 命令来将 **database** 卷备份为容器中 /backup/backup.tar.gz文件,也就是主机当前目录下的名为 backup.tar 的文件。
此处为何不直接从数据卷容器备份文件呢?
数据卷容器无法再次挂载用来备份的**数据卷**,所以只能将数据卷容器挂载到新的容器的同时挂载用来备份的数据卷,将备份文件备份到本地的文件系统中。
备份到本地后,直接解压,启动新的数据卷容器时将解压后的内容直接挂载到新的数据卷容器中。
为何不直接从本地文件系统备份数据卷容器中的内容?
### 恢复
如果要恢复数据到一个容器,首先创建一个带有**空数据卷容器** dbdata2。
~~~
docker run -d -v /webapp --name new_webapp_code centos
~~~
然后创建另一个容器(这个容器只作为**解压使用**),挂载 dbdata2 容器卷中的数据卷,并使用 untar 解压备份文件到挂载的容器卷中。
~~~
docker run -it --volumes-from new_webapp_code -v $(pwd):/backup --name temp_data centos tar xf /backup/webapp.tar
~~~
为了查看/验证恢复的数据,可以再启动一个容器挂载同样的容器卷来查看
~~~
docker run -it --volumes-from new_webapp_code centos /bin/bash
~~~
## 使用文件系统进行数据恢复
### 创建数据卷容器
创建时挂载本地的文件目录
~~~
docker run -d -v /webapp:/webapp --name webapp_code centos
~~~
在其他容器中使用 `--volumes-from` 来挂载 webapp_code 容器中的数据卷。`--volumes-from`支持级联挂载。
~~~
docker run -it --volumes-from webapp_code --name webapp_1 centos /bin/bash
docker run -it --volumes-from webapp_1 --name webapp_2 centos /bin/bash
~~~
### 本地文件系统备份
~~~
cp /webapp /webapp_backup
~~~
### 创建新的数据卷容器
~~~
docker run -d -v /webapp_backup:/webapp --name webapp_code centos
~~~