您的位置:首页 > 运维架构 > Docker

docker入门实践之数据卷管理

2017-12-12 23:20 609 查看
在实际使用docker过程中,有时需要查看容器内应用产生的数据,或需要把容器内的数据进行备份,甚至是多个容器间需要共享数据,这势必涉及到数据管理,那么docker的数据怎么管理呢?

容器中数据管理主要有以下两种方式:1.数据卷(data volumes) ;2.数据卷容器(data volumes containers);

一、 数据卷

数据卷是一个可提供容器使用的特殊目录,它绕过文件系统(UFS),可以提供很多有用的特性:

1.数据卷可以在容器间共享和重用;

2.对数据卷的修改会立马生效;

3.对数据卷的更新不会影响到镜像;

4.数据卷一直存在,直到容器没有使用;

5.完全独立于容器的生存周期,因此不会在删除容器时删除其挂在的数据卷。

提示:docker数据卷的使用,类似Linux系统下对目录或文件进行mount操作。

1.1 如何在容器内创建数据卷
在使用docker run命令创建并启动容器时。通过-v选项可以在容器内创建一个数据卷,如果想要创建多个数据卷只需要多次使用-v即可。
例如下面使用centos:latest镜像创建一个名为web容器,并创建一个数据卷挂载到容器的/data 目录下

[root@srv-xjwy-dns-node01 ~]# docker run -itd --name web -v /data centos:latest
4fa33359e280ee16fd375c7165858bfea81dd0971659c3585699636101224bc0
[root@srv-xjwy-dns-node01 ~]# docker exec -it 4fa33359e280 ls -dl /data
drwxr-xr-x 2 root root 6 Dec 12 15:01 /data

1.2 如何挂载宿主主机目录作为容器的数据卷
同样也可以通过-v选项挂载容器宿主主机目录作为容器的数据卷,格式:docker run -v 容器宿主主机目录路径:容器内数据卷路径,如果容器内没有该数据卷,则会自动创建该数据卷,注意中间用“:”隔开,如下所示,将本地的/data/目录挂在到容器作为数据卷:

[root@srv-xjwy-dns-node01 www]# ls /data/www/
test.txt
[root@srv-xjwy-dns-node01 www]# docker run -itd --name test -v /data/www:/data centos:latest
bf4aaf1b6a050ee1eb60b889d3e68c04a0f30a5423aade99a4b228918170d63b
[root@srv-xjwy-dns-node01 www]# docker exec -it test ls /data/
test.txt

发现成功的将容器宿主主机的/data/www目录挂在到名为test容器里作为数据卷,路径为:/data,并且test.txt文件也在该容器/data/目录下;

注:/data/www为宿主机目录,/data是容器中目录,若/data目录不存在容器会自动创建,另外宿主主机的目录路径必须是绝对路径;

默认容器对挂在的数据卷权限为可读可写(rw),也可以通过ro指定数据卷为可读权限,如下所示:

[root@srv-xjwy-dns-node01 www]# docker run -itd --name prod -v /data/www:/data:ro centos:latest
[root@srv-xjwy-dns-node01 www]# docker exec -it prod touch /data/1.txt
touch: cannot touch '/data/1.txt': Read-only file system

这样在容器内就不能修改数据卷内容,只能在宿主主机上修改,这时在宿主主机对应的目录下创建一个文件,发现容器实时同步过来了:

root@srv-xjwy-dns-node01 www]# touch prod.txt
[root@srv-xjwy-dns-node01 www]# docker exec -it prod ls -l /data/
total 0
-rw-r--r-- 1 root root 0 Dec 12 15:42 prod.txt
-rw-r--r-- 1 root root 0 Dec 12 15:13 test.txt

说明当设置容器的数据卷权限为可读(ro)时,只能在容器的宿主主机相对应的目录进行文件目录的增删改查操作,而不能在容器数据卷内操作,用docker inspect prod查看,仔细观察发现, 结果如下:

