jenkins docker docker-dind

jenkins - ¿Está bien ejecutar Docker desde el interior de Docker?



docker-dind (3)

Estoy ejecutando Jenkins dentro de un contenedor Docker. Me pregunto si está bien que el contenedor Jenkins también sea un host Docker. Lo que estoy pensando es iniciar un nuevo contenedor de acopladores para cada compilación de prueba de integración desde dentro de Jenkins (para iniciar bases de datos, corredores de mensajes, etc.). Por lo tanto, los contenedores deben cerrarse después de completar las pruebas de integración. ¿Hay alguna razón para evitar ejecutar contenedores Docker desde dentro de otro contenedor Docker de esta manera?


Está bien ejecutar Docker-in-Docker (DinD) y, de hecho, Docker (la compañía) tiene una imagen DinD oficial para esto.

Sin embargo, la advertencia es que requiere un contenedor privilegiado, que según sus necesidades de seguridad puede no ser una alternativa viable.

La solución alternativa de ejecutar Docker usando contenedores hermanos (también conocido como Docker-out-of-Docker o DooD) no requiere un contenedor privilegiado, pero tiene algunos inconvenientes derivados del hecho de que está iniciando el contenedor desde un contexto que es diferente de aquel en el que se está ejecutando (es decir, inicia el contenedor desde dentro de un contenedor, sin embargo, se está ejecutando en el nivel del host, no dentro del contenedor).

Escribí un blog describiendo los pros / contras de DinD vs DooD here .

Dicho esto, Nestybox (una startup que acabo de fundar) está trabajando en una solución que ejecuta Docker-in-Docker de forma segura (sin usar contenedores privilegiados). Puede consultarlo en www.nestybox.com .


Respondí una pregunta similar antes sobre cómo ejecutar un contenedor Docker dentro de Docker .

Ejecutar docker dentro de docker es definitivamente posible. Lo principal es que run el contenedor externo con privilegios adicionales (comenzando con --privileged=true ) y luego instale docker en ese contenedor.

Consulte esta publicación de blog para obtener más información: Docker-in-Docker .

Un caso de uso potencial para esto se describe en esta entrada . El blog describe cómo construir contenedores acoplables dentro de un contenedor acoplable Jenkins.

Sin embargo, Docker dentro de Docker no es el enfoque recomendado para resolver este tipo de problemas. En cambio, el enfoque recomendado es crear contenedores "hermanos" como se describe en esta publicación

Por lo tanto, ejecutar Docker dentro de Docker fue considerado por muchos como un buen tipo de solución para este tipo de problemas. Ahora, la tendencia es utilizar contenedores "hermanos" en su lugar. Vea la respuesta de @predmijat en esta página para obtener más información.


Se debe evitar ejecutar Docker dentro de Docker (también conocido como dind ), si es posible, si es posible. (La fuente se proporciona a continuación.) En su lugar, desea establecer una forma para que su contenedor principal produzca y se comunique con los contenedores hermanos .

Jérôme Petazzoni , el autor de la función que hizo posible que Docker se ejecute dentro de un contenedor Docker, en realidad escribió una publicación de blog diciendo que no debía hacerlo . El caso de uso que describe coincide con el caso de uso exacto del OP de un contenedor Docker de CI que necesita ejecutar trabajos dentro de otros contenedores Docker.

Petazzoni enumera dos razones por las cuales dind es problemático:

  1. No coopera bien con los módulos de seguridad de Linux (LSM).
  2. Crea una falta de coincidencia en los sistemas de archivos que crea problemas para los contenedores creados dentro de los contenedores principales.

De esa publicación de blog, describe la siguiente alternativa,

[La] forma más sencilla es simplemente exponer el zócalo Docker a su contenedor CI, mediante un montaje en enlace con la bandera -v .

En pocas palabras, cuando inicie su contenedor CI (Jenkins u otro), en lugar de piratear algo junto con Docker-in-Docker, comience con:

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

Ahora este contenedor tendrá acceso al zócalo Docker y, por lo tanto, podrá iniciar contenedores. Excepto que en lugar de iniciar contenedores "secundarios", comenzará contenedores "hermanos".