zoukankan      html  css  js  c++  java
  • 理解 docker volume


    1. docker volume 简介

    文章 介绍了 docker image,它由一系列只读层构成,通过 docker image 可以提高镜像构建,存储和分发的效率,节省时间和存储空间。然而 docker image 还是存在一些问题,如下:

    • 多个容器之间的数据无法共享。
    • 当删除容器时,容器产生的数据将丢失。

    基于这几点 Docker 引入了 volume 机制。 volume 是存在于一个或多个容器中的特定文件或文件夹,这个目录以独立于联合文件系统的形式在宿主机上存在。volume 机制的主要优点如下:

    • volume 能在不同容器间共享数据。
    • volume 的生存周期独立于容器,删除容器,volume 依然存在。
    • volume 中数据的操作不会影响到镜像。

    2. 创建 volume

    创建 volume,将 volume attach 到容器中,删除容器,查看 volume 的使用情况。

    查看创建 volume 使用的驱动:

    [root@k8s-master-node-1 centos]# docker info | grep -i volume
      Volume: local
    

    创建 volume:

    [root@k8s-master-node-1 centos]# docker volume create chunqiu
    chunqiu
    [root@k8s-master-node-1 centos]# docker volume inspect chunqiu
    [
        {
            "CreatedAt": "2021-05-10T09:09:49Z",
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/chunqiu/_data",
            "Name": "chunqiu",
            "Options": {},
            "Scope": "local"
        }
    ]
    

    volume 在宿主机上的目录 (Mountpoint) 是 /var/lib/docker/volumes/<volume_name>/_data。将 volume attach 到容器 ubuntu 上:

    [root@k8s-master-node-1 centos]# docker run -it -v chunqiu:/data --name=ubuntu ubuntu /bin/bash
    root@8c4611b025f6:/# ls /data/
    root@8c4611b025f6:/#
    

    使用 -v 选项将 volume attach 到容器内,并指定容器的目录为 /data。写文件到 data 目录:

    /* 容器内写文件 */
    root@8c4611b025f6:/# cd data/
    root@8c4611b025f6:/data# touch chunqiu
    
    [root@k8s-master-node-1 _data]# ls -l /var/lib/docker/volumes/chunqiu/_data/
    total 0
    -rw-r--r-- 1 root root 0 May 10 09:44 chunqiu
    
    /* 容器外写文件 */
    [root@k8s-master-node-1 _data]# touch handsomeBoy
    
    root@8c4611b025f6:/data# ls -l
    total 0
    -rw-r--r-- 1 root root 0 May 10 09:44 chunqiu
    -rw-r--r-- 1 root root 0 May 10 09:49 handsomeBoy
    

    容器和宿主机上目录建立映射。删除容器,查看 volume 是否存在:

    [root@k8s-master-node-1 _data]# docker rm ubuntu
    ubuntu
    
    [root@k8s-master-node-1 _data]# ls -l
    total 0
    -rw-r--r-- 1 root root 0 May 10 09:44 chunqiu
    -rw-r--r-- 1 root root 0 May 10 09:49 handsomeBoy
    

    删除容器 volume 依然存在。

    3. volume 与 image

    探索 volume 与 image 的关系,volume 映射的文件/文件夹会反映在“读写层”,和静态的 image 没有关系。当 volume 映射的文件/文件夹和 image 同名时,image 中内容将被隐藏,从而保持 volume 和宿主机上文件/文件夹的一致性。

    创建 volume 映射到容器内的 /home 目录,查看 home 目录下文件变化情况:

    [root@k8s-master-node-1 _data]# docker run -it b9fd190d76e0 /bin/bash
    root@c536d00399fa:/# ls
    bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    root@c536d00399fa:/# ls home/
    demo
    root@c536d00399fa:/home# exit
    
    [root@k8s-master-node-1 _data]# docker run -it -v chunqiu:/home b9fd190d76e0 /bin/bash
    root@faebe07c5405:/# cd home/
    root@faebe07c5405:/home# ls
    chunqiu  handsomeBoy
    

    home 目录下的 demo 文件被隐藏,取而代之的是宿主机上 volume 的 MountPoint 下的文件。

    思考:如果取代的是 /etc 目录会怎么样?

    4. 容器间共享目录

    volume 能在不同容器间共享数据,新建一个容器使它和 ubuntu 共享 volume chunqiu:

    [root@k8s-master-node-1 centos]# docker run -it --volumes-from ubuntu ubuntu /bin/bash
    root@a66c276b1954:/# ls data/
    chunqiu  handsomeBoy
    

    5. docker commit

    将容器 commit 为镜像,容器内的 volume 数据会保存到镜像中吗?做个小实验如下:

    [root@k8s-master-node-1 centos]# docker commit ubuntu
    sha256:e938f5251682f9b48ce344f1372d39b2ef6b7b4b6f8160afa38fe94492de158e
    [root@k8s-master-node-1 centos]# docker image ls | grep e938
    <none>                               <none>              e938f5251682        12 seconds ago      72.7MB
    
    [root@k8s-master-node-1 centos]# docker run -it e938f5251682 /bin/bash
    root@11f74c3587e1:/# ls
    bin  boot  data  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    root@11f74c3587e1:/# ls data/
    root@11f74c3587e1:/data#
    

    可以看到,data 目录下并没有 volume 的文件,这是因为 docker commit 不会对挂载的 volume 进行保存。这也说明了为什么在 dockerfile 中这么写找不到文件 file:

    FROM ubuntu
    RUN useradd foo
    VOLUME /data
    RUN touch /data/file
    RUN chown -R foo:foo /data
    

    6. docker volume 原理

    docker 创建 volume 的过程实际上是在 mount namespace 添加做 mount 操作的过程,具体可看这里了解更多,这里就不做赘述啦~

    芝兰生于空谷,不以无人而不芳。
  • 相关阅读:
    D3.js:交互式操作
    D3.js:Update、Enter、Exit
    D3.js:动态效果
    D3.js:完整的柱形图
    D3.js:坐标轴
    D3.js
    ES 6 : 数组的扩展
    ES 6 : Math对象的扩展
    拉勾网企业图片列表效果
    拉勾网图片切换效果
  • 原文地址:https://www.cnblogs.com/xingzheanan/p/14753242.html
Copyright © 2011-2022 走看看