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.
这里的目的是使用docker容器作为安全沙箱来运行不受信任的python脚本,但是使用docker-py模块在python中执行此操作,并且能够捕获该脚本的输出。
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容器中运行python脚本foo.py(它在我的Dockerfile中设置为ENTRYPOINT命令,所以它在容器运行后立即执行)并且无法捕获该脚本的输出。当我使用普通CLI运行容器时
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:
(host_dirpath是包含foo.py的目录)我得到foo.py的预期输出打印到stdout,这只是一个键值对的字典。但是,我正在尝试使用docker-py模块在python中执行此操作,并且以某种方式,日志方法未捕获脚本输出。这是我正在使用的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))
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).
这只会导致“Docker日志:” - 日志中没有捕获任何内容,stdout和stderr都没有(我尝试在foo.py中引发异常来测试它)。
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?
我之后的结果是由foo.py计算的,目前只是用python print语句打印到stdout。我怎样才能将它包含在docker容器日志中,以便我可以在python中读取它?或者从容器外部以其他方式捕获此输出?
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.
使用docker-py仍然没有运气,但是当使用subprocess.Popen使用普通CLI运行容器时它运行良好 - 执行此操作时,输出确实被stdout正确抓取。
2 个解决方案
#1
16
You are experiencing this behavior because python buffers its outputs by default.
您遇到此行为,因为python默认缓冲其输出。
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:
但如果使用-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
You can also inject the PYTHONUNBUFFERED
environment variable:
您还可以注入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
Note that this behavior affects only containers running without the -t
or --tty
parameter.
请注意,此行为仅影响在没有-t或--tty参数的情况下运行的容器。
#2
2
You may experience a race condition since the started container is running in parallel to your control program. You need to wait for your container to start and finish before grabbing the logs. Add a docker.wait to your code right after docker.start.
您可能会遇到竞争条件,因为已启动的容器与您的控制程序并行运行。在抓取日志之前,您需要等待容器启动和完成。在docker.start之后立即将docker.wait添加到您的代码中。
docker.wait(contid)
Your output seems empty because nothing has yet been logged.
您的输出似乎为空,因为尚未记录任何内容。
#1
16
You are experiencing this behavior because python buffers its outputs by default.
您遇到此行为,因为python默认缓冲其输出。
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:
但如果使用-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
You can also inject the PYTHONUNBUFFERED
environment variable:
您还可以注入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
Note that this behavior affects only containers running without the -t
or --tty
parameter.
请注意,此行为仅影响在没有-t或--tty参数的情况下运行的容器。
#2
2
You may experience a race condition since the started container is running in parallel to your control program. You need to wait for your container to start and finish before grabbing the logs. Add a docker.wait to your code right after docker.start.
您可能会遇到竞争条件,因为已启动的容器与您的控制程序并行运行。在抓取日志之前,您需要等待容器启动和完成。在docker.start之后立即将docker.wait添加到您的代码中。
docker.wait(contid)
Your output seems empty because nothing has yet been logged.
您的输出似乎为空,因为尚未记录任何内容。