zoukankan      html  css  js  c++  java
  • 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,即可实现一个NMT架构。 让它们共享名称空间中的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      #加入网络名称空间,同时复制卷

  • 相关阅读:
    [College] C++字符串读入与进制转化-关于《实践教程》P10[程序]的一些总结
    [College] 二进制与机器数的几种形式
    [College] Hello World!
    [SinGuLaRiTy] 复习模板-数学
    ByteCTF 2020 KOP Writeup
    【题解】电子科技大学第十八届 ACM 程序设计竞赛
    【逆向】某 VR 驱动分析过程
    物联网框架 IoTivity 中间人攻击分析
    批处理工具 CAPI 逆向分析之 API Call
    DASCTF 2020 六月赛 Reverse Writeup
  • 原文地址:https://www.cnblogs.com/xiaobaozi-95/p/12301121.html
Copyright © 2011-2022 走看看