Docker中可以使用Named volume和data container来进行数据的管理。
单一Container的使用Helloworld
Step 1:创建一个Named Volume
事前确认volume的信息,没有VOLUME存在
1
2
3
|
[root@host88 volumes] # docker volume ls
DRIVER VOLUME NAME
[root@host88 volumes] #
|
确认/var/lib/docker/volumes的状况
1
2
3
4
5
|
[root@host88 volumes] # pwd
/var/lib/docker/volumes
[root@host88 volumes] # ll
total 0
[root@host88 volumes] #
|
创建一个名为volname的数据卷,通过-v参数可以进行创建,同时也可以通过docker volume create来创建。
1
2
3
4
5
|
[root@host88 volumes] # docker run -it -v volname:/volumedata/dbdata debian
root@b2e3523a6dd9:/ # cd volumedata/dbdata
root@b2e3523a6dd9: /volumedata/dbdata # ls -l
total 0
root@b2e3523a6dd9: /volumedata/dbdata #
|
在Container外部确认此事volname是否已经创建成功
1
2
3
4
|
[root@host88 volumes] # docker volume ls
DRIVER VOLUME NAME
local volname
[root@host88 volumes] #
|
确认/var/lib/docker/volumes下面 的情况
1
2
3
4
5
6
7
8
9
10
11
|
[root@host88 volumes] # pwd
/var/lib/docker/volumes
[root@host88 volumes] # ll
total 0
drwxr-xr-x 3 root root 18 Jul 25 06:23 volname
[root@host88 volumes] # find . -type f
[root@host88 volumes] # find . -type d
.
. /volname
. /volname/_data
[root@host88 volumes] #
|
除了目录结构没有任何文件存在
Step 2:在Container中保存数据Hello world
1
2
3
4
5
6
7
8
9
|
root@b2e3523a6dd9: /volumedata/dbdata # ls -l
total 0
root@b2e3523a6dd9: /volumedata/dbdata # echo "hello, world" >>helloworld
root@b2e3523a6dd9: /volumedata/dbdata # cat helloworld
hello, world
root@b2e3523a6dd9: /volumedata/dbdata # ls -l
total 4
-rw-r--r-- 1 root root 13 Jul 25 06:26 helloworld
root@b2e3523a6dd9: /volumedata/dbdata #
|
在外部确认该信息是否已经存在
1
2
3
4
5
6
7
|
[root@host88 volumes] # pwd
/var/lib/docker/volumes
[root@host88 volumes] # find . -type f
. /volname/_data/helloworld
[root@host88 volumes] # cat ./volname/_data/helloworld
hello, world
[root@host88 volumes] #
|
Step 3:在外部直接修改该文件
1
2
3
4
5
6
7
8
9
10
11
|
[root@host88 volumes] # pwd
/var/lib/docker/volumes
[root@host88 volumes] # find . -type f
. /volname/_data/helloworld
[root@host88 volumes] # cat ./volname/_data/helloworld
hello, world
[root@host88 volumes] # echo "hell, this is `hostname`" >>./volname/_data/helloworld
[root@host88 volumes] # cat ./volname/_data/helloworld
hello, world
hell, this is host88
[root@host88 volumes] #
|
在内部确认信息
1
2
3
4
5
6
7
|
root@b2e3523a6dd9: /volumedata/dbdata # ls -l
total 4
-rw-r--r-- 1 root root 34 Jul 25 06:29 helloworld
root@b2e3523a6dd9: /volumedata/dbdata # cat helloworld
hello, world
hell, this is host88
root@b2e3523a6dd9: /volumedata/dbdata #
|
从Container中退出前再追加一条信息
1
2
3
4
5
6
|
root@b2e3523a6dd9: /volumedata/dbdata # echo "hello, I will exit from `hostname`" >>helloworld
root@b2e3523a6dd9: /volumedata/dbdata # cat helloworld
hello, world
hell, this is host88
hello, I will exit from b2e3523a6dd9
root@b2e3523a6dd9: /volumedata/dbdata #
|
Step 4:退出Container后看数据是否仍然存在
1
2
3
4
5
6
7
8
9
|
root@b2e3523a6dd9: /volumedata/dbdata # exit
exit
[root@host88 volumes] # find . -type f
. /volname/_data/helloworld
[root@host88 volumes] # cat ./volname/_data/helloworld
hello, world
hell, this is host88
hello, I will exit from b2e3523a6dd9
[root@host88 volumes] #
|
数据仍然存在。使用docker volume ls可以看到刚刚volname的数据卷也依然存在。
1
2
3
4
|
[root@host88 volumes] # docker volume ls
DRIVER VOLUME NAME
local volname
[root@host88 volumes] #
|
数据卷的管理
docker的volume的管理目前主要有下面4种:create/ls/inspect/rm
查询(ls)
1
2
3
4
|
[root@host88 volumes] # docker volume ls
DRIVER VOLUME NAME
local volname
[root@host88 volumes] #
|
正常的环境一定不会跑出这么清静的结果。
inspect
1
2
3
4
5
6
7
8
9
|
[root@host88 volumes] # docker volume inspect volname
[
{
"Name" : "volname" ,
"Driver" : "local" ,
"Mountpoint" : "/var/lib/docker/volumes/volname/_data"
}
]
[root@host88 volumes] #
|
其实这个信息可能会觉得非常眼熟,看完docker insepect 的结果就会发现,内容是一致的,以下是docker inspect b2e3523a6dd9的mounts相关信息
1
2
3
4
5
6
7
8
9
10
11
|
"Mounts" : [
{
"Name" : "volname" ,
"Source" : "/var/lib/docker/volumes/volname/_data" ,
"Destination" : "/volumedata/dbdata" ,
"Driver" : "local" ,
"Mode" : "z" ,
"RW" : true ,
"Propagation" : "rslave"
}
],
|
删除(rm)
删除之前的确认
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@host88 volumes] # pwd
/var/lib/docker/volumes
[root@host88 volumes] # find . -type f
. /volname/_data/helloworld
[root@host88 volumes] # cat ./volname/_data/helloworld
hello, world
hell, this is host88
hello, I will exit from b2e3523a6dd9
[root@host88 volumes] # docker volume ls
DRIVER VOLUME NAME
local volname
[root@host88 volumes] #
|
删除volume之前需要删除与其有依赖关系的container
1
2
3
|
[root@host88 volumes] # docker rm b2e3523a6dd9
b2e3523a6dd9
[root@host88 volumes] #
|
删除container并不会将volume一并删除
1
2
3
4
5
|
[root@host88 volumes] # pwd
/var/lib/docker/volumes
[root@host88 volumes] # find . -type f
. /volname/_data/helloworld
[root@host88 volumes] #
|
而使用docker volume rm则会干净地删除掉所有信息
1
2
3
4
5
6
7
|
[root@host88 volumes] # docker volume rm volname
volname
[root@host88 volumes] # ll
total 0
[root@host88 volumes] # docker volume ls
DRIVER VOLUME NAME
[root@host88 volumes] #
|
长时间运行的Docker环境中,成为僵尸的不只是/var/lib/docker/volumes下面的实际数据
而且docker volume ls中也会有很多完全不知道的信息,甚至有些相关联的实际数据已经被删除
这种情况在很多考虑不足的环境中屡见不鲜,虽然只是很简单的helloworld
数据管理时候需要考虑的问题还是值得引起足够的重视。
创建(create):
可以像例子那样通过run 和-v创建volume,同时也可以使用docker volume create来创建
1
2
3
4
5
6
|
[root@host88 volumes] # docker volume create --driver=local --name=volname
volname
[root@host88 volumes] # docker volume ls
DRIVER VOLUME NAME
local volname
[root@host88 volumes] #
|
有些volume在创建时还要结合使用–opt参数(或者-o)
如果不指定–name参数,docker会体贴地替你取一个,大概就像下面这样
1
2
3
4
5
6
7
8
9
10
|
[root@host88 volumes] # docker volume ls
DRIVER VOLUME NAME
local volname
[root@host88 volumes] # docker volume create
e54a0022fdff1e0e57b8635317e0b51b1e36c3c9b8c48a051e7778a45f08a83d
[root@host88 volumes] # docker volume ls
DRIVER VOLUME NAME
local volname
local e54a0022fdff1e0e57b8635317e0b51b1e36c3c9b8c48a051e7778a45f08a83d
[root@host88 volumes] #
|
看着太闹心了,一下全部删掉吧。
1
2
3
4
|
[root@host88 volumes] # docker volume rm $(docker volume ls -q)
volname
e54a0022fdff1e0e57b8635317e0b51b1e36c3c9b8c48a051e7778a45f08a83d
[root@host88 volumes] #
|
需要注意的是这个名字必须是唯一的,所以前面也说到过不使用docker volume rm来删除的话会导致问题,
下次用同样名字想要创建一个volume却发现已经存在的时候就只能是创建失败了。
多Container共用一个数据卷
Step 1:创建一个Named Volume
用你喜欢的方式创建一个named volume
1
2
3
4
5
6
|
[root@host88 volumes] # docker volume create --name=volname
volname
[root@host88 volumes] # docker volume ls
DRIVER VOLUME NAME
local volname
[root@host88 volumes] #
|
Step 2:路人甲Container与之相连
1
2
|
[root@host88 volumes] # docker run -it -v volname:/volumedata/dbdata debian
root@5a43b6347b53:/ #
|
路人甲使用Debian,他想知道谁是docker的主机
1
2
3
4
5
6
7
8
9
|
root@5a43b6347b53:/ # ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var volumedata
root@5a43b6347b53:/ # cd volumedata/dbdata
root@5a43b6347b53: /volumedata/dbdata # ls -l
total 0
root@5a43b6347b53: /volumedata/dbdata # echo "hello, world by `hostname`, who is host?" >> helloworld
root@5a43b6347b53: /volumedata/dbdata # cat helloworld
hello, world by 5a43b6347b53, who is host?
root@5a43b6347b53: /volumedata/dbdata #
|
Step 3:主机与路人乙
主机此时看到了这个信息
1
2
3
4
5
6
7
|
[root@host88 volumes] # pwd
/var/lib/docker/volumes
[root@host88 volumes] # find . -type f
. /volname/_data/helloworld
[root@host88 volumes] # cat ./volname/_data/helloworld
hello, world by 5a43b6347b53, who is host?
[root@host88 volumes] #
|
同时路人乙也与该volume进行了连接
1
2
|
[root@host88 ~] # docker run -it -v volname:/volumedata/dbdata centos
[root@6365668cea55 /] #
|
BTW,Docker现在不能使用相对路径,所以volname:/volumedata/dbdata的这个写法最前面的/仍然是不可或缺.
路人乙说虽然你不是找我,但是我看见了,这是共享的,我就可以回信么,说我不知道。
1
2
3
4
5
6
7
8
9
10
|
[root@6365668cea55 dbdata] # ls -l
total 4
-rw-r--r-- 1 root root 43 Jul 25 09:36 helloworld
[root@6365668cea55 dbdata] # cat helloworld
hello, world by 5a43b6347b53, who is host?
[root@6365668cea55 dbdata] # echo "hello, world by `hostname`, I do not know" >> helloworld
[root@6365668cea55 dbdata] # cat helloworld
hello, world by 5a43b6347b53, who is host?
hello, world by 6365668cea55, I do not know
[root@6365668cea55 dbdata] #
|
Step 4:主机与路人丙
主机什么时候都能看见信息的更新,作为应该回邮件的人,完全有权利装作看不见
1
2
3
4
5
6
7
8
9
10
11
|
[root@host88 volumes] # pwd
/var/lib/docker/volumes
[root@host88 volumes] # ll
total 0
drwxr-xr-x 3 root root 18 Jul 25 05:31 volname
[root@host88 volumes] # find . -type f
. /volname/_data/helloworld
[root@host88 volumes] # cat ./volname/_data/helloworld
hello, world by 5a43b6347b53, who is host?
hello, world by 6365668cea55, I do not know
[root@host88 volumes] #
|
路人丙使用ubuntu,他觉得这样数据设计地实在不好,他表示他根本不想看到这样的信息,大家不要再reply to all
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[root@host88 ~] # docker run -it -v volname:/volumedata/dbdata ubuntu
root@730209b03ea6:/ # cd volumedata/dbdata
root@730209b03ea6: /volumedata/dbdata # ls -l
total 4
-rw-r--r-- 1 root root 87 Jul 25 09:44 helloworld
root@730209b03ea6: /volumedata/dbdata # cat helloworld
hello, world by 5a43b6347b53, who is host?
hello, world by 6365668cea55, I do not know
root@730209b03ea6: /volumedata/dbdata # echo "hello, world by `hostname`, please do not reply to all" >> helloworld
root@730209b03ea6: /volumedata/dbdata # cat helloworld
hello, world by 5a43b6347b53, who is host?
hello, world by 6365668cea55, I do not know
hello, world by 730209b03ea6, please do not reply to all
root@730209b03ea6: /volumedata/dbdata #
|
Step 5:大家都看到了信息,决定都不再说话
作为和现实世界相反的期待,大家觉得这实在太无聊了,于是没有人再不断跳出来Reply all说请把我从mail link中剔除
1
2
3
4
5
|
[root@6365668cea55 dbdata] # cat helloworld
hello, world by 5a43b6347b53, who is host?
hello, world by 6365668cea55, I do not know
hello, world by 730209b03ea6, please do not reply to all
[root@6365668cea55 dbdata] #
|
1
2
3
4
5
|
root@5a43b6347b53: /volumedata/dbdata # cat helloworld
hello, world by 5a43b6347b53, who is host?
hello, world by 6365668cea55, I do not know
hello, world by 730209b03ea6, please do not reply to all
root@5a43b6347b53: /volumedata/dbdata #
|
1
2
3
4
5
|
[root@host88 volumes] # cat ./volname/_data/helloworld
hello, world by 5a43b6347b53, who is host?
hello, world by 6365668cea55, I do not know
hello, world by 730209b03ea6, please do not reply to all
[root@host88 volumes] #
|
实际多Container使用同一个Volume完全可以做的更好,把读写的权限进行合理设定,能够满足很多实际的场景。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
原文链接:http://blog.csdn.net/liumiaocn/article/details/52028007