首页 > 代码库 > Docker 数据管理
Docker 数据管理
Docker 中的数据管理主要有 2 个方法,数据卷和数据卷容器
数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改会立马生效
- 对数据卷的更新,不会影响镜像
- 卷会一直存在,直到没有容器使用
数据卷的使用,类似于 Linux 下对目录或文件进行 mount。
创建数据卷
在用 「docker run」 命令的时候,使用 -v 标记来创建一个数据卷并挂载到容器里。在一次 run 中多次使用可以挂载多个数据卷。
core@localhost ~ $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5883b400a03e base/163:latest "/usr/bin/supervisor 44 minutes ago Up 44 minutes 22/tcp agitated_heisenberg
9cb2e45814e0 4b32789c7d66 "/run.sh" 23 hours ago Up 23 hours 0.0.0.0:3306->3306/tcp, 0.0.0.0:8080->80/tcp loving_feynman
e3c136d76b44 tutum/tomcat:8.0 "/run.sh" 25 hours ago Up 25 hours 0.0.0.0:80->8080/tcp tomcat001
fe9e65aaf58c dl.dockerpool.com:5000/mysql:5.7 "/entrypoint.sh mysq 25 hours ago Up 25 hours 3306/tcp db001
core@localhost ~ $ docker stop tomcat001
tomcat001
core@localhost ~ $ docker rm tomcat001
tomcat001
core@localhost ~ $ mkdir app
core@localhost ~ $ docker run -v /home/core/app/:/opt/data -p 80:8080 -d --name tomcat001 tutum/tomcat
49dcdeb7752cd5966fa5940e52f40c11d866ab4bce67ab6a67931e62f1b75a3e
#映射宿主主机的本地目录 /home/core/app/ 到容器的 /opt/data目录
在前面的章节中,我们创建的 tomcat001 容器没有部署自己的程序,上面的操作使用 -v 参数重新创建了tomcat001 容器,这样用户就可以通过将java程序放到 /home/orceos/app 目录底下来部署程序了。
挂载一个主机目录作为数据卷
这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。本地目录的路径必须是绝对路径,如果目录不存在 Docker 会自动为你创建它。
注意:Dockerfile 中不支持这种用法,这是因为 Dockerfile 是为了移植和分享用的。而且,不同操作系统的路径格式不一样,所以目前还不能支持。
Docker 挂载数据卷的默认权限是读写,用户也可以通过 :ro 指定为只读。
core@localhost ~ $ docker run -v /home/core/app/:/opt/data:ro -p 80:8080 -d --name tomcat001
加了 :ro 之后,就挂载为只读了。
挂载一个宿主主机文件作为数据卷
-v 标记也可以从主机挂载单个文件到容器中
core@localhost ~ $ docker run -it -v ~/.bash_history:/.bash_history ubuntu:14.04 /bin/bash
root@7871e2fe1bf6:/# exit
#这样就可以记录在容器输入过的命令了。
注意:如果直接挂载一个文件,很多文件编辑工具,包括 vi 或者 sed --in-place,可能会造成文件 inode 的改变,从 Docker 1.1 .0起,这会导致报错误信息。所以最简单的办法就直接挂载文件的父目录。
数据卷容器
如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。
数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。下面以我们之前介绍过的 lamp 镜像为例子来介绍下数据卷容器的应用:
使用数据卷容器部署静态 web 数据集群服务
core@localhost ~ $ docker run -d -v /app --name webdata tutum/lamp echo data_only for web cluster
#创建一个数据卷容器,使用「echo data_only for web cluster」说明该容器的作用
e2594b4215f4dea5ec63adbeaaff7de9a953744ad9c229cb14239177b6c6ec32
core@localhost ~ $ docker ps
#可以看到该容器并没有运行
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
49dcdeb7752c tutum/tomcat:latest "/run.sh" About an hour ago Up About an hour 0.0.0.0:80->8080/tcp tomcat001
5883b400a03e base/163:latest "/usr/bin/supervisor 2 hours ago Up 2 hours 22/tcp agitated_heisenberg
9cb2e45814e0 tutum/lamp:latest "/run.sh" 25 hours ago Up 25 hours 0.0.0.0:3306->3306/tcp, 0.0.0.0:8080->80/tcp loving_feynman
fe9e65aaf58c dl.dockerpool.com:5000/mysql:5.7 "/entrypoint.sh mysq 27 hours ago Up 27 hours 3306/tcp db001
core@localhost ~ $ docker ps -a
#但是可以从历史记录里看到,还可以看到我们的注释「echo data_only for web cluster」
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e2594b4215f4 tutum/lamp:latest "echo data_only for 30 seconds ago Exited (0) 30 seconds ago webdata
c99dab4cfcb1 dl.dockerpool.com:5000/ubuntu:14.04 ": /bin/bash" 16 minutes ago elegant_hawking
49dcdeb7752c tutum/tomcat:latest "/run.sh" About an hour ago Up About an hour 0.0.0.0:80->8080/tcp tomcat001
5883b400a03e base/163:latest "/usr/bin/supervisor 2 hours ago Up 2 hours 22/tcp agitated_heisenberg
9cb2e45814e0 tutum/lamp:latest "/run.sh" 25 hours ago Up 25 hours 0.0.0.0:3306->3306/tcp, 0.0.0.0:8080->80/tcp loving_feynman
fe9e65aaf58c dl.dockerpool.com:5000/mysql:5.7 "/entrypoint.sh mysq 27 hours ago Up 27 hours 3306/tcp db001
core@localhost ~ $ docker run -d --name web1 --volumes-from webdata tutum/lamp
#新建一个 web1 容器,并从 webdata 这个刚才我们创建的容器加载数据卷
5d1aeac356319f2d0936cb54c2514b6d5f6f46a35670b86812ff32a67548fee0
core@localhost ~ $ docker run -d --name web2 --volumes-from webdata tutum/lamp
#新建一个 web2 容器,并从 webdata 这个刚才我们创建的容器加载数据卷
35dc406f87439f6ee8e8086aa25d87da212de68d3a205c0b7474feae30c938c6
core@localhost ~ $ docker ps
#如果程序没问题的话,那么一个以 /app 目录为内容的 web 集群就完成了,在前面加上就负载均衡器就可以提供对外服务了。(这里假设 /app 的程序为静态不带数据库的 web 服务,数据库在 docker 中的集群,将在后续章节详细介绍)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
35dc406f8743 tutum/lamp:latest "/run.sh" 2 seconds ago Up 2 seconds 3306/tcp, 80/tcp web2
5d1aeac35631 tutum/lamp:latest "/run.sh" 9 seconds ago Up 8 seconds 3306/tcp, 80/tcp web1
49dcdeb7752c tutum/tomcat:latest "/run.sh" About an hour ago Up About an hour 0.0.0.0:80->8080/tcp tomcat001
5883b400a03e base/163:latest "/usr/bin/supervisor 2 hours ago Up 2 hours 22/tcp agitated_heisenberg
9cb2e45814e0 tutum/lamp:latest "/run.sh" 25 hours ago Up 25 hours 0.0.0.0:3306->3306/tcp, 0.0.0.0:8080->80/tcp loving_feynman
fe9e65aaf58c dl.dockerpool.com:5000/mysql:5.7 "/entrypoint.sh mysq 27 hours ago Up 27 hours 3306/tcp db001
注意:使用 --volumes-from 参数所挂载数据卷的容器自己并不需要保持在运行状态。如果删除了挂载的容器(包括 webdata、web1 和 web2),数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用 docker rm -v 命令来指定同时删除关联的容器。 这可以让用户在容器之间升级和移动数据卷。具体的操作将在下一节中进行讲解。
备份、恢复、迁移 docker 中的数据
利用数据卷对容器中的数据进行备份、恢复、迁移
这里我们假设一个场景,有一个数据卷容器,名字叫做 testdata,我们在一个叫 testweb1 的容器中加载它,并创建一个测试文件叫做 testfile ,在宿主主机使用备份命令来备份这个数据卷
备份
core@localhost ~ $ docker run -d -v /test --name testdata ubuntu:14.04 echo data_only for test
fb8bdbca0318c801fdd432cfc7eff2055534782e8172bd25463305d354aadc9d
#创建数据卷容器
core@localhost ~ $ docker run -d --name testweb1 --volumes-from testdata -P base/163 /usr/bin/supervisord
45967e30433963add61012647c182b3b65820e55f5b49ad16bb63f5ef7b6db7b
#从 testweb1 挂载数据卷
core@localhost ~ $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
45967e304339 base/163:latest "/usr/bin/supervisor 3 seconds ago Up 3 seconds 0.0.0.0:49155->22/tcp testweb1
core@localhost ~ $ ssh root@127.0.0.1 -p 49155
The authenticity of host ‘[127.0.0.1]:49155 ([127.0.0.1]:49155)‘ can‘t be established.
ED25519 key fingerprint is 6c:03:15:1b:34:a9:df:36:46:03:9f:e8:cf:34:ec:60.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ‘[127.0.0.1]:49155‘ (ED25519) to the list of known hosts.
Welcome to Ubuntu 14.04 LTS (GNU/Linux 3.2.0-58-generic x86_64)
* Documentation: https://help.ubuntu.com/
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
root@45967e304339:~# cd /
root@45967e304339:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys test tmp usr var
root@45967e304339:/# cd test/
root@45967e304339:/test# touch testfile
#创建测试文件
root@45967e304339:/test# exit
logout
Connection to 127.0.0.1 closed.
core@localhost ~ $ docker run --volumes-from testdata -v $(pwd):/backup ubuntu:14.04 tar cvf /backup/backup.tar /test
tar: Removing leading `/‘ from member names
/test/
/test/testfile
#在宿主主机备份数据卷
core@localhost ~ $ ls
app backup.tar base php test ubuntu14.04.tar
core@localhost ~ $ sudo tar xvf backup.tar
#验证恢复数据卷内容
test/
test/testfile
恢复和迁移数据
localhost opt # ls
#我们将刚才备份的文件复制到另外一台宿主主机
bakcup.tar
localhost opt # tar xvf bakcup.tar
#解压
test/
test/testfile
localhost opt # docker run --name testweb2 -v /opt/test:/test -ti ubuntu:14.04 /bin/bash
root@f315f027671b:/# cd /
root@f315f027671b:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys test tmp usr var
root@f315f027671b:/# cd test/
root@f315f027671b:/test# ls
testfile
迁移完成
这里举的例子是在不同的宿主主机之间迁移数据,在同一宿主主机恢复步骤和上述步骤类似
更多内容请关注 http://www.dockerpool.com
Docker 数据管理