简体   繁体   English

Docker inside docker:文件丢失

[英]Docker inside docker: file missing

I am launching docker inside another docker container and I'm trying to make files visible inside "deepest" container.我在另一个 docker 容器内启动 docker,我试图让文件在“最深”容器内可见。

My first container is build on python:3.8-slim image, entrypoint is ["python"] and is called test-client .我的第一个容器构建在python:3.8-slim图像上,入口点是["python"]并且称为test-client

I launch it as docker run --rm -it -v /home/.../inputs:/inputs -v /var/run/docker.sock:/var/run/docker.sock -.network... test-client start_client.py... .我将其启动为docker run --rm -it -v /home/.../inputs:/inputs -v /var/run/docker.sock:/var/run/docker.sock -.network... test-client start_client.py...

Now inner container.现在是内胆。 Inside start_client.py I run it with docker==5.0.3 library.start_client.py ,我使用 docker docker==5.0.3库运行它。

def check_docker():
    import time
    inputs = Mount('/inputs', 'inputs')
    client = docker.from_env()
    client.images.pull('apline')
    time.sleep(30) # I will explain this later
    output = client.containers.run(
        'apline', 'ls inputs -al',
         mounts=[inputs]
    ).decode('utf-8')
    for line in output.split('\n'):
        print(line)

So.所以。 I used time.sleep to have time to dive into first container and check if needed file is presed.我使用time.sleep有时间潜入第一个容器并检查是否需要文件。 Yes it is, my file is inside first container.是的,我的文件在第一个容器中。 But output of deepest container sees no files inside inputs directory.但是最深容器的 output 在inputs目录中看不到任何文件。

What am I doing wrong?我究竟做错了什么?

You can't directly mount a directory from one container to another.您不能直接将一个目录从一个容器挂载到另一个容器。 In the mounts option you show (and in docker run -v and Compose volumes: ) the host path is always a path on the system where the Docker daemon is running.在您显示的mounts选项中(以及在docker run -v和 Compose volumes:中)主机路径始终是运行 Docker 守护程序的系统上的路径。 If you're bind-mounting the host's Docker socket, these paths will be paths on the host;如果您绑定安装主机的 Docker 套接字,这些路径将是主机上的路径; if $DOCKER_HOST points into a VM or at a remote machine, the paths will be paths on that system and not your local one.如果$DOCKER_HOST指向虚拟机或远程机器,则路径将是该系统上的路径,而不是您本地的路径。

But, in your specific example, the directory you're trying to remount is already a mount itself.但是,在您的具体示例中,您尝试重新挂载的目录本身已经是一个挂载。 If you mount the same host location into both containers, then you'll be able to see the files.如果将相同的主机位置挂载到两个容器中,那么您将能够看到这些文件。 I'd suggest specifying this in an environment variable我建议在环境变量中指定它

inputs = Mount('/inputs', os.getenv('INPUT_SOURCE', 'input'))

and when you run the container, pass that directory in as a variable当你运行容器时,将该目录作为变量传入

INPUT_SOURCE="$PWD/inputs"
docker run --rm -it \
  -e INPUT_SOURCE \
  -v "$INPUT_SOURCE:/inputs" \
  --network ... \
  test-client \
  start_client.py ...

If you use a bare string input in the Mount object as you've done, it will mount (and automatically create) a named volume.如果您像之前那样在Mount object 中使用裸字符串input ,它将挂载(并自动创建)一个命名卷。 You can use your container to inspect this你可以用你的容器来检查这个

docker run --rm -v inputs:/inputs test-client \
  -e 'print(os.listdir("/inputs"))'

(you can use a simpler shell syntax if you remove the ENTRYPOINT ["python"] line from your Dockerfile). (如果从 Dockerfile 中删除ENTRYPOINT ["python"]行,则可以使用更简单的 shell 语法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM