zoukankan      html  css  js  c++  java
  • 11.Docker存储管理

    Docker Data Volume

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

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

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

    存在的问题

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

    解决方案:”volume“

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

    volume的初衷是独立于容器生命周期实现数据持久化,因此删除容器不会删除卷

    image

    Docker的数据持久化即使数据不随着container的结束而结束,数据存在于host机器上——要么存在于host的某个指定目录中(使用bind mount),要么使用docker自己管理的volume(/var/lib/docker/volumes下)。

    bind mount

    bind mount自docker早期便开始为人们使用了,用于将host机器的目录mount到container中。需明确指定宿主机路径与容器内部路径,进行绑定;具有高耦合性,强自由行;

    bind mount在不同的宿主机系统时不可移植的,比如Windows和Linux的目录结构是不一样的,bind mount所指向的host目录也不能一样。这也是为什么bind mount不能出现在Dockerfile中的原因,因为这样Dockerfile就不可移植了。

    docker run -it -v HOSTDIR:VOLUMEDIR --name bbox2 busybox
    #查看bbox2容器的卷、卷标识符及挂载的主机目录(-f 指定Go模板)
    docker inspect -f {{.mounts}} bbox2
    #绑定当前路径下host-dava到容器/container-data下
    docker run -it -v $(pwd)/host-dava:/container-data alpine sh
    

    有几点需要注意:

    • host机器的目录路径必须为全路径(准确的说需要以/~/开始的路径),不然docker会将其当做volume而不是volume处理
    • 如果host机器上的目录不存在,docker会自动创建该目录
    • 如果container中的目录不存在,docker会自动创建该目录
    • 如果container中的目录已经有内容,那么docker会使用host上的目录将其覆盖掉

    volume

    只需指定容器内需要挂载路径,由docker daemon自动创建维护特定目录下;低耦合性,但无法指定特定宿主机路径

    volume也是绕过container的文件系统,直接将数据写到host机器上,只是volume是被docker管理的,docker下所有的volume都在host机器上的指定目录下/var/lib/docker/volumes。

    docker run -it -name bbox1 -v /data busybox
    #查看bbox1容器的卷、卷标识符及挂载的主机目录
    docker inspect -f {{.mounts}} bbox1
    
    docker run -it -v my-volume:/mydata alpine sh
    

    然后可以查看到给my-volume的volume:

    docker volume inspect my-volume
    [
        {
            "CreatedAt": "2019-08-28T19:42:49Z",
            "Driver": "local",
            "Labels": null,
            "Mountpoint": "/var/lib/docker/volumes/my-volume/_data",
            "Name": "my-volume",
            "Options": {},
            "Scope": "local"
        }
    ]
    
    LowerDir: image镜像层(镜像本身,只读)
    UpperDir:容器的上层(读写)
    MergedDir:容器的文件系统,使用UnionFS(联合文件系统)将lowerdir和upperdir合并给容器使用
    WorkDir:容器在宿主机的工作目录
    

    可以看到,volume在host机器的目录为/var/lib/docker/volumes/my-volume/_data。此时,如果my-volume不存在,那么docker会自动创建my-volume,然后再挂载。

    也可以不指定host上的volume:

    docker run -it -v /mydata alpine sh
    

    此时docker将自动创建一个匿名的volume,并将其挂载到container中的/mydata目录。匿名volume在host机器上的目录路径类似于:/var/lib/docker/volumes/30b32264cd0acfe8625e07edf156eb197716c20f69e7e9a053c87c2182b2e7d8/_data

    创建volume

    除了让docker帮我们自动创建volume,我们也可以自行创建:

    docker volume create my-volume-2
    

    然后将这个已有的my-volume-2挂载到container中:

    docker run -it -v my-volume-2:/mydata alpine sh
    

    需要注意的是,与bind mount不同的是,如果volume是空的而container中的目录有内容,那么docker会将container目录中的内容拷贝到volume中,但是如果volume中已经有内容,则会将container中的目录覆盖。

    创建数据容器(一个不运行的容器)

    docker  run -it  -v /father/path:/child/path  --name data  ubuntu
    exit
    上面两步是创建号了数据container,接下来就用 --volumes--from 来挂载数据到新的容器中
    docker  run -it   --volumes--from data    ubuntu
    

    复制容器volume(共享容器存储)

    单个容器的卷使用同一个主机目录

    docker run -it --name c1 -v /docker/volume/v1:/data busybox
    docker run -it --name c2 -v /docker/volume/v1:/data busybox
    

    复制使用其它容器的卷,为docker run命令使用--volumes-from选项

    docker run -it --name bbox1 -v /docker/volumes/v1:/data busybox
    docker run -it --name bbox2 --volumes-from bbox1 busybox
    

    tmpfs

    tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久存储在任何位置,可以使用

    tmpfs,同时避免写入容器可写层提高性能。

    # 使用--tmpfs
    docker run -dit --name tmpfs-test --tmpfs /app busybox
    
  • 相关阅读:
    vmware ubuntu 异常关机无法连接到网络
    Speed up GCC link
    常用的一些解压命令
    Log4j 漏洞复现
    Test Case Design method Boundary value analysis and Equivalence partitioning
    CCA (Citrix Certified Administrator) exam of “Implementing Citrix XenDesktop 4”
    What is Key Word driven Testing?
    SAP AGS面试小结
    腾讯2013终端实习生一面
    指针的引用
  • 原文地址:https://www.cnblogs.com/Gmiaomiao/p/14289243.html
Copyright © 2011-2022 走看看