热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

了解DockerFile中的"VOLUME"指令

如何解决《了解DockerFile中的"VOLUME"指令》经验,为你挑选了5个好方法。

以下是我的"Dockerfile"的内容

FROM node:boron

# Create app directory
RUN mkdir -p /usr/src/app

# change working dir to /usr/src/app
WORKDIR /usr/src/app

VOLUME . /usr/src/app

RUN npm install

EXPOSE 8080

CMD ["node" , "server" ]

在这个文件中,我期待"VOLUME./ usr/src/app"指令将主机中当前工作目录的内容挂载到容器的/ usr/src/app文件夹中.

如果这是正确的方法,请告诉我?



1> Martin Ander..:

简而言之:不,你的VOLUME指示不正确.

Dockerfile VOLUME指定给定容器端路径的一个或多个卷.但它不允许图像作者指定主机路径.在主机端,在Docker根目录中创建的卷具有非常长的ID类名称.在我的机器上这是/var/lib/docker/volumes.

注意:因为自动生成的名称非常长并且从人的角度来看没有意义,所以这些卷通常被称为"未命名"或"匿名".

你使用'.'的例子.无论我是否将点作为第一个或第二个参数,角色甚至都不会在我的机器上运行.我收到此错误消息:

docker:来自守护进程的错误响应:oci运行时错误:container_linux.go:265:启动容器进程导致"process_linux.go:368:容器init导致"打开/ dev/ptmx:没有这样的文件或目录\"".

我知道,对于那些试图理解的人而言,对于这一点所说的内容可能并不是很有价值VOLUME,-v而且它肯定不能为你想要完成的事情提供解决方案.因此,希望以下示例能够更好地阐述这些问题.

Minitutorial:指定卷

鉴于此Dockerfile:

FROM openjdk:8u131-jdk-alpine
VOLUME vol1 vol2

(对于这个小型教程的结果,如果我们指定vol1 vol2或者/vol1 /vol2- 不要问我原因,它没有任何区别)

建立它:

docker build -t my-openjdk

跑:

docker run --rm -it my-openjdk

在容器内,运行ls,你会发现存在两个目录; /vol1/vol2.

运行容器还会在主机端创建两个目录或"卷".

让容器运行时,docker volume ls主机上执行,你会看到类似的东西(为了简洁起见,我用两个点替换了名称的中间部分):

DRIVER    VOLUME NAME
local     c984...e4fc
local     f670...49f0

回到容器中,执行touch /vol1/weird-ass-file(在所述位置创建一个空白文件).

此文件现在可在主机上的一个未命名卷lol中使用.我花了两次尝试,因为我第一次尝试了第一个列出的卷,但最终我确实在第二个列出的卷中找到了我的文件,在主机上使用此命令:

sudo ls /var/lib/docker/volumes/f670...49f0/_data

同样,您可以尝试在主机上删除此文件,它也将在容器中删除.

注意:该_data文件夹也称为"安装点".

退出容器并列出主机上的卷.他们走了.我们--rm在运行容器时使用了该标志,这个选项不仅有效地消除了退出时的容器,还消除了卷.

运行新容器,但使用-v以下命令指定卷:

docker run --rm -it -v /vol3 my-openjdk

增加了第三个卷,整个系统最终有三个未命名的卷.如果我们只指定了命令就会崩溃-v vol3.参数必须是容器绝对路径.在主机端,新的第三卷是匿名的,并与其他两个卷一起驻留./var/lib/docker/volumes/

前面已经说过,Dockerfile在运行时尝试将文件从主机引入容器时,无法映射到主机路径,这对我们造成了问题.不同的-v语法解决了这个问题.

想象一下,我的项目目录./src中有一个子文件夹,我希望/src在容器内同步.这个命令可以解决问题:

docker run -it -v $(pwd)/src:/src my-openjdk

:角色的两边都需要绝对的路径.左侧是主机上的绝对路径,右侧是容器内的绝对路径.pwd是一个"打印当前/工作目录"的命令.将命令放入$()括号内的命令,在子shell中运行它并返回到项目目录的绝对路径.

把它们放在一起,假设我们./src/Hello.java在主机上的项目文件夹中有以下内容:

public class Hello {
    public static void main(String... ignored) {
        System.out.println("Hello, World!");
    }
}

我们构建这个Dockerfile:

FROM openjdk:8u131-jdk-alpine
WORKDIR /src
ENTRYPOINT javac Hello.java && java Hello

我们运行这个命令:

docker run -v $(pwd)/src:/src my-openjdk

这打印出"Hello,World!".

最好的部分是我们可以完全自由地修改.java文件,并在第二次运行时为另一个输出修改新消息 - 无需重建图像=)

最后的评论

