COW机制
docker镜像是由多个可读层叠加而成,启动容器时只会加载只读镜像层并在镜像栈顶部添加一个读写层
如运行容器修改一个已存在的文件,该文件会从读写层下面的只读层复制到读写层。该文件只读版本依然存在,只是被读写层该文件副本所隐藏
写时复制机制:Copy On Write(COW)
- 由于隔着很多镜像,文件修改比较麻烦,这就引出了存储卷的概念
存储卷
什么是存储卷
主机上的这个与容器形成绑定关系的目录被称作存储卷
通过跟宿主机的指定目录和容器内部文件系统进行绑定。这样容器写入文件的时候会直接写入宿主机的目录下
存储卷的优点
- 安全性,容器消亡只要不删除宿主机上的存储目录就不怕数据丢失
- 共享性,指定宿主机的目录存储卷,该机上的容器可共享存储卷的数据
- 独立性,可以在宿主机配置一个硬盘当作存储卷,且不与所有的容器共享
Docker存在的问题有:
- 存储于联合挂载文件系统中,不易于宿主机访问
- 容器间数据共享不便
- 删除容器其数据会丢失
存储卷则提供一个很好的解决方案
存储卷管理方式
存储卷在容器初始化时自动创建,由base image卷中的数据复制而来
存储卷为Docker提供了独立于容器的数据管理机制:
- 镜像与数据的分离
- 镜像于制作镜像主机的分离
存储卷的分类
- 绑定挂载卷
- 指向主机文件系统上用户指定位置的卷
- docker管理卷
- docker守护进程在宿主机文件系统属于docker的部分创建管理卷
- docker守护进程在宿主机文件系统属于docker的部分创建管理卷
容器数据管理
在使用Docker的过程中,往往需要能查看容器内应用产生的数据,或者需要把容器内的数据进行备份,甚至多个容器之间进行数据的共享
容器中管理数据主要有两种方式:
- 数据卷(Data Volumes)
- 数据卷容器(Data Volumes Containers)
容器卷使用语法
- docker管理卷
docker run -it --name CONTAINER_NAME -v VOLUMEDIR IMAGE_NAME
- 绑定挂载卷
docker run -it --name CONTAINER_NAME -v HOSTDIR:VOLUMEDIR:(权限) IMAGE_NAME
容器中使用数据卷
- 容器内创建数据卷
//目录需要添加绝对路径
[root@node0 ~]# docker run -P -it --rm -v /test busybox
/ # ls
bin dev etc home proc root sys test tmp usr var
/ # touch test/a
/ # ls test/
a
- 挂载主机目录为绑定挂载卷
[root@node0 ~]# docker run -P -it --rm -v /test:/data busybox #目录必须使用绝对路径,不存在将自动创建
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # touch data/a
/ # ls data/
a
[root@node0 ~]# ls /
bin dev home lib64 mnt proc run srv test usr
boot etc lib media opt root sbin sys tmp var
[root@node0 ~]# ls /test/
a
Docker挂载数据卷的默认权限是读写(rw),用户也可以通过(ro)指定为只读
[root@node0 ~]# docker run -it -P --rm --name test -v /data:/htdocs:ro httpd
//只读目录,无法写入
[root@node0 data]# mkdir a
mkdir: cannot create directory ‘a’: No such file or directory
挂载一个本地主机文件作为数据卷
//通过挂载文件查看历史
[root@node0 ~]# docker run -it -P --rm --name test -v /root/.bash_history:/.bash_history busybox
基于数据卷容器实现的数据迁移
备份
创建数据卷容器
[root@node0 ~]# docker run -itd --name dbdata -v /dbdata:/dbdata centos
f4c79816dcaacb3190c23946384e89406812b08ac78dc84830bd7dd02008bdcb
备份
[root@node0 ~]# docker run --name t1 --volumes-from dbdata -v $(pwd):/backup centos tar -cvf /backup/backup.tar /dbdata
tar: Removing leading `/' from member names
/dbdata/
/dbdata/a
[root@node0 ~]# tar tf backup.tar
dbdata/
dbdata/a
迁移数据
//再拉一个数据卷容器
[root@node0 ~]# docker run -it --name dbdata2 -v /dbdata/ centos /bin/bash
[root@e0c770b4a60f /]# ls /dbdata/
[root@e0c770b4a60f /]#
//恢复备份
[root@node0 ~]# docker run --name t2 --volumes-from dbdata2 -v $(pwd):/backup centos tar -xvf /backup/backup.tar
dbdata/
dbdata/a
//查看数据卷端
[root@e0c770b4a60f /]# ls /dbdata/
a