捕获python脚本的输出在docker容器内运行 [英] Capturing output of python script run inside a docker container

查看:345
本文介绍了捕获python脚本的输出在docker容器内运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里的目的是使用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 命令行参数,一切显示:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