我对Docker很陌生,前面提到的"教程"反映了我从一个为期3天的命令行黑客马拉松收集到的信息.我几乎感到惭愧我无法提供链接来清除支持我的陈述的英文文档,但老实说,我认为这是由于缺乏文档而不是个人努力.我知道这些示例的工作原理是使用我当前的设置,即"Windows 10 - > Vagrant 2.0.0 - > Docker 17.09.0-ce".

本教程没有解决问题"我们如何在Dockerfile中指定容器的路径,让run命令只指定主机路径".可能有办法,我还没有找到它.

最后,我有一种直觉,认为VOLUME在Dockerfile 中指定并不常见,但它可能是永远不会使用的最佳做法VOLUME.有两个原因.我们已经确定的第一个原因:我们无法指定主机路径 - 这是一件好事,因为Dockerfiles应该与主机的细节非常不相关.但第二个原因是人们可能忘记--rm在运行容器时使用该选项.有人可能记得要移除容器但忘记移除卷.此外,即使拥有最佳的人类记忆,也可能需要确定哪些匿名卷可以安全删除.


@Martin非常感谢你.你的黑客马拉松及其产生的教程非常有用.
"我无法提供清除类似英文文档的链接......老实说,我认为这是由于缺乏文档".我可以证实.这是我发现的最全面,最新的文档,我一直在寻找.
`docker volume prune`可以用于清除未连接到正在运行的容器的剩余卷。并不是说仅凭id就能识别潜在的重要信息很容易...
我们什么时候应该使用未命名/匿名卷?

2> Bukharov Ser..:

官方码头教程告诉:

数据卷是绕过Union文件系统的一个或多个容器中的特殊指定目录.数据卷为持久性或共享数据提供了几个有用的功能:

创建容器时初始化卷.如果容器的基本映像包含指定安装点的
数据,则在卷
初始化时将现有数据复制到新卷中.(请注意,安装主机
目录时不适用.)

可以在容器之间共享和重用数据卷.

直接对数据卷进行更改.

更新映像时,不会包括对数据卷的更改.

即使删除容器本身,数据量仍然存在.

进入Dockerfile您只能容器指定卷的目的地.例如/usr/src/app.

当您运行容器时,docker run --volume=/opt:/usr/src/app my_image可以但不必在主机中指定安装点(/ opt).如果未指定--volume参数,则将自动选择安装点



3> mr haven..:

a中的VOLUME命令Dockerfile相当合法,完全是常规的,使用起来绝对好,而且无论如何也不会过时。只需要了解它。

我们使用它来指向容器中应用程序将写入很多目录。我们VOLUME不仅仅因为我们想像配置文件一样在主机和容器之间共享。

该命令只需要一个参数。相对于WORKDIR容器(如果已设置)的文件夹路径。然后docker将在其graph(/ var / lib / docker)中创建一个卷并将其安装到容器中的文件夹中。现在,该容器将可以在某处写入高性能文件。如果没有该VOLUME命令,则写入指定文件夹的速度将非常慢,因为现在容器copy on write在容器本身中正在使用其策略。该copy on write策略是存在卷的主要原因。

如果在VOLUME命令指定的文件夹上挂载,则命令永远不会运行,因为VOLUME仅在容器启动时才执行,就像ENV

基本上,使用VOLUME命令您无需外部装入任何卷即可获得性能。数据也将保存在整个容器运行中,而无需任何外部安装。然后,准备好后,只需在其上安装一些东西即可。

一些很好的示例用例:
-日志
-临时文件夹

一些不好的用例:
-静态文件
-配置
-代码



4> BMitch..:

VOLUME在Dockerfile中指定一行会在图像上配置一些元数据,但是如何使用该元数据很重要。

首先,这两行做了什么:

WORKDIR /usr/src/app
VOLUME . /usr/src/app

WORKDIR如果该目录不存在,该行将创建目录,并更新一些图像元数据以指定所有相对路径,以及命令的当前目录(例如RUN将位于该位置)。VOLUME那里的行指定了两个卷,一个是相对路径.,另一个是/usr/src/app,这两个卷恰好是同一目录。通常,该VOLUME行仅包含一个目录,但可以包含多个目录,也可以是json格式的数组。

您无法在Dockerfile中指定卷源:在Dockerfile中指定卷时,常见的混乱原因是试图在映像构建时匹配源和目标的运行时语法,这将不起作用。Dockerfile只能指定卷的目的地。如果有人可以定义卷的源,这将是一个微不足道的安全漏洞,因为他们可以更新docker hub上的公共映像以将根目录安装到容器中,然后在容器内部启动后台进程作为入口点的一部分,将登录名添加到/ etc / passwd,将systemd配置为在下次重新启动时启动比特币矿工,或者在文件系统中搜索信用卡,SSN和私钥以发送到远程站点。

