【问题标题】:What is the purpose of VOLUME in DockerfileDockerfile 中 VOLUME 的用途是什么
【发布时间】:2016-04-20 23:06:42
【问题描述】:

我正在尝试更深入地了解 Docker 的容量,但我很难弄清楚以下方面的差异/用例:

  • docker volume create 命令
  • docker run -v /path:/host_path
  • Dockerfile 文件中的 VOLUME 条目

我特别不明白如果将 VOLUME 条目与 -v 标志结合起来会发生什么。

【问题讨论】:

标签: docker volume


【解决方案1】:

使用来自docker hub的MYSQL:

以运行以下命令为例:

$ docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

命令的 -v /my/own/datadir:/var/lib/mysql 部分从底层主机挂载 /my/own/datadir 目录系统作为容器内的 /var/lib/mysql,默认情况下 MySQL 将写入其数据文件。

因此,在容器被挂载时仍然存在的目录是可用的,它还为某些操作(如数据库操作)提供了更高的性能。

【讨论】:

    【解决方案2】:

    VOLUME 指令与volumes-from 运行时参数结合使用会变得有趣。

    给定以下 Dockerfile:

    FROM busybox
    VOLUME /myvolume
    

    使用以下方法构建映像:

    docker build -t my-busybox .
    

    然后启动一个容器:

    docker run --rm -it --name my-busybox-1 my-busybox
    

    首先要注意的是,这张图片中有一个名为myvolume 的文件夹。但这并不是特别有趣,因为当我们退出容器时,卷也会被移除。

    在此文件夹中创建一个空文件,因此在容器中运行以下命令:

    cd myvolume
    touch hello.txt
    

    现在启动一个新容器,但与 my-busybox-1 共享同一个卷:

    docker run --rm -it --volumes-from my-busybox-1 --name my-busybox-2 my-busybox
    

    您将看到my-busybox-2myvolume 文件夹中包含文件hello.txt

    退出两个容器后,该卷也将被删除。

    【讨论】:

    • 这些卷将被删除,因为它们是匿名卷并且您使用--rm 选项启动了这些容器。我认为它可能会提到它。如果您没有使用--rm 启动容器,您仍然可以使用docker rm -v my-container 删除容器及其匿名卷
    【解决方案3】:

    @radium226

    1. 在 Dockerfile 中指定 VOLUME 可确保在运行时将文件夹视为卷(即容器外部),而不是容器内的常规目录。请注意对性能和可访问性的影响。
    2. 如果忘记在“docker run”命令行中指定“-v”,上述情况仍然成立。只是卷名变得匿名。但仍有一些方法可以访问或从此类匿名卷中恢复数据。

    【讨论】:

      【解决方案4】:

      卷是存储在/var/lib/docker/volumes/...中的持久数据

      • 您可以在 Dockerfile 中声明它,这意味着每次从映像启动容器时,都会创建卷(),即使您没有任何-v 选项。

      • 您可以在运行时声明它docker run -v [host-dir:]container-dir
        将两者结合起来(VOLUME + docker run -v)意味着您可以将主机文件夹的内容挂载到由/var/lib/docker/volumes/...中的容器保存的卷中

      • docker volume create 无需定义 Dockerfile 并构建映像和运行容器即可创建卷。用于快速允许其他容器挂载该卷。

      如果您在卷中保留了一些内容,但此后删除了该容器(默认情况下不会删除其关联的卷,除非您使用 docker rm -v),您可以将所述卷重新附加到新的容器(声明相同的卷)。

      见“Docker - How to access a volume not attached to a container?”。
      使用 docker volume create,很容易将命名卷重新附加到容器。

      docker volume create --name aname
      docker run -v aname:/apath --name acontainer
      ...
      # modify data in /apath
      ...
      docker rm acontainer
      
      # let's mount aname volume again
      docker run -v aname:/apath --name acontainer
      ls /apath
      # you find your data back!
      

      【讨论】:

      • 假设您使用 DockerfileVOLUME-v /path:/host_path/ 标志。 VOLUME 的内容将被/host_path/ 的内容覆盖?
      • 感谢@VonC,我想我明白了 :) 如果您执行docker volume create --name my_volume 后跟docker run --volume-from my_volume,您怎么知道挂载点在哪里?
      • @radium226 没有挂载点(意味着没有从主机挂载,除了本机空的 /var/lib/docker/volume 之外)。卷的路径在 my_volume 元数据中:stackoverflow.com/a/31997267/6309
      • 我了解主机端没有挂载点。但是在使用docker run ... 启动的运行容器中,如何写入存储在my_volume 卷上的文件?我不知道...路径?我正在运行的容器内的体积,因为我什么都没定义?我希望我足够清楚,因为我绝对不确定我的发音:-/
      • @radium226 docker volume create --name aname 创建一个 named 卷:您在运行时分配一个 container 路径:docker run -v aname:/apath:该容器现在有一个附加到它的卷,安装到它的 /apath 文件夹。我已经重写了答案以明确这一点。
      猜你喜欢
      • 1970-01-01
      • 2018-09-12
      • 1970-01-01
      • 2021-03-10
      • 1970-01-01
      • 1970-01-01
      • 2017-02-06
      • 2012-06-03
      相关资源
      最近更新 更多