• docker数据持久化


    转载/参考:

    https://www.jianshu.com/p/ef0f24fd0674

    Docker的数据持久化主要有两种方式:

    • bind mount
    • docker managed volume

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

    1.bind mount

    bind mount自docker早期便开始为人们使用了,用于将host机器的目录mount到container中。但是bind mount在不同的宿主机系统时不可移植的,比如Windows和Linux的目录结构是不一样的,bind mount所指向的host目录也不能一样。这也是为什么bind mount不能出现在Dockerfile中的原因,因为这样Dockerfile就不可移植了。

    将host机器上当前目录下的host-data目录mount到container中的/container-data目录:

    docker run -it -v /home/host-dava:/container-data alpine sh

    有几点需要注意:

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

    2.docker managed volume

    2.1在docker run使用

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

    将my-volume挂载到container中的/mydata目录:

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

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

    docker volume inspect my-volume
    [
        {
            "CreatedAt": "2018-03-28T14:52:49Z",
            "Driver": "local",
            "Labels": null,
            "Mountpoint": "/var/lib/docker/volumes/my-volume/_data",
            "Name": "my-volume",
            "Options": {},
            "Scope": "local"
        }
    ]

    可以看到,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/300c2264cd0acfe862507eedf156eb61c197720f69e7e9a053c87c2182b2e7d8/_data

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

    docker volume create my-volume-2

    查看所有volume

    docker volume ls

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

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

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

    2.2.Dockerfile中的VOLUME

    在Dockerfile中,我们也可以使用VOLUME指令来申明contaienr中的某个目录需要映射到某个volume:

    #Dockerfile
    VOLUME /foo

    这表示,在docker运行时,docker会创建一个匿名的volume,并将此volume绑定到container的/foo目录中,如果container的/foo目录下已经有内容,则会将内容拷贝的volume中。也即,Dockerfile中的VOLUME /foodocker run -v /foo alpine的效果一样。

    Dockerfile中的VOLUME使每次运行一个新的container时,都会为其自动创建一个匿名的volume,如果需要在不同container之间共享数据,那么我们依然需要通过docker run -it -v my-volume:/foo的方式将/foo中数据存放于指定的my-volume中。

    3.对比

    相同点:两者都是 host 文件系统中的某个路径。

    不同点:

     bind mountdocker managed volume
    volume 位置 可任意指定 /var/lib/docker/volumes/...
    对已有mount point 影响 隐藏并替换为 volume 原有数据复制到 volume
    是否支持单个文件 支持 不支持,只能是目录
    权限控制 可设置为只读,默认为读写权限 无控制,均为读写权限
    移植性 移植性弱,与 host path 绑定 移植性强,无需指定 host 目录

    4.数据容器

    如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,但是它的目的是专门用来提供数据卷供其他容器挂载。通常会在容器中创建一个或多个卷,其他的容器就可以通过--volumes-from选项来访问它们。

    运行一个名为storage的数据容器,它包含一个卷并在后台运行:

    docker run -d -v /data --name storage ubuntu

        接下来我们运行另一个容器:

    docker run -it --name
    storage2 --volumes-from storage ubuntu bash
     
  • 相关阅读:
    Math类四个常用方法辨析,floor、ceil、round、rint
    【转】ctypes库的使用整理
    【转】采用dlopen、dlsym、dlclose加载动态链接库【总结】
    【转】collectd的部署
    【转】Pycharm Professional(专业版)完美破解,
    【转】在结构体最后定义一个长度为0的字符数组(技巧)
    【转】C++11智能指针之weak_ptr
    轻量级、高性能http代理服务器,内网穿透从未如此简单。
    php 大文件上传 redis+php resque 较低io消耗
    leetcode 870. 优势洗牌
  • 原文地址:https://www.cnblogs.com/SmilingEye/p/11168343.html
Copyright © 2020-2023  润新知