此处的目的是使用docker容器作为安全沙箱,以在其中运行不受信任的python脚本,但使用docker-py模块从python内部执行此操作,并能够捕获该脚本的输出。

我在Docker容器中运行python脚本foo.py(在Dockerfile中将其设置为ENTRYPOINT命令,因此在容器运行后立即执行),无法捕获该脚本的输出。当我通过普通的CLI使用运行容器时

docker run -v /host_dirpath:/cont_dirpath my_image

(host_dirpath是包含foo.py的目录)我将foo.py的预期输出打印到stdout,这只是键值对的字典。但是,我正在尝试使用docker-py模块在python内部执行此操作,并且logs方法无法以某种方式捕获脚本输出。这是我正在使用的python代码:
from docker import Client

docker = Client(base_url='unix://var/run/docker.sock',
              version='1.10',
              timeout=10)

contid = docker.create_container('my_image', volumes={"/cont_dirpath":""})
docker.start(contid, binds={"/host_dirpath": {"bind": "/cont_dirpath"} })

print "Docker logs: " + str(docker.logs(contid))

这只会导致“Docker日志:”-日志中没有捕获任何内容,无论是stdout还是stderr(我都尝试在foo.py中引发异常以测试此问题)。

我得到的结果是由foo.py计算的,当前仅通过python print语句打印到stdout。我如何才能将其包含在Docker容器日志中,以便可以从python中读取它?还是从容器外部以其他方式捕获此输出?

任何帮助将不胜感激。提前致谢!

编辑:

docker-py仍然没有运气,但是当使用带有subprocess.Popen的常规CLI运行容器时,它运行良好,在执行此操作时,stdout确实正确地捕获了输出。

最佳答案

您正在遇到此行为,因为python默认情况下会缓冲其输出。

举个例子:

vagrant@docker:/vagrant/tmp$ cat foo.py
#!/usr/bin/python
from time import sleep

while True:
    print "f00"
    sleep(1)

然后从作为守护程序运行的容器中观察日志不会显示任何内容:
vagrant@docker:/vagrant/tmp$ docker logs -f $(docker run -d -v $(pwd):/app dockerfile/python python /app/foo.py)

但是,如果您使用-u命令行参数禁用python缓冲的输出,则会显示所有内容:
vagrant@docker:/vagrant/tmp$ docker logs -f $(docker run -d -v $(pwd):/app dockerfile/python python -u /app/foo.py)
f00
f00
f00
f00

您还可以注入(inject)PYTHONUNBUFFERED环境变量:
vagrant@docker:/vagrant/tmp$ docker logs -f $(docker run -d -v $(pwd):/app -e PYTHONUNBUFFERED=0 dockerfile/python python /app/foo.py)
f00
f00
f00
f00

请注意,此行为仅影响没有-t--tty参数运行的容器。

关于python - 捕获在Docker容器中运行的python脚本的输出,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23524976/

10-14 17:42
查看更多