docker学习笔记3-data volume

时间:2022-10-09 08:58:50



docker data volume:​

docker镜像由多个只读层叠加而成,启动容器时,docker会加载只读镜像层并在镜像栈顶部添加个读写层;

如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即COW写时复制机制;

关闭并重启容器,其数据不受影响;但删除docker容器,则其更改将会全部丢失;

存在的问题:存储于联合文件系统中,不易于宿主机访问;容器间数据共享不便;删除容器其数据丢失;

解决方案:卷volume,volume是容器上的一个或多个目录,此类目录可绕过联合文件系统,与宿主机上的某目录绑定关联;

volume在容器初始化时即会创建,由base image提供的卷中的数据会于此期间完成复制;

volume的初衷是独立于容器的生命周期实现数据持久化,因此删除容器之时既不会删除卷,也不会对哪怕未被引用的卷做垃圾回收操作;

虽然容器的操作中有选项可以在删除容器时删除所用的volume,但不建议这么做;


容器中的目录与宿主机的目录建立绑定关系,当在容器中写时会对应写到宿主机上;

若数据存储在容器内,导致容器迁移有问题,且容器生命周期中只能停而不能删除,如果删除会那可写层写的数据就没了;

需要容器编排工具,实现在启动一个容器时,1传递的众多选项参数,2启动先后顺序;docker上的编排是docker-compose工具,kubernets比它要强大;

有状态应用(MySQL要存储数据)可理解为要持久存储,另无状态应用;

重要概念,只要是有状态应用,那存储卷是必须的;

有状态要存储(MySQL);

有状态不需存储(tomcat,session在内存中可以不存储,存下来最好);

无状态不需存储(nginx作反向代理);

无状态要存储(少见);


volume提供了独立于容器的数据管理机制:

可以把镜像想象成静态文件,如程序,把卷类比为动态内容,如数据,于是镜像可以重用,而卷可以共享;

volume实现了程序(镜像)和数据(卷)的分离,及程序(镜像)和制作镜像的主机分离,用户制作镜像时无须再考虑镜像运行的容器所在的主机的环境;


volume types:

docker有2种类型的卷,每种类型都在容器中存在1个挂载点,但其在主机上的位置有所不同;

bind mount volume,在宿主机上自行创建的目录;

docker-managed volume,由docker进程在固定的目录下/var/lib/docker/vfs/dir/<some volume>自行管理的,通常用id;

容器启动时要有挂载卷选项参数;


docker run --name b2 --it -v /data/ busybox #docker管理的卷

docker inspect b2 #Volume,Mounts段/var/lib/docker/volumes/f8.../_data

cd /var/lib/docker/volumes/f8.../_data

echo 'test' > index.html #在容器中查看,是有的

docker rm b2


docker rn --name b2 -it --rm -v /data/volumes/b2:/data busybox #默认会自动在宿主机上创建目录,必须要明确指定;下次启动必须要指定宿主机的目录,而容器中的目录可自定义

docker inspect b2 #Mounts段Source|Destination


docker是用go开发的,有go模板,而ansible用的是jinja2模板;

docker inspect -f {{ .Mounts }} b2 #外层的{}为模板,{.Mounts}为根下的Mounts;{{>NetworkSettings.IPAddress}}


2个或多个容器共享1个volume,甚至共享net|IPC|UTS;

docker run --name infracon -it -v /data/infraconvolumes/:/data/web/html busybox #基础架构支撑的容器

docker run --name nginx --network container:infracon --volume-from infracon -it --rm busybox #复制并使用指定容器的volume;ifconfig

nginx|tomcat|mariadb,类似一个主机上运行了3个进程;

docker学习笔记3-data volume