VOLUME系列有什么作用?如前所述,它设置一些图像元数据来表示图像内的目录是一个卷。该元数据如何使用?每次从该映像创建容器时,docker都会将该目录强制为卷。如果您在run命令或撰写文件中未提供卷,则docker的唯一选择是创建一个匿名卷。这是一个本地命名卷,其名称具有唯一的长ID,并且没有其他说明其创建原因或包含哪些数据的信息(匿名卷是数据丢失的原因)。如果覆盖该卷,则指向命名卷或主机卷,则数据将转到该卷。

VOLUME破坏了事情:一旦在Dockerfile中定义了卷,就无法禁用它。更重要的是,RUNdocker中的命令是使用临时容器实现的。这些临时容器将获得一个临时匿名卷。该匿名卷将使用您的图像内容进行初始化。您的RUN命令在容器内进行的任何写入都将写入该卷。当RUN命令完成时,更改图像被保存,并以匿名的体积变化被丢弃。因此,强烈建议您不要VOLUME在Dockerfile 中定义内部。对于希望使用卷位置中的初始数据扩展图像的图像下游用户,这会导致意外的行为。

您应该如何指定音量?要指定要将卷包含在映像中的位置,请提供一个docker-compose.yml。用户可以对其进行修改以将卷的位置调整到其本地环境,并且它可以捕获其他运行时设置,例如发布端口和网络。

有人应该记录下来!他们有。Docker在其关于Dockerfile的文档中包括有关VOLUME使用情况的警告以及在运行时指定源的建议:

从Dockerfile内更改卷:如果在声明了卷后有任何构建步骤更改了卷内的数据,则这些更改将被丢弃。

...

主机目录在容器运行时声明:主机目录(挂载点)从本质上说是依赖于主机的。这是为了保留图像的可移植性,因为不能保证给定的主机目录在所有主机上都可用。因此,您无法从Dockerfile内挂载主机目录。该VOLUME 指令不支持指定host-dir参数。创建或运行容器时,必须指定安装点。



5> Li-Tian..:

为了更好地理解volumedockerfile中的指令,让我们学习mysql官方docker文件实现中的典型卷用法。

VOLUME /var/lib/mysql

参考:https : //github.com/docker-library/mysql/blob/3362baccb4352bcf0022014f67c1ec7e6808b8c5/8.0/Dockerfile

/var/lib/mysql是MySQL存储数据文件的默认位置。

如果仅出于测试目的运行测试容器,则不能指定其安装点,例如

docker run mysql:8

然后mysql容器实例将使用volumedockerfile中的指令指定的默认安装路径。这些卷是在Docker根目录中使用非常长的类似ID的名称创建的,这称为“未命名”或“匿名”卷。在基础主机系统的文件夹/ var / lib / docker / volumes中。

/var/lib/docker/volumes/320752e0e70d1590e905b02d484c22689e69adcbd764a69e39b17bc330b984e4

这对于无需指定安装点的快速测试而言非常方便,但仍可以通过将Volume用于数据存储而不是容器层来获得最佳性能。

对于正式使用,您将需要通过覆盖安装点以使用命名卷来指定安装路径,例如

docker run  -v /my/own/datadir:/var/lib/mysql mysql:8

该命令将基础主机系统中的/ my / own / datadir目录作为/ var / lib / mysql装入容器中。数据目录/ my / own / datadir不会被自动删除,即使容器也被删除了。

mysql官方映像的用法:参考:https : //hub.docker.com/_/mysql/


推荐阅读
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
  • 电脑公司win7剪切板位置及使用方法
    本文介绍了电脑公司win7剪切板的位置和使用方法。剪切板一般位于c:\windows\system32目录,程序名为clipbrd.exe。通过在搜索栏中输入cmd打开命令提示符窗口,并输入clip /?即可调用剪贴板查看器。赶紧来试试看吧!更多精彩文章请关注本站。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • phpcomposer 那个中文镜像是不是凉了 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 本文介绍了在Mac上安装Xamarin并使用Windows上的VS开发iOS app的方法,包括所需的安装环境和软件,以及使用Xamarin.iOS进行开发的步骤。通过这种方法,即使没有Mac或者安装苹果系统,程序员们也能轻松开发iOS app。 ... [详细]
  • 1.直接在cmd窗口运行pipinstalljieba2.使用conda自带的安装工具condainstalljieba3.有一些模块是无法使用以上两种方式安装上ÿ ... [详细]
  • 本文详细介绍了如何创建和使用VUE uni-app开发环境,包括通过HBuilderX可视化界面和通过vue-cli命令执行的方法。文章内容简单清晰,易于学习与理解。通过学习本文,读者可以深入了解VUE uni-app开发环境,并通过实践验证掌握具体的使用情况。编程笔记将为读者推送更多相关知识点的文章,欢迎关注! ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
author-avatar
大叔丶你好哇塞
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有