Docker 添加与音量

Docker ADD vs VOLUME

我正在学习Docker,我对何时何地使用ADDVOLUME有疑问。这是我认为这两者的作用:

添加

在构建时将文件复制到映像。该映像包含所有文件,因此您可以非常轻松地进行部署。另一方面,每次都需要构建在开发中看起来并不是一个好主意,因为构建需要开发人员运行命令来重建容器;此外,构建容器可能很耗时。

音量

我知道使用 docker run -v 您可以在容器中安装主机文件夹,这样您就可以轻松修改文件并观察容器中的应用程序对更改做出反应。它在开发中看起来很棒,但我不确定如何以这种方式部署我的文件。

VOLUME 指令在 运行 时间在您的 Docker 容器中创建了一个数据卷。作为参数提供给 VOLUME 的目录是绕过 Union File System 的目录,主要用于持久和共享数据。

如果你 运行 docker inspect <your-container>,你会看到 Mounts 部分下有一个 Source 代表主机上的目录位置,还有一个 Destination代表容器中挂载的目录位置。例如,

"Mounts": [
  {
    "Name": "fac362...80535",
    "Source": "/var/lib/docker/volumes/fac362...80535/_data",
    "Destination": "/webapp",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
  }
]

以下是 docker run -v 的 3 个用例:

  1. docker run -v /data:这类似于在 Docker 文件中指定 VOLUME 指令。
  2. docker run -v $host_path:$container_path:这允许您在 运行 时间内将 $host_path 从主机挂载到容器中的 $container_path。在开发中,这对于与容器共享主机上的源代码很有用。在生产中,这可用于将主机的 DNS 信息(在 /etc/resolv.conf 中找到)或机密等内容装载到容器中。反过来,你也可以使用这种技术将容器的日志写入宿主机上的特定文件夹中。 $host_path$container_path 都必须是绝对路径。
  3. docker run -v my_volume:$container_path:这会在您的容器中创建一个位于 $container_path 的数据卷并将其命名为 my_volume。它与使用 docker volume create my_volume 创建和命名卷本质上相同。像这样命名卷对于 container data volume and a shared-storage volume using a multi-host storage driver like Flocker.
  4. 很有用

请注意,Dockerfile 中不提供将主机文件夹装载为数据卷的方法。引用 docker documentation,

Note: This is not available from a Dockerfile due to the portability and sharing purpose of it. As the host directory is, by its nature, host-dependent, a host directory specified in a Dockerfile probably wouldn't work on all hosts.

现在,如果您想将文件复制到非开发环境中的容器中,可以在 Docker 文件中使用 ADDCOPY 指令。这些是我通常用于非开发部署的。

添加

这两者之间的根本区别在于 ADD 使您添加的任何内容,无论是文件夹还是文件实际上 图像的一部分 。任何使用您之后构建的图像的人都可以访问您 ADD 的任何内容。即使您之后将其删除也是如此,因为 Docker 在图层中工作并且 ADD 图层仍将作为图像的一部分存在。需要明确的是,您只能在构建时 ADD 某些东西,而不能在 运行 时 ADD

一些您想使用的案例 ADD:

  • 您在 requirements.txt 文件中有一些要求,您希望在 Docker 文件中引用和安装这些要求。然后你可以这样做: ADD ./requirements.txt /requirements.txt 然后是 RUN pip install -r /requirements.txt
  • 你想在你的 Docker 文件中使用你的应用程序代码作为上下文,例如,如果你想将你的应用程序目录设置为图像中的工作目录并让容器 运行 中的默认命令实际上来自您的图像 运行 您的应用程序,您可以这样做:

    ADD ./ /usr/local/git/my_app

    WORKDIR /usr/local/git/my_app

    CMD python ./main.py

音量

另一方面,Volume 只是让您的映像中的容器 运行 可以访问该容器所在的任何本地计算机上的某些路径 运行。您 不能在 Docker 文件 中使用 VOLUME 目录中的文件。卷目录中的任何内容在构建时无法访问,但在运行-time 时可以访问。

一些您希望使用的情况示例 VOLUME:

  • 您容器中 运行 的应用程序会登录 /var/log/my_app。您希望这些日志可以在主机上访问,并且在删除容器时不会被删除。您可以通过将 VOLUME /var/log/my_app 添加到您的 Docker 文件,然后 运行 使用 docker run -v /host/log/dir/my_app:/var/log/my_app some_repo/some_image:some_tag[=61= 连接您的容器,在 /var/log/my_app 创建一个挂载点来完成此操作]
  • 您有一些本地设置文件希望容器中的应用能够访问。也许这些设置文件在您的本地计算机上与开发人员和生产人员不同。特别是如果这些设置文件是秘密的,在这种情况下,您 绝对不希望它们出现在您的图像中 。在这种情况下,一个好的策略是将 VOLUME /etc/settings/my_app_settings 添加到您的 Docker 文件,运行 您的容器 docker run -v /host/settings/dir:/etc/settings/my_app_settings some_repo/some_image:some_tag,并确保 /host/settings/dir 存在于所有环境中您希望您的应用是 运行.