[root@srv-xjwy-dns-node01 www]# docker inspect prod
"Mounts": [
{
"Type": "bind",
"Source": "/data/www",
"Destination": "/data",
"Mode": "ro",
"RW": false,
"Propagation": "rprivate"
}

发现此时容器数据卷是可读模式,即不能在容器内修改该数据卷里的内容

1.3 如何挂载宿主主机文件作为容器的数据卷
-v也可以将容器宿主主机本地单个文件挂载到容器作为数据卷使用,如下:

docker run -rm -it --name prod -v /data/www/test.txt:/data/test.txt centos:latest /bin/bash

注意:如果挂载一个文件到容器,使用编辑工具时,可能会造成文件inode改变,导致容器报错,所以最佳推介方式是挂在文件所在的目录。

温馨提示:

Clean up (--rm)
默认情况下,每个容器在退出时,它的文件系统也会保存下来,这样一方面调试会方便些,因为你可以通过查看日志等方式来确定最终状态。另外一方面,你也可以保存容器所产生的数据。但是当你仅仅需要短暂的运行一个容器,并且这些数据不需要保存,你可能就希望Docker能在容器结束时自动清理其所产生的数据。这个时候你就需要--rm这个参数了。 注意:--rm 和 -d不能共用!

二、 数据卷容器

在有些情况下容器之间需要共享一些持续更新的数据,这时最简单的方式就是利用数据卷容器来实现,数据卷容器就是一个普通的容器,只不过用它提供的数据卷供其他容器挂载而已。
如下,创建一个数据卷容器data,并在其中创建一个数据卷/datas:

root@srv-xjwy-dns-node01 ~]# docker run  -it --name data -v /datas centos:latest
[root@a92af8ad138f /]# ll /data/
total 0

然后使用--volumes-from选项挂载data容器中/datas数据卷,例如下面创建两个容器:app1,app2,并从datas容器挂载数据卷:

[root@srv-xjwy-dns-node01 ~]# docker run  -it --volumes-from data --name app1  centos:latest
[root@srv-xjwy-dns-node01 ~]# docker run  -it --volumes-from data --name app2  centos:latest
[root@srv-xjwy-dns-node01 ~]# docker exec app1 ls /datas/
test.txt   text2.txt
[root@srv-xjwy-dns-node01 ~]# docker exec app2 ls /datas/
test.txt   text2.txt

分别进入app1、app2容器中,会有一个/datas目录,在app1里的/datas目录创建文件,app2也能看的到,另外使用--volumes-from时,后面的值是数据卷容器的名称而不是数据卷容器中数据卷。

注意:
1.如果删除data、app1、app2,时,数据卷并不会被自动删除。如果想删除,必须删除最后一个挂载着它的容器,使用docker rm -v 命令来指定删除关联的容器;

2.使用--volumes-from参数挂载的数据卷容器自身并不需要保持在运行状态。

3.使用数据卷容器会降低I/O读写性能;

4.可以多次使用--volumes-from参数挂载多个容器中的数据卷,也可以从已经挂载了容器卷的容器挂载数据卷;

三、 利用数据卷进行数据迁移

在实际应用中,可以利用数据卷容器对其中的数据卷做数据备份。数据恢复以实现数据迁移;
3.1 数据卷数据备份
如下将data数据卷容器中/datas数据卷进行数据备份:

[root@srv-xjwy-dns-node01 ~]#  docker run -it --volumes-from data -v /data/apps/bak:/backup --name backup centos:latest tar cvf /backup/backup.tar /datas
tar: Removing leading `/' from member names
/datas/
/datas/test.txt
[root@srv-xjwy-dns-node01 ~]# cd /data/apps/bak/
[root@srv-xjwy-dns-node01 bak]# ls
backup.tar

上面先是创建了一个backup容器,并使用--volumes-form将容器data下的datas数据卷挂载到自己的文件系统中,然后使用-v参数将宿主主机的/data/apps/bak挂载到容器backup作为数据卷,最后通过tar 方式将/datas目录下数据备份到宿主主机/data/apps/bak下。

3.2 数据卷数据恢复
同样我们如果要恢复数据到一个容器中,可以这样做,如下所示:
删除data容器下/datas目录下的数据:

root@srv-xjwy-dns-node01 bak]# docker exec data ls /datas/
test.txt
[root@srv-xjwy-dns-node01 bak]# docker exec data rm  -rf /datas/test.txt
[root@srv-xjwy-dns-node01 bak]# docker exec data ls /datas/

然后创建一个容器recover,通过--volumes-form参数将data容器下的/datas目录挂载,再通过-v选项将宿主主机的/data/apps/bak挂载,通过tar xvf命令将备份文件恢复到/datas下即可:

[root@srv-xjwy-dns-node01 ~]# docker run -it --volumes-from data -v /data/apps/bak:/backup --name recover centos:latest tar xvf /backup/backup.tar -C /datas/
datas/
datas/test.txt
[root@srv-xjwy-dns-node01 ~]# docker exec data ls /datas/datas/
test.txt

如上,备份的数据成功的恢复到data数据卷容器中,在实际操作过程中也可以登录容器手动将指定的备份文件恢复到数据卷容器中。

总结:在生产环境中,数据卷或数据卷容器是一种很好的容器间数据共享的解决方案,除此之外应定期将本地主机数据进行备份,或使用容错存储系统(RAID或分布式文件系统),需要注意的是-v的用法,当仅仅需要创建数据卷时,直接使用-v 数据卷名即可,当挂载本地宿主主机目录时,中间需要用“:”分开,若容器数据卷目录不存在会自动创建!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  docker 数据卷