有没有人有一个 Dockerfile 和命令行的简单示例,可以将外部目录从 linux 挂载到 docker 映像中?

Posted

技术标签:

【中文标题】有没有人有一个 Dockerfile 和命令行的简单示例,可以将外部目录从 linux 挂载到 docker 映像中?【英文标题】:Does anyone have a working trivial example of a Dockerfile & command line that mount an external directory from linux into the docker image? 【发布时间】:2015-06-03 06:12:14 【问题描述】:

我正在寻找的只是 Dockerfile 和 docker build+run 命令在 linux 上通过容器内的挂载点查看 /var/tmp。这里的问题都是复杂的情况,或者涉及 OS/X 和 Windows,或者尝试做的不仅仅是简单地挂载卷。我的情况是,我只是尝试将 /var/tmp 挂载到 一个busybox镜像的/foobar,用这个镜像运行一个容器,然后使用“ls /foobar”来查看内容。

在带有 aufs 的 linux 4.0.1 上运行“Docker 版本 1.6.1,构建 97cd073” 使用本地存储库。

http://docs.docker.com/userguide/dockervolumes/

注意:

Mount a Host Directory as a Data Volume

In addition to creating a volume using the 
-v flag you can also mount a directory from 
your Docker daemon's host into a container.

<snip>

$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp 
training/webapp python app.py

This will mount the host directory, /src/webapp, 
into the container at /opt/webapp.

    Note: If the path /opt/webapp already exists 
    inside the container's image, its contents 
    will be replaced by the contents of 
    /src/webapp on the host to stay consistent 
    with the expected behavior of mount

This is very useful for testing, for example we can mount our source 
code inside the container and see our application at work as we change 
the source code. The directory on the host must be specified as an 
absolute path and if the directory doesn't exist Docker will 
automatically create it for you.

我正在使用获取其“/data”目录的本地存储库 通过“-v”切换到 docker run:

docker run -d -p 5000 \
-v '/var/lib/docker/registry:/data/registry/storage' \
'kampka/registry';

这似乎是主机的 /var/lib/docker/registry 目录 获取添加到其中的条目。

所以我为自己尝试了一个简单的测试:构建一个busybox的最小副本 可以访问主机系统上的 /var/tmp。

FROM        localhost:5000/lembark/busybox
MAINTAINER  lembark@wrkhors.com

VOLUME  [ "/foobar" ]

ENV     PATH /bin
WORKDIR /

ENTRYPOINT  [ "/bin/sh" ]

此时运行“docker build”会执行 VOLUME 命令,但不会创建挂载点:

$ docker build --tag="localhost:5000/lembark/hak" . ;

Sending build context to Docker daemon  7.68 kB
Sending build context to Docker daemon
Step 0 : FROM localhost:5000/lembark/busybox
 ---> c1a1f5abbf79
Step 1 : MAINTAINER lembark@wrkhors.com
 ---> Using cache
 ---> b46677881767
Step 2 : VOLUME /foobar
 ---> Running in 7127bdbcfb56
 ---> bcf9c3f1c441
Removing intermediate container 7127bdbcfb56
Step 3 : ENV PATH /bin
 ---> Running in 89f92c815860
 ---> 780fea54a67f
Removing intermediate container 89f92c815860
Step 4 : WORKDIR /
 ---> Running in aa3871c408a1
 ---> 403190e9415b
Removing intermediate container aa3871c408a1
Step 5 : ENTRYPOINT /bin/sh
 ---> Running in 4850561f7ebd
 ---> 77c32530b4a9
Removing intermediate container 4850561f7ebd
Successfully built 77c32530b4a9

第 2 步中的“VOLUME /foobar”似乎表明一个挂载点 应该在运行时可用。

此时使用任一

docker run --rm -t -i                     localhost:5000/lembark/hak;
docker run --rm -t -i -v /foobar          localhost:5000/lembark/hak;
docker run --rm -t -i -v /var/tmp:/foobar localhost:5000/lembark/hak;

留给我:

# ls -al /foobar
ls: /foobar: No such file or directory

在 VOLUME 之前添加 mkdir 会给我留下 /foobar 具有匿名卷的目录,而不是来自 /var/tmp 的映射:

...

RUN     [ "mkdir", "/foobar" ]
VOLUME  [ "/foobar" ]

# made a local ./foobar directory, added that to the image.

COPY    [ "foobar", "/foobar" ]

其中的 Bofh 使用 /foobar,但无法映射任何外部 目录到它。相反,我不断收到匿名卷:

 # mount | grep foobar;
 /dev/mapper/vg00-var--lib on /var/lib/docker/aufs/mnt/dd12f3e11a6fcb88627412a041b7c910e4d32dc1bf0c15330899036c59d7b3d9/foobar type xfs (rw,noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,logdev=/dev/vg02/var-lib-extlog,noquota)

