【问题标题】:Why docker in docker (dind) containers mount volumes with host path?为什么docker(dind)容器中的docker使用主机路径安装卷?
【发布时间】:2019-05-01 13:30:24
【问题描述】:

我在 docker 中设置了 docker 并尝试挂载文件夹。

假设我有想要与他的父母共享的文件夹。在主机上,我在 /tmp/dind 中创建了一个名为 foo 的文件。主机启动容器1,容器2启动。这是我想要的结果。

Host      | Container 1 | Container 2

/tmp/dind |  /tmp/dind2 | /tmp/dind3
      <------->     <------->

相反,我得到了

Host      | Container 1 | Container 2

/tmp/dind |  /tmp/dind2 | /tmp/dind3
      <------->
      <----------------------->

代码在这里:

docker run --rm -it \
  -v /tmp/dind:/tmp/dind2 \
  -v /var/run/docker.sock:/var/run/docker.sock docker sh -c \
    "docker run --rm -it \
      -v /tmp/dind2:/tmp/dind3 \
      -v /var/run/docker.sock:/var/run/docker.sock \
      docker ls /tmp/dind3"

这不输出任何内容,而下一个命令给出 foo 作为结果。我更改了挂载的卷:

docker run --rm -it \
  -v /tmp/dind:/tmp/dind2 \
  -v /var/run/docker.sock:/var/run/docker.sock docker sh -c \
    "docker run --rm -it \
      -v /tmp/dind:/tmp/dind3 \
      -v /var/run/docker.sock:/var/run/docker.sock \
      docker ls /tmp/dind3"

问题是,我需要做什么才能使用 Container 1 路径而不是主机?还是我在这里对 docker 有什么误解?

【问题讨论】:

    标签: docker docker-in-docker


    【解决方案1】:

    对于你所说的“Docker-in-Docker”和“dind”,这个设置实际上并不是 Docker-in-Docker:你的 container1 正在向影响 container2 的主机的 Docker 守护进程发出指令。

    Host      Container1
        /-----
     (Docker)
        |     Container2
        \---->
    

    (注意:这个通常是 CI 类型设置的推荐路径。“Docker-in-Docker”通常意味着容器 1 正在运行自己的、独立的 Docker 守护进程,这往往不是推荐。)

    由于 container1 正在向主机的 Docker 发出指令,而主机的 Docker 正在启动 container2,因此任何docker run -v 路径始终是主机的路径。除非您知道某个特定目录已经挂载到您的容器中,否则很难与“子容器”共享文件。

    解决此问题的一种方法是断言存在某种共享路径:

    docker run \
      -v $PWD/exchange:/exchange \
      -v /var/run/docker.sock:/var/run/docker.sock \
      -e EXCHANGE_PATH=$PWD/exchange \
      --name container1
      ...
    
    # from within container1
    mkdir $EXCHANGE_PATH/container2
    echo hello world > $EXCHANGE_PATH/container2/file.txt
    docker run \
      -v $EXCHANGE_PATH/container2:/data
      --name container2
      ...
    

    当我过去这样做时(对于想要启动辅助容器的测试设置),我使用了一个艰苦的docker createdocker cpdocker startdocker cpDocker rm 序列.这是非常手动的操作,但它的优势在于 docker cp 的“本地”端始终是当前文件系统上下文,即使您是在容器内与主机的 Docker 守护进程通信。

    【讨论】:

      【解决方案2】:

      容器 2 是否绑定主机路径无关紧要,因为容器 1 中文件的更改直接影响主机路径上的所有内容。所以他们都在同一个文件上工作。

      因此,您的设置是正确的,并且与您描述的方式引用它们的功能相同。

      更新
      如果您想确保该进程不会修改主机文件,您可以执行以下操作:

      构建一个自定义 docker 映像,将文件夹 a 中的所有数据复制到文件夹 b,您在文件夹 b 上执行脚本。然后使用./:/a 挂载文件。这样您就可以灵活地绑定到容器的文件,而无需让容器修改主机文件。

      我希望这能回答你的问题:)

      【讨论】:

      • 问题是我不想在主机中进行任何修改
      • @DavidBensoussan,你想这样做的用例是什么?因为通常您会使用卷来进行数据持久化,这意味着您确实希望在主机上进行修改,否则就不可能持久化数据。所以考虑到这一点,我很好奇你到底想做什么/实现这个
      • 我的主机上有一个 jenkins 容器正在运行。其中一项工作启动了一个容器,我将一个文件夹传递到该容器。这是一个将针对此文件夹运行的脚本。另一种方法是 docker 创建、启动和复制文件夹。它会比一个简单的 docker run 更冗长
      • @DavidBensoussan,我在回答中添加了一个建议,您可以如何实现这一目标。
      猜你喜欢
      • 2014-08-08
      • 1970-01-01
      • 2014-10-08
      • 1970-01-01
      • 2015-03-04
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 2020-10-06
      相关资源
      最近更新 更多