如何在不覆盖现有文件的情况下重新安装docker卷?

时间:2017-01-17 12:49:53

标签: docker dockerfile

运行Docker时,可以使用--volume选项挂载文件和目录。 E.g:

docker run --volume /remote ./local myimage

我正在运行一个在Dockerfile中定义VOLUMES的docker镜像。我需要访问恰好位于其中一个已定义卷中的配置文件。我想要那个文件&#34;同步&#34;在主机上,以便我可以编辑它。我知道我可以运行docker exec ...,但我希望绕过仅编辑一个文件的开销。我发现VOLUMES行创建的卷存储在/var/lib/docker/volumes/<HASH>/_data

使用docker inspect我能够找到挂载的目录:

docker inspect gitlab-runner | grep -B 1 '"Destination": "/etc/gitlab-runner"' | head -n 1 | cut -d '"' -f 4

输出:

  

的/ var / lib中/搬运工/体积/ 9c233c085c36380c6c33035222c16e5d061368c5060cc81dda2a9a713a2b2b3b / _data

所以问题是:

有没有办法重新安装图像中定义的卷?或者以某种方式让目录比上面的oneliner更容易?

zeppelin发表评论后,

编辑我尝试重新调整音量但没有成功:

$ mkdir etc

$ docker run -d --name test1 gitlab/gitlab-runner
$ docker run -d --name test2 -v ~/etc:/etc/gitlab-runner gitlab/gitlab-runner

$ docker exec test1 ls /etc/gitlab-runner/
certs
config.toml

$ docker exec test2 ls /etc/gitlab-runner/
# empty. no files
$ ls etc
# also empty

docker inspect正确显示卷已绑定到~/etc,但/etc/gitlab-runner/容器内的文件似乎丢失了。

3 个答案:

答案 0 :(得分:1)

$ docker run -d --name test1 gitlab/gitlab-runner
$ docker run -d --name test2 -v ~/etc:/etc/gitlab-runner gitlab/gitlab-runner

你有两种不同的卷类型。我称之为匿名卷(当你运行docker volume ls时,可以看到很长的uuid)。第二个是主机卷或绑定装载,它将主机上的目录直接映射到容器中。所以你旋转的每个容器都在寻找不同的地方。

匿名卷和命名卷(docker run -d -v mydata:/etc/gitlab-runner gitlab/gitlab-runner)初始化为该目录位置的图像内容。此初始化仅在卷为空并且装入新容器时发生。正如您所见,主机卷只获取主机文件系统的内容,即使它在该位置是空的。

在这样的背景下,对您的问题的简短回答是否定的,您无法将容器中的文件挂载回主机。但是,您可以使用多种方法复制文件,假设您没有使用主机卷装置覆盖文件的源。使用正在运行的容器,有docker cp命令。就个人而言,我喜欢:

docker run --rm -v ~/etc:/target gitlab/gitlab-runner \
  cp -av /etc/gitlab-runner/. /target/.

如果您有一个包含要复制或复制的数据的命名卷,则可以使用任何图像以及复制所需的工具:

docker run --rm -v mydata:/source -v ~/etc:/target busybox \
  cp -av /source/. /target/.

答案 1 :(得分:1)

尽量避免直接从主机修改容器内的数据,当你将任务包装到另一个容器中时更好,然后在你的情况下以“--volumes-from”选项开头。

答案 2 :(得分:0)

无论如何,我不确定你理解你的问题,就你提到的文件而言,

  

VOLUME指令创建具有指定名称的安装点   并将其标记为从本机主机或外部保存外部安装的卷   其他容器。 [...] docker run命令初始化新的   使用指定位置存在的任何数据创建卷   在基本图像中。

因此,在构建图像之后example Dockerfile之后

docker build -t mytest .

让容器运行

docker run -d -ti --name mytestcontainer mytest /bin/bash

您可以从容器本身访问它,例如

docker exec -ti mytestcontainer ls -l /myvol/greeting
docker exec -ti mytestcontainer cat /myvol/greeting

希望它有所帮助。