Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python docker容器在约50%的情况下绑定装载后获得空文件_Python_Docker - Fatal编程技术网

Python docker容器在约50%的情况下绑定装载后获得空文件

Python docker容器在约50%的情况下绑定装载后获得空文件,python,docker,Python,Docker,我试图使用bind选项将文件装载到容器中,但它的工作非常不稳定 下面的示例创建一个文件,将其装入容器并打印该文件的内容 import docker import docker.types import tempfile def foo(): temp_dir = tempfile.TemporaryDirectory() file_path = temp_dir.name + "/file.txt" with open(file_path, "w") as f:

我试图使用
bind
选项将文件装载到容器中,但它的工作非常不稳定

下面的示例创建一个文件,将其装入容器并打印该文件的内容

import docker
import docker.types
import tempfile

def foo():

    temp_dir = tempfile.TemporaryDirectory()
    file_path = temp_dir.name + "/file.txt"
    with open(file_path, "w") as f:
        f.write("Hello")

    docker_client = docker.DockerClient()
    output = docker_client.containers.run(
        image="alpine",

        mounts=[
            docker.types.Mount("/file.txt", file_path, type="bind")
        ],
        command="cat /file.txt"
    )
    print(output)

for _ in range(10):
    foo()
以下是执行结果:

b''
b'Hello'
b''
b''
b''
b''
b'Hello'
b'Hello'
b'Hello'
b'Hello'
这种随意的行为真把我弄糊涂了。我尝试过各种选择,但仍然有相同的结果

我做错了什么

提前谢谢

UPD:

更清楚地说,我应该说我已经尝试过:

  • consistensy=“consistent”
    选项
  • 刷新文件并在写入数据后休眠

在运行容器之前,文件似乎没有完全写入磁盘。如果最初只编写一次文件,然后运行容器,则每次都会打印内容。以下是ipython中的输出:

In [7]: !echo "Hello" > /tmp/file.txt                                                                                                                                           

In [8]: import docker 
   ...: import docker.types 
   ...:  
   ...: def foo(file_path): 
   ...:     docker_client = docker.DockerClient() 
   ...:     output = docker_client.containers.run( 
   ...:         image="alpine", 
   ...:         mounts=[ 
   ...:             docker.types.Mount("/file.txt", file_path, type="bind") 
   ...:         ], 
   ...:         command="cat /file.txt" 
   ...:     ) 
   ...:     print(output) 
   ...:  
   ...: for _ in range(10): 
   ...:     foo("/tmp/file.txt") 
   ...:                                                                                                                                                                         
b'Hello\n'
b'Hello\n'
b'Hello\n'
b'Hello\n'
b'Hello\n'
b'Hello\n'
b'Hello\n'
b'Hello\n'
b'Hello\n'
b'Hello\n'

然而,这很奇怪,因为强制写入磁盘并不能解决问题。看

[1]中的
:导入docker
…:导入docker.types
…:导入临时文件
…:导入操作系统
...:  
…:def foo():
...:  
…:temp_dir=tempfile.TemporaryDirectory()
…:file_path=temp_dir.name+“/file.txt”
…:打开(文件路径,“w”)作为f:
…:f.write(“你好”)
…:f.flush()#已添加。
…:os.fsync(f.fileno())#已添加。
...:  
…:docker_client=docker.DockerClient()
…:output=docker\u client.containers.run(
…:image=“alpine”,
...:  
…:安装=[
…:docker.types.Mount(“/file.txt”,文件路径,type=“bind”)
...:         ], 
…:command=“cat/file.txt”
...:     ) 
…:打印(输出)
...:  
…:对于范围内的uu(10):
…:foo()
...:                                                                                                                                                                         
b“
b“
b“
b‘你好’
b“
b“
b“
b“
b“
b‘你好’

实际上,装载的文件不是空的,容器工作正常,问题在于
DockerClient.containers.run
函数的输出不稳定。真令人惊讶:)

这里有一个例子。它不是那么优雅,但应该有用

import docker
import docker.types
import tempfile
import os


def foo():
    temp_dir = tempfile.TemporaryDirectory()
    file_path = temp_dir.name + "/file.txt"
    with open(file_path, "w") as f:
        f.write("Hello")

    output_path = temp_dir.name + "/output"

    os.mkdir(output_path)

    docker_client = docker.DockerClient()
    docker_client.containers.run(
        image="alpine",

        mounts=[
            docker.types.Mount("/file.txt", file_path, type="bind"),
            docker.types.Mount("/output", output_path, type="bind")  # mount new directory to store copy result.
        ],
        command="cp /file.txt /output/checkfile.txt",  # copy first file into mounted directory
    )

    checkfile_path = output_path + "/checkfile.txt"

    with open(checkfile_path) as f:
        print(f.read())


for _ in range(20):
    foo()
输出:

Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello

为了确保测试是相同的,值得使用相同的文件夹重复。现在我至少看到了一个区别:第一种情况下有
/tmp
,第二种情况下返回的是
tempfile.TemporaryDirectory()
。因为我使用的是linux,
tempfile.TemporaryDirectory()
/tmp
中创建一个目录,如
/tmp/tmpak9wwrnf
您能再解释一下吗?为什么该函数的输出会不稳定?@jakub,因为如果我们将装载的文件复制到另一个文件,然后从容器中获取它,内容就会在那里。我用例子更新了这个答案。