• Docker存储


    Docker存储

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

          1. storage driver管理的镜像层和容器层

          2. Date Volume

    storage driver

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

                1. 新数据会直接存放在最上面的容器层

                2. 修改现有数据会先从镜像层复制文件到容器中,再在容器层修改并保持,镜像层的数据不会发生改变

                3. 若多个层中有命名相同的文件,用户只能看到最上面一层的文件

    Date volume之bind mount

    Date volume的特点

          1. Date volume是目录或文件,而非没有格式化的磁盘

          2. 容器可以读写volume中的数据

          3. volume数据可以被永久保存,即使使用它的容器已经销毁

    docker提供两种类型的volume:bind mount和docker managed volume

          bind mount是将host上已经存在的目录或文件mount容器

          例如docker host上有目录$HOME/test

          通过-v将其mount到httpd容器 

          -v的格式为<host path>:<container path>。/usr/local/apache2/test就是apache server存放静态文件的地方。由于/usr/local/apache2/test已经存在,原有数据会被隐藏起来,取而代之的是host $HOME/test/ 中的数据,这与linux mount命令的行为是一致的。

          下面我们进入到容器里面去查看mount过去的目录及其文件 

          这与host下的文件内容一致,现在我们在host中对文件内容进行更新,再进入容器查看修改后的文件,由结果可以看出,在host中修改了index.html文件的内容,容器中文件的内容也跟着被修改 

          也可以使用参数来修改文件的权限,比如下面的例子使用ro将文件设置为只读,容器不能对该文件进行修改,只有在host里面才有权限修改文件

          使用bind mount单个文件的场景是:只需要向容器添加文件,不希望覆盖整个目录。在上面的例子中,我们将html文件加到apache中,同时也保留了容器原有的数据。

          使用单一文件有一点要注意:host中的源文件必须要存在,不然会当作一个新目录bind mount给容器。

          mount point有很多应用场景,比如我们可以将源代码目录mount到容器中,在host中修改代码就能看到应用的实时效果。再比如将mysql容器的数据放在bind mount里,这样host可以方便地备份和迁移数据。

          bind mount不足的地方:bind mount需要指定host文件系统的特定路径,这就限制了容器的可移植性,当需要将容器迁移到其他host,而该host没有要mount的数据或者数据不在相同的路径时,操作会失败。

    docker managed volume

          docker managed volume与bind mount最大的区别是不需要指定mount源,指明mount point就行了,还是以httpd容器为例,创建容器后并用inspect来查看mount源

          docker manages volume的创建过程

                1. 容器启动时,简单告诉docker“我需要一个volume存放数据,帮我mount到目录/abc”

                2. docker在 /var/lib/docker/volume中生成一个随机目录作为mount源

                3. 如果/abc已存在,则将数据复制到mount源

                4. 将volume mount到/abc

    容器与host共享数据

          有两种类型的data volume,它们都可以实现在容器与host间共享数据

          对于bind mount:直接将要共享的目录mount到容器,可以参照前面的例子

          docker managed volume要麻烦些。由于volume位于host中的目录,是在容器启动时才生成,所以需要将共享数据copy到volume中,可以用docker cp在容器与host之间进行文件拷贝 

    容器之间共享数据

          第一种实现方法是将共享数据放在bind mount中,然后再mount到多个容器。先创建三个httpd容器组成web server集群,它们使用相同的html文件,具体操作如下

          1. 将HOME/test mount到三个httpd容器

          2. 查看当前主页内容 

          3. 修改volume中的主页文件,再次查看并确认所有容器文件都使用了新的主页

          另一种方法是用volume container共享数据,下面创建一个volume container

          这里执行的是docker create命令,因为volume container的作用只是提供数据,它本身不需要处于运行状态。容器mount了两个volume

                1. bind mount,存放web server静态文件

                2. docker managed volume,存放一些实用工具(这里为空,只是为了演示)

          通过docker inspect vc_date来查看这两个volume 

          其他容器可以通过--volumes-from使用vc_date这个volume container 

          三个容器都使用了vc_date,以web4为例查看它的volume 

          web4容器使用的是vc_date的volume,而且mount point都是一样的,验证一下数据共享结果,由结果可以看出三个容器已经成功共享了volume container的volume 

    data-packed volume container

          可以将数据完全放在volume container中,与其他容器共享。其方法是将数据打包到镜像,然后通过docker managed volume共享

          用Dockerfile构建镜像,其中ADD将静态文件添加到容器目录,VOLUME的作用于-v等效,用来创建docker manage volume

          build新镜像datapacked 

          用新镜像创建data-packed volume container 

          因为在Dockerfile中使用了VOLUME指令,这里就不需要指定volume的mount point了。启动httpd容器并使用data-packed volume container 

          容器能够正确读取volume中的数据,data-packed volume container是自包含的,不依赖于host提供数据,具有很强的移植性,非常适合只用静态数据的场景,比如web server静态文件

    volume生命周期管理

    备份

          前面搭建了一个本地Registry,并可以通过本地搭建的Registry来运行容器。所有的本地镜像都存在host的 /myregistry目录下,我们要定期备份这个目录 

    恢复

          volume的恢复很简单,如果数据损坏了,直接用之前备份的数据copy到/myregistry下即可

    迁移

          1. docker stop当前Registry容器

          2. 启动新版本容器并mount原有volume

    docker run -d -p 5000:5000 -v /myregistry:/usr/lib/registry registry:lastest

    销毁

          docker不会销毁bind mount,删除数据只能在host上执行。对于docker managed volume,在执行docker rm时可以带上-v参数,docker会将容器使用到的volume一并删除,但前提是没有其他容器mount该volume。也可以用docker volume ls来查看当前的volume,docker volume rm来删除遗留下来的volume。如果想要批量删除遗留的volume,可以使用以下命令

    docker volume rm $(docker volume ls -q)
  • 相关阅读:
    安卓学习第三课——常见布局
    安卓学习第二课——短信发送器
    POJ3735【矩阵快速幂】
    Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)【A,B,C,D】
    POJ3737【数学】
    HDU2489【状压枚举】
    POJ3734【状压枚举】
    HDU1598【最小生成树拓展】
    HDU1597【二分瞎搞】
    HDU3279【水】
  • 原文地址:https://www.cnblogs.com/chenjin2018/p/9840649.html
Copyright © 2020-2023  润新知