Docker存储卷
Docker存储卷
Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在栈顶部添加一个读写层。
如果运行中的容器修改了现有的一个已经存在的文件,那么该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即“写时复制(COW)”机制。
卷为docker提供了独立于容器的数据管理机制
- 可以把“镜像”想象成静态文件,例如“程序”,把卷类比为动态内容,例如“数据”;于是,镜像可以重用,而卷可以共享;
- 卷实现了“程序(镜像)”和“数据(卷)”分离,以及“程序(镜像)”和“制作镜像的主机”分离,用户制作镜像时无需考虑镜像运行的容器所在的宿主机环境;
为什么需要数据卷?
-
关闭并重启容器,其数据不受影响;但删除Docker容器,则其更改将会全部丢失。
-
存在的问题
- 存储于联合文件系统中,不易于宿主机访问;
- 容器间数据共享不便
- 删除容器其数据会丢失
-
解决方案:”卷(volume)“
“卷”是容器上的一个或多个“目录”,此类目录可绕过联合文件系统,与宿主机上的某目录“绑定(关联)”。
卷的类型
Bind Mount Volume
# 主机目录如果没有会自动创建。
$ docker run -it --name bbox1 -v HOSTDIR:VOLUMEDIR busybox:latest
# 查看bbox1容器的卷、卷标识符和挂载的主机目录
$ docker inspect -f {{.Mounts}} bbox1
Managed Volume
需要给定容器中的目录,无需指定宿主机的目录。采用-v选项即可。
$ docker run -it --name bbox2 -v /data busybox:latest
# 查看bbox1容器的卷、卷标识符和挂载的主机目录,此处采用了go模板。
$ docker inspect -f {{.Mounts}} bbox2
多容器共享宿主机目录
# 创建第一个容器,并指定目录
$ docker run -it --name box1 -v /data/volumes/box1:/data --rm busybox:latest
# 创建第二个容器,并指定目录,并仍旧沿用/data/volumes/box1目录
$ docker run -it --name box2 -v /data/volumes/box1:/data --rm busybox:latest
# 复制使用其他容器的卷,为docker run命令使用--volumes-form 选项
$ docker run -it --name bbox3 --volumes-form box1 busybox:latest
# 如此一来,可以搭建公用基础容器网络、数据卷的多个容器的服务。基础架构支撑容器。
$ docker run -it --name infracon -v /data/infracon/volume/:/data/web/html busybox
$ docker run --name nginx --network container:infracon --volumes-from infracon -it busybox
$ docker inspect infracon -f {{.Mounts}},{{.NetworkSettings.IPAddress}}
[{bind /data/infracon/volume /data/web/html true rprivate}],172.17.0.2
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
`inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0`
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:656 (656.0 B) TX bytes:42 (42.0 B)