前面已经介绍了许多基础的知识,如今咱们来一块儿学习如何管理Docker容器里面以及容器之间的数据python
先介绍两种原始的方法来管理Docker中的应用:web
data volumns
是专门设计的工具,它绕过了UFS直接工做于一个或多个容器。它为数据持久和分享提供了许多功能:docker
数据卷的设计被用来持久化数据,让数据可以独立于容器的生命周期。所以当删除容器时Docker也不会自动删除数据卷。shell
增长数据卷ubuntu
docker create -v
和docker run -v
中的-v标记来给容器添加数据卷,咱们能够在一条命令中屡次使用-v
标记来添加多个数据卷,下面的例子挂载了一个数据卷在咱们的web应用容器中。windows
languagedocker run -d -P --name web -v /webapp training/webapp python app.py
这条命令执行后会在容器中建立一个新的卷webapp
bash
为数据卷挂在主机目录app
除了使用-v标记来建立卷以外,你还能够挂载Docker守护进程主机的目录到容器中。webapp
注意:若是你使用Boot2Docker,那么你的Docker守护进程只能被限制访问OSX/windows特定的文件目录。Boot2Docker会努力自动分享OSX中的
/users
目录和windows中的C:users
目录。所以你能够经过docker run -v /Users/<path>:/<container path>
... (OSX)或者docker run -v /c/Users/<path>:/<container path ...
(Windows).来挂在文件或目录。全部的其它路径(不是/users和C:users)都来自Boot2Docker虚拟机中的文件系统。工具
languagedocker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
上述命令会把主机的/src/webapp
目录挂在到容器中的/opt/webapp
下
注意:若是
/opt/webapp
目录已经存在与容器的镜像中,那么/opt/webapp
中的内容会被主机上的/src/webapp
中的数据替换,这个和mount命令是一致的。
数据卷挂在数据对测试很是有用,好比咱们能够把源代码挂在到容器中,而后修改代码看看应用会发生什么。主机上的目录必须是绝对路径,若是这个目录不存在Docker会自动去建立1个。
注意:不能在
Dockerfile
中来配置挂载目录,由于Dockerfile
的目的是更方便的来一直和分享镜像,而主机目录依赖于主机,(对于一个目录,在不一样的主机上可能绝对路径不一致)因此Dockerfile中目录挂载不会适用于全部的主机
挂载的数据卷默认是可读写的,固然咱们能够经过命令标记来让它只读
languagedocker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py
上述命令中咱们经过ro
选项来让数据卷只读
挂载主机文件做为数据卷
-v
标记还能够用来挂在来自主机的文件,而不单单是目录
languagedocker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
上述命令会带你到一个新容器的shell界面,你会有来自主机的bash历史。由于容器和主机共享了一个.bash_history
文件,因此你在容器中的命令历史和主机中的历史都会记录到.bash_history
中,这样当你退出容器中时,你在容器中的命令历史被保存下来了,在主机的shell历史记录中仍然可以看到容器中的历史。
注意:人们会使用不少工具来编辑文件,
vi
,sed --in-place
,这些都会致使文件的索引节点改变。Docker 1.1.0以前,文件修改会报如sed: cannot rename ./sedKdJ9Dy: Device or resource busy
这样的错误。可是在Docker 1.1.0以后,挂载文件让文件修改变得很是简单而不须要再去挂在包含这个文件的父目录了。
建立一个专门防数据的数据卷容器
若是你有一些持久化的数据须要在容器之间共享,或者想从非持久化容器使用持久化数据。最好的办法是建立名为Data
的卷容器,把数据都挂在到Data容器里
咱们建立一个能分享数据的命名容器,他不运行任何应用,它重复使用training/postgres
镜像以便全部的容器使用同一个层,这样能够节省磁盘空间。
languagedocker create -v /dbdata --name dbdata training/postgres /bin/true
咱们使用--volumes-from
标记来绑定/dbdata
卷到另外一个容器
languagedocker run -d --volumes-from dbdata --name db1 training/postgres
或者
languagedocker run -d --volumes-from dbdata --name db2 training/postgres
在是上述的例子中,咱们在容器中挂在了/dbdata
卷,若是恰巧镜像training/postgres
中也有/dbdata
这个目录,那么容器会隐藏镜像的目录,而让容器中的/dbdata目录可见,新建多个数据容器一样是隐藏镜像的文件而显示容器中的文件,这种机制实现了数据卷的数据共享。
你能够在一条命令中使用多个--volumes-from
标记参数把多个容器的数据卷绑定在一块儿。
上述的代码中db1和db2是挂载dbdata这个容器来扩展的,你也能够挂载db1或者db2来扩展你的数据卷。
languagedocker run -d --name db3 --volumes-from db1 training/postgres
若是你想删除包含挂载数据卷的容器,甚至是初始化的容器dbdata
,或者是由dbdata
扩展的db1和db2,容器会删除,可是数据卷会留下。使用docker rm -v
来删除容器的数据卷。
注意:当你删除容器没有使用
-v
标记的时候,Docker不会提示警告。没有使用-v
标记删除容器,会让残留的volumns
变得“无家可归”(就是没有容器再引用这个数据卷)。这样的卷很难删除并且会占用不少空间,咱们正在努力改善数据卷的管理,你能够经过pull request #8484
来跟进咱们的进程。
咱们能够利用数据卷来有效的备份、恢复和迁移数据
languagedocker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
命令中咱们启动了一个新的容器,它共享了来自dbdata
容器的数据卷。而后咱们挂在了一个本地主机的目录/backup
。最后咱们使用tar
命令把/dbdata
中的数据压缩成dbdata.jar
放到/backup
中。执行结束咱们就完成了数据卷的数据备份工做。
数据恢复
languagedocker run -v /dbdata --name dbdata2 ubuntu /bin/bash docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
建立一个新的容器dbdata2
,解压文件到新的容器的数据卷。