docker的存储卷
1、简介
- Docker镜像是由多个只读层叠加而成,启动容器的时候,docker会加载只读镜像并再镜像栈顶添加一些读写层
- 如果运行的容器修改了现有的一个已经存在的文件,那改文件会从读写层下的只读层复制到读写曾,改文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,就是所说的写时复制机制
- 类似于挂载 把容器内的数据 与宿主机的一个路径简历关联关系,可以让宿主机和容器交换文件等 也可以让两个容器的隔离系统 在某个子路径实现绑定关系 共享该路径的效果
- 容器关闭后自动删除 容器内部数据也会丢失 如果重新创建容器直接关联到原数据的存储卷,可保证数据和业务的持久性
- 扩展: 容器的存储卷所在宿主机的位置可以是宿主机NFS挂载的位置,这样的话,所有挂载了nfs目录的主机就都可以看到该存储卷 可以实现集群范围内任意机器启动docker来继续业务,云计算的基础理论就是这样
2、存储卷
存储卷:关闭重启容器数据不受影响,但是删除docker则会全部丢失
存在的问题
存储与联合文件系统中,不易于宿主机访问
荣期间数据共享不便
删除容器其数据会丢失
解决方案 卷
卷是容器上的一个或多个目录 此类目录也可以绕过联合文件系统 与宿主机上的某目录关联
种类
1、绑定挂载卷:
-
需要制定容器和宿主机的关联路径
docker run -it -v HOSTDIR:VOLUMEDIR --name aaa aaa
2、docker管理的卷: -
只指定容器路径 -v
docker run -it --name aaa -v /data
1、docker管理的卷
验证
#开启容器并指定容器路径
[root@node1 ~]# docker run --name b2 -it -v /data busybox
/ # ls
bin data dev etc home proc root sys tmp usr var
#查看卷详情
[root@node1 ~]# docker inspect b2
"Mounts": [
{
"Type": "volume",
"Name": "f7a3823aa84cab14754c145f9645b4509d749d7131c5115fdf325286067276ff",
"Source": "/var/lib/docker/volumes/f7a3823aa84cab14754c145f9645b4509d749d7131c5115fdf325286067276ff/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
#看到容器挂载路径为/data
#宿主机挂载路径为/var/lib/docker/volumes/f7a3823aa84cab14754c145f9645b4509d749d7131c5115fdf325286067276ff/_data
#测试宿主机和容器之间共享文件
#宿主机
[root@node1 ~]# cd /var/lib/docker/volumes/f7a3823aa84cab14754c145f9645b4509d749d7131c5115fdf325286067276ff/_data
[root@node1 _data]# touch 406056573
[root@node1 _data]# ls
406056573
#容器
/ # ls data
406056573
#容器和宿主机之间可以实现文件共享
2、绑定挂载卷
验证
#开启容器指定宿舍主机和容器存储卷路径
[root@node1 ~]# docker run --name b2 -it --rm -v /data/volumes/bs:/data busybox
/ # ls
bin data dev etc home proc root sys tmp usr var
[root@node1 ~]# docker inspect b2
"Mounts": [
{
"Type": "bind",
"Source": "/data/volumes/bs",
"Destination": "/data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
#宿舍主 /data/volumes/bs(没有会自动生成) 与容器内的/data绑定
#验证
#容器
/ # cd data
/data # touch test.php
#宿主机
[root@node1 _data]# cd /data/volumes/bs/
[root@node1 bs]# ls
test.php
扩展
多个容器可以通过绑定挂在卷实现共享
#启动容器b3 使用b2 一样的挂载路径和方式
[root@node1 ~]# docker run --name b3 -it --rm -v /data/volumes/bs:/data busybox
/ # ls /data
test.php
#此时可以实现 b2 b3 共享 手动指定共享
#生产中可以先创建一个基础容器 可以不提供服务 做基础支撑 真正生产服务的容器复制基础支撑的存储卷设置,生产服务的容器通过基础支撑的容器获得一切生产环境的设定
#类似虚拟机 克隆,还可以指定数据的读写权限,默认是可读可写,可指定为只读 /data/volumes/bs:/dat:ro ro 设置了只读权限,在容器中是无法对 bind mount 数据进行修改的。只有 host 有权修改数据,提高了安全性。
#除了绑定目录外也可以绑定单个文件,/data/volumes/bs/index.html:/data/web/html
还可以指定数据的读写权限,默认是可读可写,可指定为只读:
docker 不会销毁 bind mount,删除数据的工作只能由 host 负责。对于 docker managed volume,在执行 docker rm 删除容器时可以带上 -v 参数,docker 会将容器使用到的 volume 一并删除,但前提是没有其他容器 mount 该 volume,目的是保护数据,非常合理。
如果删除容器时没有带 -v 呢?这样就会产生孤儿 volume,好在 docker 提供了 volume 子命令可以对 docker managed volume 进行维护
可以通过 docker volume ls 查看 docker volume rm 删除,由于种种原因对docker容器维护的不善,导致在销毁容器的时候没有使用-v这个参数,所有就导致留下了很多“孤儿volume”,但是docker volume ls这个命令只能简单查看本地的docker managed volume,而并不能显示是挂载到哪个容器,而即便是使用docker volume inspect [volume name]也无法确认是哪个容器正在使用,这样就出现很多有效和无效的docker managed volume混在一起,用这个命令删除孤儿 volume: docker volume prune