zoukankan      html  css  js  c++  java
  • Docker数据卷

    Docker数据卷

    1.数据卷介绍

    数据卷简单的来说就是一个目录,它是由docker daemon挂载到容器中的,因此数据卷并不属于联合文件系统。也就是说数据卷是不会随着容器的丢失而丢失的。就像我们将U盘插到计算机,即使计算机的硬盘坏了,也不会影响U盘里面的数据。因此在使用docker commit提交时并不会把数据卷里面的数据提交到镜像中。

    2.数据卷容器介绍

    如果让两个容器共享一个数据卷,最快的办法是将数据卷挂载到两个容器上面即可。

    3.挂载数据卷

    docker run 或者是docker create命令时,可以指定-v参数来添加数据卷,并且这个参数可以用多次,可以挂载多个数据卷。

    el:

    $docker run -d -v /vol --name volume bonc:5000/busybox:v1

     

    我们现在已经为容器volume挂载了一个数据卷,位置是/vol

    但是这样我们不易管理,可以使用docker inspect来查看数据卷的位置:

    "Mounts": [

    {

    "Type": "volume",

    "Name": "3b1e12ca553a462526c9079e5ea95869af7b93ca98ca7f5497624c7f9ab8f00f",

    "Source": "/var/lib/docker/volumes/3b1e12ca553a462526c9079e5ea95869af7b93ca98ca7f5497624c7f9ab8f00f/_data",

    "Destination": "/vol",

    "Driver": "local",

    "Mode": "",

    "RW": true,

    "Propagation": ""

    }

    ],

    如果删除容器 :

    $docker rm –f volume

    再去查看数据卷目录会发现,数据卷还是存在的。虽然数据还是存在,但是我们的这样子做超级麻烦。

     

     

    下面我们用简单的方式去解决这个问题,我们通过使用映射目录就可以方便的解决这个问题。

    $ docker run -d -v /vol:/vol--name=volume bonc:5000/busybox:v1
    目前数据卷存储在宿主机的/vol,不用去担心数据卷的丢失。数据卷的路径必须是绝对路径,另外删除数据卷时可以指定docker rm –v <container ID>

    4.挂载数据卷容器

    在上面的挂载数据卷虽然很好的解决了数据持久化的问题,但是在迁移上面还是很麻烦的。例如多个容器之间的共享数据需要迁移时,使用挂载宿主机的文件夹的方法迁移起来显得很麻烦。所以为了方便起见,我们可以启一个容器来专门负责存放数据

        $ docker run -it -v /var/lib/mysql --name=mysql_volume mysql /bin/true

    上面就启动了一个数据卷容器,/bin/true是为了覆盖原有进程并防止容器退出

    然后启动其他容器容器并挂载数据卷容器

        $ docker run -d --volumes-from mysql_volume --name db1 mysql

        $ docker run -d --volumes-from mysql_volume21 --name db2 mysql

    甚至可以通过db1来挂载到后续启动的容器中:

        $ docker run -d --volume-from db1 --name db4 mysql

    这样删除上面4个容器中的3个,数据卷也 不会丢失,即使四个都丢失了,但是还会保存在/var/lib/docker/volume/的某个目录下,这事先通过docker inspect 命令来查看volume ID.

    综上所述,docker volume 并不是特别好用。 在挂载的时候一定要注意,避免以后的数据找不到。

    还有补充的就是如果删除一个一个含有挂载数据卷的容器,在删除时没有用-v,则这些数据卷会成为dangling状态

        $ docker volume ls -f dangling=true #查看所有没有挂载到容器上的数据卷

    删除dangling状态的数据。

        $docker volume rm <volume NAME>

    >>>>>>>>>>>>小结<<<<<<<<<<<<<<<<

    为了更直观的了解数据卷的挂载操作,做实验。

    1.将本地宿主机不存在的文件挂载到容器中,而容器中存在,发现失败了

    $ docker run --name=test -v ~/test.txt:/etc/hosts -d httpd #这里启动容器失败

    报错:

    /usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:364: container init caused "rootfs_linux.go:54: mounting \"/root/test.txt\" to rootfs \"/var/lib/docker/overlay2/549a2539ade911b73d6025bcf17bd91de98379ef21099f63edefead57863703e/merged\" at \"/var/lib/docker/overlay2/549a2539ade911b73d6025bcf17bd91de98379ef21099f63edefead57863703e/merged/etc/hosts\" caused \"not a directory\"""

    : Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type.

    2.将本地不存在的文件夹挂载到容器的文件夹中。bonc:5000/busybox:v1镜像中存在一个/srv的文件夹,在文件夹有一个index.php文件。

        $ docker run -d --name=test14 -v ~/srv:/srv bonc:5000/busybox:v1

        最后发现容器启动成功了。

    上面两个实验告诉我们,数据卷的挂载是通过把本地的目录覆盖到容器中的。也就是说宿主机文件不存在时,不能挂载;当文件夹不存在时,挂载到容器会用一个空文件夹覆盖容器原有的目录。

     

    3.继续假设宿主机存在文件,容器内部存在该文件:

        $ docker run -d --name=a23 -v ~/a.txt:/srv/a.txt -d docker.io/domeos/openfalcon-domeos:0.5 #假设本地文件a.txt是存在的

    4.接下来是宿主机存在文件夹,容器不存在文件夹,宿主机的a文件夹里面存在一个hello文件

        $ docker run --name=b99 -v ~/a:/srv/a -d docker.io/domeos/k8s-domeos:1.4.7 #容器启动成功

        $ docker exec -it b99 sh #进入容器

        $cd /srv/a

        $ls

        Hello

        上面这两个例子说明:

    如果容器内不存在文件,宿主机可直接挂载。

    5.接下来继续测试,如果容器内存在文件夹b,宿主机内存在文件夹b。这样挂载结果如下:

        $ docker run --name=y77 -v ~/b:/svr/b -d docker.io/domeos/k8s-domeos:1.4.7

    会报错,容器启动失败。

    6.假设宿主机是文件夹,容器也是文件夹,两个文件夹里面的内容不一样,宿主机内部是hello文件,容器文件夹里面是index.php:

    $ docker run --name=c9 -v ~/a:/srv/b -d b:latest #能正确的启动

     

    ______________________综上所述___________________________

    根据上面的6个实验,不难总结出一个规律:

    宿主机文件

    容器内文件

    启动参数(加粗表示不存在)

    容器启动情况

    不存在

    文件

    -v ~/test.txt:/etc/hosts

    启动错误

    不存在

    文件夹

    -v ~/srv:/srv

    启动正常

    文件

    不存在

    -v ~/test.txt:/srv/test.txt

    启动正常

    文件夹

    不存在

    -v ~/test:/srv/test

    启动正常

    文件夹

    文件

    -v ~/test:/srv/test.txt

    启动错误

    文件夹

    文件夹

    -v ~/test:/srv/test

    启动正常

    文件

    文件

    -v ~/test.txt:/srv/test.txt

    启动正常

    文件

    文件夹

    -v ~/test.txt:/srv/test

    启动错误

     

  • 相关阅读:
    手机端上传图片及java后台接收和ajaxForm提交
    JEECG中datagrid方法自定义查询条件
    微信分享到朋友圈按钮 右上角提示
    Js获取后台集合List的值和下标的方法
    redis系列之数据库与缓存数据一致性解决方案
    替换{0}为指定的字符串(MessageFormat)
    java中对array数组的常用操作
    面试题-Java Web-网络通信
    你应该知道的JAVA面试题
    各大互联网公司java开发面试常问问题
  • 原文地址:https://www.cnblogs.com/cdipp/p/9642439.html
Copyright © 2011-2022 走看看