这里的目的是使用docker容器作为安全沙箱来运行不受信任的python脚本,但是使用docker-py模块在python中执行此操作,并且能够捕获该脚本的输出。
我在docker容器中运行了一个python脚本foo.py(它在我的Dockerfile中设置为ENTRYPOINT
命令,所以它在容器运行后立即执行)并且无法捕获输出那个剧本当我使用
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正确抓取。
答案 0 :(得分:20)
您遇到此行为,因为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
参数的情况下运行的容器。
答案 1 :(得分:3)
由于启动的容器与控制程序并行运行,因此您可能会遇到竞争状况。在抓取日志之前,您需要等待容器启动和完成。在docker.start。
之后立即将docker.wait添加到您的代码中docker.wait(contid)
您的输出似乎为空,因为尚未记录任何内容。