tiangolo python3 hub dockers container python bash shell unix docker

python3 - Docker timeout para contenedor?



tiangolo uwsgi nginx flask python3 6 (4)

He logrado una solución para este problema.

Primero debes matar el contenedor de la ventana acoplable cuando se alcanza el límite de tiempo:

#!/bin/bash set -e did=$(docker run -it -d -v "/my_real_path/$1":/usercode virtual_machine ./usercode/compilerun.sh 2>> $1/error.txt) sleep 10 && docker kill $did &> /dev/null && echo -n "timeout" >> $1/error.txt & docker wait "$did" &> /dev/null docker rm -f $ &> /dev/null

El contenedor se ejecuta en modo separado (opción -d), por lo que se ejecuta en segundo plano. Entonces corres el sueño también en el fondo. Luego espera a que el contenedor se detenga. Si no se detiene en 10 segundos (temporizador de apagado), el contenedor se eliminará.

Como puede ver, el proceso de ejecución de la ventana acoplable llama a un script llamado compilerun.sh:

#!/bin/bash gcc -o /usercode/file /usercode/file.c 2> /usercode/error.txt && ./usercode/file < /usercode/input.txt | head -c 1M > /usercode/output.txt maxsize=1048576 actualsize=$(wc -c <"/usercode/output.txt") if [ $actualsize -ge $maxsize ]; then echo -e "1MB file size limit exceeded/n/n$(cat /usercode/output.txt)" > /usercode/output.txt fi

Comienza compilando y ejecutando un programa en C (es mi caso de uso, estoy seguro de que se puede hacer lo mismo para Python Compiller).

Esta parte:

command | head -c 1M > /usercode/output.txt

Es responsable del tamaño máximo de salida. Permite que la salida sea de 1MB máximo.

Después de eso, acabo de comprobar si el archivo es de 1 MB. Si es verdadero, escriba un mensaje dentro (al comienzo de) el archivo de salida.

Para mi disertación en la Universidad, estoy trabajando en un sistema de tablas de clasificación de códigos donde los usuarios pueden compilar / ejecutar códigos no confiables a través de contenedores de conexión temporales. El sistema parece estar funcionando bien hasta ahora, pero un problema que estoy enfrentando es que cuando se envía el código para un bucle infinito, por ejemplo:

while True: print "infinite loop"

el sistema se vuelve loco El problema es que cuando estoy creando un nuevo contenedor de docker, el intérprete de Python evita que el docker mate el contenedor secundario ya que los datos todavía se imprimen en STDOUT (para siempre). Esto lleva a la enorme vulnerabilidad de que la ventana acoplable se consuma todos los recursos disponibles del sistema hasta que la máquina que usa el sistema se congele por completo (se muestra a continuación):

Entonces, mi pregunta es, ¿hay una mejor manera de establecer un tiempo de espera en un contenedor de la ventana acoplable que mi método actual que realmente mate al contenedor de la ventana acoplable y haga que mi sistema sea seguro (código tomado originalmente de here )?

#!/bin/bash set -e to=$1 shift cont=$(docker run --rm "$@") code=$(timeout "$to" docker wait "$cont" || true) docker kill $cont &> /dev/null echo -n ''status: '' if [ -z "$code" ]; then echo timeout else echo exited: $code fi echo output: # pipe to sed simply for pretty nice indentation docker logs $cont | sed ''s/^//t/'' docker rm $cont &> /dev/null

Editar: El tiempo de espera predeterminado en mi aplicación (pasado a la variable $to ) es "10s" / 10 segundos.

He intentado buscar agregar un cronómetro y sys.exit() a la fuente de python directamente, pero esta no es realmente una opción viable ya que parece bastante insegura porque el usuario podría enviar un código para evitar que se ejecute, lo que significa el problema Todavía persistiría. Oh, las alegrías de estar atrapado en una disertación ... :(


Puede configurar su contenedor con un ulimit en el tiempo máximo de CPU, lo que matará el proceso de bucle. Sin embargo, un usuario malintencionado puede evitar esto, si son root dentro del contenedor.

Hay otra pregunta de SO, " Establecimiento de límites absolutos en la CPU para los contenedores Docker " que describe cómo limitar el consumo de CPU de los contenedores. Esto le permitiría reducir el efecto de usuarios malintencionados.

Sin embargo, estoy de acuerdo con Abdullah en que deberías poder docker kill un fugitivo de tu supervisor.


Si desea ejecutar los contenedores sin proporcionar ninguna protección dentro de ellos, puede utilizar restricciones de tiempo de ejecución en los recursos .

En su caso, -m 100M --cpu-quota 50000 puede ser razonable.

De esa manera, no consumirá los recursos del sistema de los padres hasta que consigas matarlo.


Supongo que puedes usar señales en Python como Unix para establecer el tiempo de espera. Puedes usar la alarma de tiempo específico digamos 50 segundos y atraparla. El siguiente enlace puede ayudarte. señales en python