zoukankan      html  css  js  c++  java
  • docker volume

    个人学习笔记,谢绝转载!!!
    原文:https://www.cnblogs.com/wshenjin/p/9566926.html


    Docker 为容器提供了两种存放数据的资源:

    • 由 Storage driver 管理的镜像层和容器层
    • Data Volume

    Storage driver

    容器由最上面一个可写的容器层,以及若干只读的镜像层组成,容器的数据就存放在这些层中。这样的分层结构最大的特性是 Copy-on-Write:

    1. 新数据会直接存放在最上面的容器层。
    2. 修改现有数据会先从镜像层将数据复制到容器层,修改后的数据直接保存在容器层中,镜像层保持不变。
    3. 如果多个层中有命名相同的文件,用户只能看到最上面那层中的文件。

    分层结构使镜像和容器的创建、共享以及分发变得非常高效,而这些都要归功于 Docker storage driver。正是 storage driver 实现了多层数据的堆叠并为用户提供一个单一的合并之后的统一视图。

    Docker 支持多种 storage driver,有 AUFS、Device Mapper、Btrfs、OverlayFS、VFS 和 ZFS。它们都能实现分层的架构,同时又有各自的特性。

    对于那些无状态的应用,直接将数据放在由 storage driver 维护的层中是很好的选择,无状态意味着容器没有需要持久化的数据,随时可以从镜像直接创建。

    Data Volume

    Data Volume 本质上是宿主机文件系统中的目录或文件,能够直接被 mount 到容器的文件系统中,Data Volume 数据可以被永久的保存,即使使用它的容器已经销毁。

    Data Volume有两种类型:bind mountdocker managed volume

    bind mount

    bind mount是直接将宿主机上已存在的目录或者文件直接挂到容器中,容器路径不存在会自动创建,已存在的会被隐藏起来

    -v [local path]:[container path]:[ro]

    [root@Docker_Machine_192.168.31.130 ~]# docker run -itd --name mybusybox  -v /data/web/:/mydata/web busybox    
    08ce3e68d61061356993426237da2474c518aaab2b45d48271c73610217aef28
    [root@Docker_Machine_192.168.31.130 ~]# docker exec -ti mybusybox sh 
    / # ls -l /mydata/web/
    total 0
    / # 
    

    -v 参数最后可以指定权限,默认是可读可写,ro表示只读

    上面的栗子中宿主机/data/web/这个路径和容器mybusybox是共享的,不论在容器内部操作挂载点下的文件还是在宿主操作这个路径下的文件,结果都是一样的

    还可以把宿主机的同一个路径挂到多个容器中,实现文件的共享

    另外一种命令方式,相对麻烦些:

    docker run -itd --name mybusybox  --mount type=bind,source=/data/web/,target=/mydata/web,readonly  busybox
    

    inspect 查看一下容器挂载的信息:

    [root@Docker_Machine_192.168.31.130 ~]# docker inspect -f '{{.Mounts}}' mybusybox  
    [{bind  /data/web /mydata/web   false rprivate}]
    
    #非readonly:
    [root@Docker_Machine_192.168.31.130 ~]# docker inspect -f '{{.Mounts}}' mybusybox              
    [{bind  /data/web /mydata/web   true rprivate}]
    

    docker managed volume

    和bind volume最大的区别是,docker managed volume不需要指定本地路径,而是被固定指到$DOCKER_PATH/volumes/

    具体命令:

    [root@Docker_Machine_192.168.31.130 ~]# docker run -tid --name=mybusybox1 -v /data/web busybox 
    bba8213c2e545231d5fbddd2d265d46f9740e9f6e1339747d9a7a038cd36db88
    #或者:
    [root@Docker_Machine_192.168.31.130 ~]# docker run -itd --name mybusybox2 --mount type=volume,target=/mydata/web  busybox
    
    #查看一下信息:
    [root@Docker_Machine_192.168.31.130 ~]# docker inspect -f '{{.Mounts}}' mybusybox1 
    [{volume 2bd769dd0a7152f09fed996944c6a4990d60f5077a1e51f7118bf4e6e4584895 /data/dokcer/docker_data/volumes/2bd769dd0a7152f09fed996944c6a4990d60f5077a1e51f7118bf4e6e4584895/_data /data/web local  true }]
    

    可以看到,docker managed volume所配置的本地目录位置是在/data/dokcer/docker_data/volumes/$volumes_id/_data/,进入这个目录对该目录下的文件执行操作,和进入容器的/data/web目录是一样的

    可以用docker volume命令查看:

    [root@Docker_Machine_192.168.31.130 ~]# docker volume ls
    DRIVER              VOLUME NAME
    local               2bd769dd0a7152f09fed996944c6a4990d60f5077a1e51f7118bf4e6e4584895
    

    和bind volume的一些区别:

    1. 无法指定权限,只能可读可写
    2. 容器目录已存在的数据,会被复制到volume中,不是被隐藏
    3. 宿主机位置不可任意指定,都在/data/dokcer/docker_data/volumes/

    数据共享

    volume container

    在bind volume的情况下,我们可以将一个宿主机目录挂到多个容器中,实现数据共享,在docker managed volume的情况下呢?

    可以使用 volume container,既创建一个专门为其他容器提供 volume 的容器实例,而这个实例的volume可以是bind volume

    我们先创建一个volume container:

    [root@Docker_Machine_192.168.31.130 ~]# docker create --name=my_volume_container -v /data/web/:/mydata/web busybox
    bd25e807dd9e0518ae2d6a525bcb56fc10944f9a7195b72c3d4f7b799376531e
    [root@Docker_Machine_192.168.31.130 ~]# docker inspect -f '{{.Mounts}}' my_volume_container
    [{bind  /data/web /mydata/web   true rprivate}]
    

    其他容器可以通过 --volumes-from 使用my_volume_container的volume:

    [root@Docker_Machine_192.168.31.130 ~]# docker run -tid --volumes-from my_volume_container --name mybusybox1 busybox 
    a15f4e66c4cc8c9a09e572d5328edd808c34e8ea377688a1fe2671736b5b3d6b
    [root@Docker_Machine_192.168.31.130 ~]# docker run -tid --volumes-from my_volume_container --name mybusybox2 busybox  
    aabc8bca934734b68dcacc0986463cb39c192aad958a5a6325a9d3767f502113
    [root@Docker_Machine_192.168.31.130 ~]# docker run -tid --volumes-from my_volume_container --name mybusybox3 busybox  
    ab8158b9c8d3bfaa42da4346cf83d51ecbb7470ed32919fb94f85c2beff68293
    

    看看其中一个容器的volume信息:

    [root@Docker_Machine_192.168.31.130 ~]# docker inspect -f '{{.Mounts}}' mybusybox2
    [{bind  /data/web /mydata/web   true rprivate}]
    

    mybusybox1 mybusybox2 mybusybox3 这三个容器的volume就和volume container一致了

    volume container 的特点:

    1. 与 bind mount 相比,不必为每一个容器指定 host path,所有 path 都在 volume container 中定义好了,容器只需与 volume container 关联,实现了容器与 host 的解耦
    2. 使用 volume container 的容器其 mount point 是一致的,有利于配置的规范和标准化,但也带来一定的局限,使用时需要综合考虑。
    docker cp

    docker managed volume的源点目录一开始是不存在的,在Docker启动后,执行创建容器时才生成,这样一些数据只能等到目录创建后才能复制进去

    docker cp可以在容器和 host 之间拷贝数据

    [root@Docker_Machine_192.168.31.130 ~]# docker cp /data/web/index.html  mybusybox1:/data/web/ 
    [root@Docker_Machine_192.168.31.130 ~]# ll /data/dokcer/docker_data/volumes/94b92f2c5074343f8f3244ad9cb65e67bb5306f621df871224a9debbf443fada/_data/
    total 4
    -rw-r--r-- 1 root root 12 Aug 31 16:49 index.html
    

    volume的生命周期

    volume是本地文件或目录,在容器关闭销毁时不会被销毁

    如果要删除容器时,同时删除该容器的volume,可以用命令:docker rm -v [id|name]

    volume的基本管理命令

    • docker volume ls:列出所有的volume
    • docker volume rm:删除volume,无法删除正在使用的
    • docker volume create :创建docker managed volume
    • docker volume inspect:查看详细信息
    • docker volume prune :清空所有不在使用的volume

    简单创建一个volume:

    [root@Docker_Machine_192.168.31.130 ~]# docker volume create -d local  --name myvolume      
    myvolume
    [root@Docker_Machine_192.168.31.130 ~]# docker volume inspect myvolume
    [{
        "CreatedAt": "2018-08-31T17:08:10+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/data/dokcer/docker_data/volumes/myvolume/_data",
        "Name": "myvolume",
        "Options": {},
        "Scope": "local"
    }]
    

    使用:

    [root@Docker_Machine_192.168.31.130 ~]# docker run -tid --name=mybusybox1 -v myvolume1:/data/web busybox 
    9cb821232d042dba071f777067361e427daaebf4250c36906b36d65587fac662
    [root@Docker_Machine_192.168.31.130 ~]# docker run -tid --name=mybusybox2 --mount type=volume,source=myvolume1,target=/mydata/web  busybox  
    a4b134dff9a3072ff06ffaaeabead7e2f6c740946be815f10f18d0a861c4a513
    
  • 相关阅读:
    oracle锁表查询,资源占用,连接会话,低效SQL等性能检查
    oracle临时表
    oracle列转行
    oracle数据库查询重复记录
    查找mysql的cnf文件位置
    Nginx反向代理,负载均衡,redis session共享,keepalived高可用
    Linux 软件安装
    Linux上网设置
    c#学习内容
    PHP八大设计模式
  • 原文地址:https://www.cnblogs.com/wshenjin/p/9566926.html
Copyright © 2011-2022 走看看