捕获python脚本的输出在docker容器内运行 [英] Capturing output of python script run inside a docker container
问题描述
这里的目的是使用docker容器作为安全沙箱来运行不受信任的python脚本,但是在python内使用docker-py模块,并能够捕获该脚本的输出。
我在Docker容器内运行一个python脚本foo.py(它被设置为 ENTRYPOINT
命令我的Dockerfile,所以一旦运行容器就执行它),并且我无法捕获该脚本的输出。当我通过普通CLI运行容器时,使用
docker run -v / host_dirpath:/ cont_dirpath my_image
( host_dirpath
是包含foo.py的目录)输出foo.py打印到stdout,这只是一个键值对的字典。但是,我试图通过使用docker-py模块在python中执行此操作,并且不知何故脚本输出未被 logs
方法捕获。以下是我使用的python代码:
$ code from docker import Client
docker = Client(base_url ='unix://var/run/docker.sock',
version ='1.10',
timeout = 10)
contid = docker.create_container('my_image' ,volume = {/ cont_dirpath:})
docker.start(contid,binding = {/ host_dirpath:{bind:/ cont_dirpath}})
打印Docker日志:+ str(docker.logs(contid))
Docker日志: - 在日志中没有捕获任何东西,既不是Stdout也不是stderr(我尝试在foo.py中引发异常来测试这个)。
结果我以后是由foo.py计算的,目前只是使用python print
语句打印到stdout。我如何才能将其包含在docker容器日志中,以便我可以从python中读取它?或者从容器外面以其他方式捕获此输出?
任何帮助将不胜感激。感谢提前!
编辑:
仍然没有运气与docker-py,但它运行良好使用普通的CLI使用子进程运行容器.Popen - 在执行此操作时,输出确实被stdout正确地抓住了。
您正在遇到此行为,因为python默认缓冲其输出。
以此示例:
vagrant @ docker:/ vagrant / tmp $ cat foo.py
#! / usr / bin / python
从时间导入睡眠
同时True:
打印f00
睡眠(1)
然后观察从作为守护进程运行的容器中的日志不显示任何内容:
<$ -v $(pwd):/ app dockerfile / python python /app/foo.py)pre>
vagrant @ docker:/ vagrant / tmp $ docker logs -f $(docker run -d -v
但是如果使用 -u $ c禁用python缓冲输出$ c>命令行参数,一切显示:
vagrant @ docker:/ vagrant / tmp $ docker logs -f $ docker运行-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
参数。
The aim here is to use a docker container as a secure sandbox to run untrusted python scripts in, but to do so from within python using the docker-py module, and be able to capture the output of that script.
I'm running a python script foo.py inside a docker container (it's set as the ENTRYPOINT
command in my Dockerfile, so it's executed as soon as the container is run) and am unable to capture the output of that script. When I run the container via the normal CLI using
docker run -v /host_dirpath:/cont_dirpath my_image
(host_dirpath
is the directory containing foo.py) I get the expected output of foo.py printed to stdout, which is just a dictionary of key-value pairs. However, I'm trying to do this from within python using the docker-py module, and somehow the script output is not being captured by the logs
method. Here's the python code I'm using:
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))
Which just results in "Docker logs: " - nothing is being captured in the logs, neither stdout nor stderr (I tried raising an exception inside foo.py to test this).
The results I'm after are calculated by foo.py and are currently just printed to stdout with a python print
statement. How can I get this to be included in the docker container logs so I can read it from within python? Or capture this output some other way from outside the container?
Any help would be greatly appreciated. Thanks in advance!
EDIT:
Still no luck with docker-py, but it is working well when running the container with the normal CLI using subprocess.Popen - the output is indeed correctly grabbed by stdout when doing this.
You are experiencing this behavior because python buffers its outputs by default.
Take this example:
vagrant@docker:/vagrant/tmp$ cat foo.py
#!/usr/bin/python
from time import sleep
while True:
print "f00"
sleep(1)
then observing the logs from a container running as a daemon does not show anything:
vagrant@docker:/vagrant/tmp$ docker logs -f $(docker run -d -v $(pwd):/app dockerfile/python python /app/foo.py)
but if you disable the python buffered output with the -u
command line parameter, everything shows up:
vagrant@docker:/vagrant/tmp$ docker logs -f $(docker run -d -v $(pwd):/app dockerfile/python python -u /app/foo.py)
f00
f00
f00
f00
You can also inject the PYTHONUNBUFFERED
environment variable:
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
Note that this behavior affects only containers running without the -t
or --tty
parameter.
这篇关于捕获python脚本的输出在docker容器内运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!