无论是否组合 mkdir、VOLUME、COPY 或 -v,我都无法查看 /var/tmp undef /foobar。

谢谢

【问题讨论】:

【参考方案1】:

这对我有用

Dockerfile

FROM busybox:latest
VOLUME /foo/bar

命令

$ docker build -t bb .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM busybox:latest
 ---> 8c2e06607696
Step 1 : VOLUME /foo/bar
 ---> Running in a94615dd3353
 ---> fa500ba91831
Successfully built fa500ba91831
$ docker run -it -v /tmp:/foobar bb ls /foobar
[contents of my /tmp directory]

请注意,您不需要VOLUME 命令来执行此操作。 docker run -it -v /tmp:/foobar busybox:latest ls /foobar 也可以。

【讨论】:

尝试在这里获取已安装卷的“没有这样的文件或目录”。 FROM localhost:5000/lembark/busybox VOLUME /var/tmp MAINTAINER lembark@wrkhors.com $ ./build Sending build context to Docker daemon 6.656 kB Sending build context to Docker daemon ... Step 1 : VOLUME /var/tmp ---&gt; Running in bebc1b347b4e ---&gt; 328a76d7eee3 ... Successfully built 8d8f2c71aae3 $ docker run -v /var/tmp:/var/tmp localhost:5000/lembark/frobnicate ls /var/tmp ls: /var/tmp: No such file or directory 向 Dockerfile 添加“mkdir”、“/va/rtmp”后,我就可以匿名存储卷,而不是查看 /var/tmp。 你的本地机器上真的有 /var/tmp 吗?是可以访问的普通目录吗? 是的。目前已安装带 mods 01777。 是的。 /var/tmp 安装有 mods 01777 并且有内容; /lib64 (我尝试安装的原始目录)具有 mods 02775 并已填充。 `$ ls -ld /var/tmp; drwxrwxrwt 21 root root 880 Jun 3 04:05 /var/tmp $ ls /var/tmp|head -2 15PvaS0xyv 23611 '【参考方案2】:

我和@Nathaniel Waisbrot 做了同样的事情。

vagrant@vagrant:/code/busybox$ ls
Dockerfile
vagrant@vagrant:/code/busybox$ docker build -t busybox:0.0.1 .
Sending build context to Docker daemon 9.216 kB
Sending build context to Docker daemon
Step 0 : FROM busybox:latest
---> 8c2e06607696
Step 1 : VOLUME /foobar
---> Running in 0b99eac833aa
---> a93b5ae5de5f
Removing intermediate container 0b99eac833aa
Successfully built a93b5ae5de5f
vagrant@vagrant:/code/busybox$ docker run -i -v /code/busybox/:/foobar busybox:0.0.1 ls /foobar
Dockerfile
vagrant@vagrant:/code/busybox$

这是我用来构建镜像的 Dockerfile。

FROM        busybox:latest

VOLUME  [ "/foobar" ]

在这里您可以看到我列出了我的/code/busybox 目录以向您显示其中的文件。 然后我构建图像。 然后我运行图像并将我的/code/busybox 目录映射到图像/foobar 目录与-v /code/busybox:/foobar。 然后我执行我用 ls 命令构建的图像和我想列出的目录ls /foobar。 结果将打印到控制台。

为了清楚起见,我认为您的操作存在一些问题。这就是您看不到文件的原因。

FROM        localhost:5000/lembark/busybox
MAINTAINER  lembark@wrkhors.com

VOLUME  [ "/foobar" ]

ENV     PATH /bin
WORKDIR /

ENTRYPOINT  [ "/bin/sh" ]

您正在从 PC 上的图像创建图像。那个图是什么来的。这可能是一个问题,因为您正在构建的图像从该图像继承了它的基本属性和 O/S。 WORKDIR 命令设置工作目录。由于您没有导入任何内容,因此您不需要此命令。 您通过将 ENTRYPOINT 设置为 ['/bin/sh'] 来覆盖每次初始化容器时执行的 ENTRYPOINT 或命令。这可能是您的命令未执行的原因。您运行容器,然后执行该入口点。

请看上面的例子。这是一个正确的 Dockerfile,将编译并提供上面列出的控制台输出,并完全按照您的要求进行操作。如果没有看到您正在构建最新镜像的镜像的 Dockerfile,就很难准确地确定您还有哪些不正确的部分。

【讨论】:

以上是关于有没有人有一个 Dockerfile 和命令行的简单示例,可以将外部目录从 linux 挂载到 docker 映像中?的主要内容,如果未能解决你的问题,请参考以下文章

dockerfile动态修改服务配置文件

dockerfile动态修改服务配置文件

awknawkmawkgawk的简答介绍

userdel的简答用法

docker 在没有dockerfile的情况下 如何查看一个运行容器的启动命令

有很多行的表上的基本选择非常慢