这里的目的是使用docker容器作为安全沙箱来运行不受信任的python脚本,但是要在python中使用docker-py模块来执行此操作,并且能够捕获该脚本的输出。
我在Docker容器(它在ENTRYPOINT
设置为ENTRYPOINT
命令,所以在容器运行后立即执行)运行一个python脚本foo.py,并且无法捕获该脚本的输出。 当我通过正常的CLI使用运行容器
docker run -v /host_dirpath:/cont_dirpath my_image
( host_dirpath
是包含foo.py的目录)我得到打印到stdout的foo.py的预期输出,这只是键值对的字典。 不过,我正在尝试从使用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日志:” – 没有任何东西被捕获在日志中,无论是标准输出或标准错误(我试图引发foo.py中的exception来testing)。
我后面的结果是由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
你也可以注入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
参数运行的容器。
由于启动的容器与您的控制程序并行运行,您可能会遇到竞争状况。 抓取日志之前,您需要等待容器开始和完成。 在docker.start之后,将docker.wait添加到您的代码中。
docker.wait(contid)
你的输出看起来是空的,因为还没有记录。