Docker en Docker no se puede montar el volumen


Estoy ejecutando un clúster de Jenkins donde en el Maestro y el Esclavo, ambos se ejecutan como contenedores Docker.

El host es la última máquina virtual boot2docker que se ejecuta en macOS.

Para permitir que Jenkins pueda realizar la implementación usando Docker, he montado la docker.cliente sock y docker desde el host al contenedor Jenkins así: -

docker run -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker -v $HOST_JENKINS_DATA_DIRECTORY/jenkins_data:/var/jenkins_home -v $HOST_SSH_KEYS_DIRECTORY/.ssh/:/var/jenkins_home/.ssh/ -p 8080:8080 jenkins

Me enfrento a problemas al montar un volumen en contenedores Docker que se ejecutan dentro del contenedor Jenkins. Por ejemplo, si necesito ejecutar otro Contenedor dentro del contenedor Jenkins, hago lo siguiente: -

sudo docker run -v $JENKINS_CONTAINER/deploy.json:/root/deploy.json $CONTAINER_REPO/$CONTAINER_IMAGE 

Lo anterior ejecuta el contenedor, pero el archivo "deploy.json " NO se monta como un archivo, sino como un "Directorio". Incluso si monte un directorio como un Volumen, no puedo ver los archivos en el contenedor resultante.

¿Es esto un problema, debido a los permisos de archivo debidos a Docker en el caso Docker ?

Cualquier puntero sería útil !

Gracias!

Author: ZephyrPLUSPLUS, 2015-07-13

5 answers

Un contenedor de Docker en un contenedor de Docker utiliza el demonio de Docker del HOST principal y, por lo tanto, cualquier volumen montado en el caso "docker-in-docker" sigue siendo referenciado desde el HOST, y no desde el Contenedor.

Por lo tanto, la ruta real montada desde el contenedor Jenkins "no existe" en el HOST. Debido a esto, se crea un nuevo directorio en el contenedor "docker-in-docker" que está vacío. Lo mismo se aplica cuando un directorio se monta en un nuevo contenedor Docker dentro de un Contenedor.

Algo muy básico y obvio que me perdí, pero me di cuenta tan pronto escribí la pregunta.

 40
Author: ZephyrPLUSPLUS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-13 10:47:11

Con respecto a su caso de uso relacionado con Jenkins, simplemente puede falsificar la ruta creando un enlace simbólico en el host:

ln -s $HOST_JENKINS_DATA_DIRECTORY/jenkins_data /var/jenkins_home
 6
Author: mperrin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-08 14:09:29

Otra forma de hacerlo es usar volúmenes con nombre o contenedores de volúmenes de datos. De esta manera, el contenedor interior no tiene que saber nada sobre el host y tanto el contenedor Jenkins como el contenedor build hacen referencia al volumen de datos de la misma manera.

He intentado hacer algo similar a lo que estás haciendo, excepto con un agente en lugar de usar el maestro Jenkins. El problema era el mismo en que no podía montar el espacio de trabajo Jenkins en el contenedor interno. Lo trabajé para mí utilizando el enfoque de contenedor de volumen de datos y los archivos del espacio de trabajo eran visibles tanto para el contenedor del agente como para el contenedor interno. Lo que me gustó del enfoque es que ambos contenedores hacen referencia al volumen de datos de la misma manera. Montar directorios con un contenedor interno sería complicado, ya que el contenedor interno ahora necesita saber algo sobre el host en el que se está ejecutando su contenedor primario.

He detallado la entrada del blog sobre mi enfoque aquí:

Http://damnhandy.com/2016/03/06/creating-containerized-build-environments-with-the-jenkins-pipeline-plugin-and-docker-well-almost/

Así como el código aquí:

Https://github.com/damnhandy/jenkins-pipeline-docker

En mi caso específico, no todo está funcionando de la manera que me gustaría en términos del plugin Jenkins Pipeline. Pero sí aborda el problema de que el contenedor interno pueda acceder al directorio del espacio de trabajo de Jenkins.

 5
Author: Ryan J. McDonough,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-06 18:20:24

Una forma de solucionar este problema es montar un directorio (dentro del contenedor de docker en el que montó el socket de docker) utilizando exactamente la misma ruta para su destino. Luego, cuando ejecuta un contenedor desde dentro de ese contenedor, puede montar cualquier cosa dentro de la ruta de ese montaje en el nuevo contenedor usando docker -v.

Tomemos este ejemplo:

# Spin up your container from which you will use docker
docker run -v /some/dir:/some/dir -v /var/run/docker.sock:/var/run.docker.sock docker:latest

# Now spin up a container from within this container
docker run -v /some/dir:/usr/src/app $CONTAINER_IMAGE

La carpeta /some/dir ahora está montada en el host, el contenedor intermedio y el contenedor de destino. Dado que la ruta del montaje existe tanto en el host como en el contenedor "casi acoplable en acoplable", puede usar docker -v como se espera.

Es un poco similar a la sugerencia de crear un enlace simbólico en el host, pero encontré esto (al menos en mi caso), una solución más limpia. Simplemente no se olvide de limpiar el dir en el anfitrión después! ;)

 0
Author: Toon Lamberigts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-27 18:18:18

Esto también funciona a través de docker-compose y/o volúmenes con nombre, por lo que no necesita crear un contenedor solo de datos, pero aún necesita tener el directorio vacío en el host.

Configuración del host

Cree directorios del lado del host y establezca permisos para permitir el acceso a contenedores Docker sudo mkdir -p /var/jenkins_home/{workspace,builds,jobs} && sudo chown -R 1000 /var/jenkins_home && sudo chmod -R a+rwx /var/jenkins_home

Docker-compose.yml

version: '3.1'
services:
  jenkins:
    build: .
    image: jenkins
    ports:
      - 8080:8080
      - 50000:50000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - workspace:/var/jenkins_home/workspace/
      # Can also do builds/jobs/etc here and below
  jenkins-lts:
    build:
      context: .
      args:
        versiontag: lts
    image: jenkins:lts
    ports:
      - 8081:8080
      - 50001:50000
volumes:
  workspace:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /var/jenkins_home/workspace/

Cuando docker-compose up --build jenkins (es posible que desee incorporar esto en un ejemplo listo para ejecutar como https://github.com/thbkrkr/jks donde el .guiones de groovy pre-configure Jenkins para que sea útil en el inicio) y entonces podrá clonar sus trabajos en el directorio JEN JENKINS_HOME/workspace y no debería obtener errores sobre archivos faltantes/etc porque las rutas de host y contenedor coincidirán, y luego ejecutar más contenedores desde dentro de la Docker-in-Docker debería funcionar también.

Dockerfile (para Jenkins con Docker en Docker)

ARG versiontag=latest
FROM jenkins/jenkins:${versiontag}

ENV JAVA_OPTS="-Djenkins.install.runSetupWizard=false"

COPY jenkins_config/config.xml /usr/share/jenkins/ref/config.xml.override
COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt

USER root
RUN curl -L http://get.docker.io | bash && \
    usermod -aG docker jenkins
# Since the above takes a while make any other root changes below this line
# eg `RUN apt update && apt install -y curl`
# drop back to the regular jenkins user - good practice
USER jenkins
EXPOSE 8080
 0
Author: dragon788,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-12 21:33:50