docker(三)--存储卷

为什么需要存储卷?

  • Docker镜像由多个只读层叠加而成,启动容器时,docker会加载只读镜像并在镜像栈顶部添加一个读写层。
  • 如果运行的容器修改了一个已有的文件,那么该文件会从只读层复制到读写层,该文件的只读版本依然存在,只是已经被读写层中该文件的副本所隐藏,即“写时复制 COW”机制。

存在的问题

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

存储卷 volume

“卷”是容器上的一个或多个“目录”,此类目录可绕过联合文件系统,与宿主机上的某个目录“绑定(关联)”;

类似于挂载一样,宿主机 /data/web目录与容器中的/container/data/web目录建立绑定关系,然后容器中的进程向这个目录中写数据时,是直接写在宿主机的目录上的,绕过容器文件系统与宿主机的文件系统建立关联关系, 宿主机和容器内可以共享数据库内容,让容器直接访问宿主机中的内容,宿主机也可以访问容器内容,两者是同步的。即使容器被删除,数据也不会丢失。

 数据卷的最大特点是:其生存周期独立于容器的生存周期 

  • volume于容器初始化之时会创建,由base image提供的卷中的数据会于此期间完成复制
  • volume的初衷是独立于容器的生命周期实现数据持久化,因此删除容器之时既不会删除卷,也不会对哪怕未被引用的卷做垃圾回收操作
  • 卷为docker提供了独立于容器的数据管理机制

Docker卷类型

Docker存储卷有两种类型,每种类型都在容器中存在一个挂载点,但其在宿主机上位置有所不同

第一种:绑定挂载卷: 在宿主机上的路径需要人工指定,在容器中的路径也需要指定,两个已知的路径建立关联关系。

第二种:docker管理卷: 只需要指定容器的挂载点,而被绑定宿主机下的那个目录,是由容器引擎daemon自行创建一个空的目录,或者使用一个已经存在的目录,与存储卷建立存储关系,这种方式极大解脱用户在使用卷时的耦合关系,缺陷是用户无法指定那些使用目录,临时存储比较适合

在容器中使用volumes

1.docker管理卷

 在一个终端运行容器:

docker run -it --name vbox1 -v /data busybox

/ # touch /data/test

 另一个终端查看:

docker inspect vbox1    #查看容器详细信息

"Mounts": [
{"Type": "volume",
"Name": "257ff9d7f0822606560fc21f8bd63b784cd2db72e410c8634ef361df3f5157b3",
"Source": "/var/lib/docker/volumes/257ff9d7f0822606560fc21f8bd63b784cd2db72e410c8634ef361df3f5157b3/_data",
"Destination": "/data",

# cd /var/lib/docker/volumes/257ff9d7f0822606560fc21f8bd63b784cd2db72e410c8634ef361df3f5157b3/_data
# ls
test

# echo "hello" > a.txt   #在容器中也可看到

2.绑定挂载卷

docker run -it --rm --name vbox2 -v /host/volumes/b2:/data busybox

docker inspect vbox2

"Mounts": [
{"Type": "bind",
"Source": "/host/volumes/b2",
"Destination": "/data",

在宿主机/host/volumes/b2 做的操作和容器内/data的操作会同步。下次启动容器绑定挂在此卷时,文件依然存在。

使用golang模板查看

docker inspect -f {{.Mounts}} vbox2
[{bind /host/volumes/b2 /data1 true rprivate}]

docker inspect -f {{.NetworkSettings.Networks.bridge.IPAddress}} vbox2
172.17.0.5

多个容器共享同一个存储卷

可以让两个docker容器同时关联到同一个宿主机的目录中,实现共享使用同一个存储卷,容器之间的数据共享

docker run -it --rm --name vbox3 -v /host/volumes/b2:/data3 busybox

# ls /data3

docker run -it --rm --name vbox2 -v /host/volumes/b2:/data2 busybox

# ls /data2

复制存储卷 --volumes-from

当需要多个容器同进使用多个卷,卷在那里写每次初始化时都要使用-v来指定,如果不想记录这个路径,docker还支持复制其他的存储卷路径

   制定一个容器,不执行任何任务,创建时,只要指定它的存储路径,作为其他容器的基础容器,其他的容器启动时去复制它的存储卷设置,但是这样的点浪费,不过使用joined container的基础的话,几个容器本来就有密切的关系,如nginx+tomcat,nginx的容器和tomcat容器共享一个底层的网络,有一个对外的接口,有一个loop接口,这样80给nginx,在内loop给tomcat,请求进来,nginx作为反射代理转给tomcat就可以了,再加一个mysql,即可实现一个lnmp架构。 让它们共享名称空间中的uts,net,ipc,  还可以共享存储卷,ngInx处理静态,tomcat处理动态的,在同一个目录下,使用存储卷来解决这个问题,这种组织方式使用构建应用。

  nginx     tomcat     mysql

          共享uts,net,ipc

          共享volume

       

docker run -it --rm --name vbox4 --volumes-from vbox2 busybox

\ # ls data1/
b.txt vbox2 vbox3

制定基础镜像(网上有专门制作基础架构容器的,不用启动,只要创建就可以了)
# docker run --name infracon -it --rm -v /data/basic/volume/:/data/web/html busybox

# docker run --name nginx --network container:infracon --volumes-from infracon -it busybox      #加入网络名称空间,同时复制卷

猜你喜欢

转载自www.cnblogs.com/xiaobaozi-95/p/12301121.html