3.3.3 管理容器数据
到目前为止,我们已经介绍了一些基本的docker概念,如何管理docker 镜像,以及了解网络和容器之间的联系。
在这一节中,我们将介绍如何管理容器数据。
docker管理数据的两种主要方式。
数据卷,以及数据卷容器。
数据卷是在一个或多个容器,它绕过Union File System的一个专门指定的目录。数据卷为持续共享数据提供了一些有用的功能:
- 在创建容器时,卷被初始化。如果容器的基础映像包含指定的数据装入点,现有的数据复制到在卷初始化新卷。
数据卷可以共享和容器之间重复使用。
改变数据卷将立刻生效(在所有挂载该容器中)
改变数据卷数据不会影响到容器。
即使容器本身被删除。但是数据卷依然存在。
数据卷的目的是持久化数据,独立于容器的生命周期。Docker因此不会自动删除卷,当你删除一个容器,也不会“垃圾回收”直到没有容器再使用。
添加一个数据卷
你可以在docker run时加上-v参数来添加一个数据卷,-v参数也可以使用多次,以挂载多个数据卷。
$ docker run -d -P --name web -v /webapp training/webapp python app.py
这条命令将在容器中的/webapp文件夹创建一个数据卷存储数据。
你也可以在构建镜像时在Dockerfile里面定义。
数据卷默认的权限时读写,你也可以定义成只读。
$ docker run -d -P --name web -v /opt/webapp:ro training/webapp python app.py
查找数据卷路径用docker inspect命令定位
$ docker inspect web
我们可以看到保存在主机上数据卷的路径:
...
Mounts": [
{
"Name": "fac362...80535",
"Source": "/var/lib/docker/volumes/fac362...80535/_data",
"Destination": "/webapp",
"Driver": "local",
"Mode": "",
"RW": true
}
]
... 并切看到权限RW是ture
挂载一个主机目录作为数据卷
挂载主机目录为数据卷,必须参照 -v hostPATH:containerPATH 这种格式 路径必须为绝对路径,以保证容器的 可移植性。
$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
上面的命令加载主机的 /src/webapp 目录到容器的 /opt/webapp 目录
docker数据卷的权限是读写,你也可以指定只读:
$ docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py
挂载一个数据文件作为数据卷
-v 标记也可以从主机挂载单个文件到容器中
$ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
这样就可以记录在容器输入过的命令了。
如果直接挂载一个文件,很多文件编辑工具,包括 vi 或者 sed --in-place,可能会造成文件 inode 的改变,从 Docker 1.1 .0起,这会导致报错误信息。所以最简单的办法就直接挂载文件的父目录。
创建和挂载数据卷容器
如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。
数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。
首先,创建一个命名的数据卷容器 dbdata:
$ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
然后,在其他容器中使用 --volumes-from 来挂载 dbdata 容器中的数据卷。
$ sudo docker run -d --volumes-from dbdata --name db1 training/postgres
$ sudo docker run -d --volumes-from dbdata --name db2 training/postgres
还可以使用多个 --volumes-from 参数来从多个容器挂载多个数据卷。 也可以从其他已经挂载了数据卷的容器来挂载数据卷。
$ sudo docker run -d --name db3 --volumes-from db1 training/postgres
*注意:使用 --volumes-from 参数所挂载数据卷的容器自己并不需要保持在运行状态。
如果删除了挂载的容器(包括 dbdata、db1 和 db2),数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用 docker rm -v 命令来指定同时删除关联的容器。 这可以让用户在容器之间升级和移动数据卷。
备份、存储、移动数据卷
另一个非常有用大功能是利用数据卷容器进行备份、存储以及迁移操作。
备份
$ docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
然后新创建一个新的容器
$ docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
然后解压数据卷挂载到容器
$ docker run --volumes-from dbdata2 -v $(pwd):/backup ubuntu cd /dbdata && tar xvf /backup/backup.tar