linux - run - dockerfile ejemplos
Explorando el sistema de archivos del contenedor Docker (21)
He notado con la ventana acoplable que necesito entender qué sucede dentro de un contenedor o qué archivos existen allí. Un ejemplo es la descarga de imágenes desde el índice de la ventana acoplable: no tiene ni idea de qué contiene la imagen, por lo que es imposible iniciar la aplicación.
Lo que sería ideal es poder ssh en ellos o equivalente. ¿Existe alguna herramienta para hacer esto, o mi conceptualización de la ventana acoplable es errónea al pensar que debería poder hacer esto?
El comando docker exec
para ejecutar un comando en un contenedor en ejecución puede ayudar en varios casos.
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...] Run a command in a running container Options: -d, --detach Detached mode: run command in the background --detach-keys string Override the key sequence for detaching a container -e, --env list Set environment variables -i, --interactive Keep STDIN open even if not attached --privileged Give extended privileges to the command -t, --tty Allocate a pseudo-TTY -u, --user string Username or UID (format: [:]) -w, --workdir string Working directory inside the container
Por ejemplo :
1) Accediendo en bash al sistema de archivos del contenedor en ejecución:
docker exec -it containerId bash
2) Accediendo en bash al sistema de archivos contenedor en ejecución como root para poder tener los derechos requeridos:
docker exec -it -u root containerId bash
Esto es particularmente útil para poder realizar algún procesamiento como raíz en un contenedor.
3) Accediendo en bash al sistema de archivos contenedor en ejecución con un directorio de trabajo específico:
docker exec -it -w /var/lib containerId bash
El sistema de archivos del contenedor está en la carpeta de datos de la ventana acoplable, normalmente en / var / lib / docker. Para iniciar e inspeccionar un sistema de archivos de contenedores en ejecución, haga lo siguiente:
hash=$(docker run busybox)
cd /var/lib/docker/aufs/mnt/$hash
Y ahora el directorio de trabajo actual es la raíz del contenedor.
En Ubuntu 14.04 ejecutando Docker 1.3.1 , encontré el sistema de archivos raíz del contenedor en la máquina host en el siguiente directorio:
/var/lib/docker/devicemapper/mnt/<container id>/rootfs/
Información completa de la versión de Docker:
Client version: 1.3.1
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): 4e9bbfa
OS/Arch (client): linux/amd64
Server version: 1.3.1
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): 4e9bbfa
En las versiones más nuevas de Docker, puede ejecutar docker exec [container_name]
que ejecuta un shell dentro de su contenedor
Entonces, para obtener una lista de todos los archivos en un contenedor, simplemente ejecute el docker exec [container_name] ls
En mi caso no se soportó shell en el contenedor excepto sh
. Así que, esto funcionó a la perfección.
docker exec -it <container-name> sh
Esta respuesta ayudará a aquellos (como yo) que quieran explorar el sistema de archivos de volumen de la ventana acoplable incluso si el contenedor no se está ejecutando.
Lista de contenedores docker en ejecución:
docker ps
=> ID DEL CONTENEDOR "4c721f1985bd"
Mire los puntos de montaje de volumen de la ventana acoplable en su máquina física local ( https://docs.docker.com/engine/tutorials/dockervolumes/ ):
docker inspect -f {{.Mounts}} 4c721f1985bd
=> [{/ tmp / container-garren / tmp true rprivate}]
Esto me dice que el directorio de la máquina física local / tmp / container-garren está asignado al destino de volumen de la ventana acoplable / tmp.
Conocer el directorio de la máquina física local (/ tmp / container-garren) significa que puedo explorar el sistema de archivos si el contenedor de la ventana acoplable se está ejecutando o no. Esto fue fundamental para ayudarme a descubrir que había algunos datos residuales que no deberían haber persistido incluso después de que el contenedor no se estuviera ejecutando.
Intenta usar
docker exec -it <container-name> /bin/bash
Puede haber posibilidad de que bash no esté implementado. para eso puedes usar
docker exec -it <container-name> sh
La respuesta más votada es buena, excepto si su contenedor no es un sistema Linux real.
Muchos contenedores (especialmente los basados en Go) no tienen ningún binario estándar (no /bin/bash
o /bin/sh
). En ese caso, deberá acceder directamente al archivo de los contenedores reales:
Funciona de maravilla:
name=<name>
dockerId=$(docker inspect -f {{.Id}} $name)
mountId=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$dockerId/mount-id)
cd /var/lib/docker/aufs/mnt/$mountId
Nota: Necesitas ejecutarlo como root.
La respuesta más votada me funciona cuando el contenedor se inicia realmente, pero cuando no es posible ejecutarlo y, por ejemplo, desea copiar archivos del contenedor, esto me ha salvado antes:
docker cp <container-name>:<path/inside/container> <path/on/host/>
Gracias a docker cp ( this ) puede copiar directamente desde el contenedor como lo era cualquier otra parte de su sistema de archivos. Por ejemplo, recuperando todos los archivos dentro de un contenedor:
mkdir /tmp/container_temp
docker cp example_container:/ /tmp/container_temp/
Tenga en cuenta que no necesita especificar que desea copiar de forma recursiva.
Mi forma preferida de entender lo que sucede dentro del contenedor es:
exponer -p 8000
docker run -it -p 8000:8000 image
Iniciar el servidor en su interior
python -m SimpleHTTPServer
Otro truco es usar la herramienta atomic para hacer algo como:
mkdir -p /path/to/mnt && atomic mount IMAGE /path/to/mnt
La imagen de Docker se montará en / path / to / mnt para que la inspeccione.
Para el driver aufs docker:
El script encontrará el directorio raíz del contenedor (Prueba en la ventana acoplable 1.7.1 y 1.10.3)
if [ -z "$1" ] ; then
echo ''docker-find-root $container_id_or_name ''
exit 1
fi
CID=$(docker inspect --format {{.Id}} $1)
if [ -n "$CID" ] ; then
if [ -f /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id ] ; then
F1=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id)
d1=/var/lib/docker/aufs/mnt/$F1
fi
if [ ! -d "$d1" ] ; then
d1=/var/lib/docker/aufs/diff/$CID
fi
echo $d1
fi
Para mí, este funciona bien (gracias a los últimos comentarios por señalar el directorio / var / lib / docker / ):
chroot /var/lib/docker/containers/2465790aa2c4*/root/
Aquí, 2465790aa2c4 es el ID corto del contenedor en ejecución (como se muestra en la ventana acoplable ps ), seguido de una estrella.
Para un contenedor ya en ejecución, puede hacer:
dockerId=$(docker inspect -f {{.Id}} [docker_id_or_name])
cd /var/lib/docker/btrfs/subvolumes/$dockerId
Necesitas ser root para poder cd en ese directorio. Si no es root, intente ''sudo su'' antes de ejecutar el comando.
Edición: Siguiendo v1.3, vea la respuesta de Jiri - es mejor.
Puede archivar el sistema de archivos de su contenedor en el archivo tar:
docker export adoring_kowalevski > contents.tar
Esta forma funciona incluso si su contenedor está detenido y no tiene ningún programa de shell como /bin/bash
. Me refiero a imágenes como hello-world de la documentación de Docker .
Puede ejecutar un bash dentro del contenedor con esto: $ docker run -it ubuntu /bin/bash
Si está utilizando el controlador de almacenamiento AUFS, puede usar mi script de la ventana docker-layer para encontrar la raíz del sistema de archivos de cualquier contenedor (mnt) y la capa de reescritura:
# docker-layer musing_wiles
rw layer : /var/lib/docker/aufs/diff/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
mnt : /var/lib/docker/aufs/mnt/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
Editar 2018-03-28:
Docker-layer ha sido reemplazado por docker-backup
Utilizo otro truco sucio que es aufs / devicemapper agnostic.
Miro el comando que el contenedor está ejecutando, por ejemplo, docker ps
y si es un apache o java
solo hago lo siguiente:
sudo -s
cd /proc/$(pgrep java)/root/
Y voilá estás dentro del contenedor.
Básicamente, usted puede como cd raíz en la carpeta /proc/<PID>/root/
siempre que el contenedor ejecute ese proceso. Cuidado con los enlaces simbólicos no tendrá sentido usar ese modo.
ACTUALIZACIÓN: ¡EXPLORANDO!
Este comando debe permitirle explorar un contenedor de ventana acoplable en ejecución :
docker exec -it name-of-container bash
una vez dentro haz:
ls -lsa
o cualquier otro comando de bash como:
cd ..
Este comando debería permitirte explorar una imagen de ventana acoplable :
docker run --rm -it --entrypoint=/bin/bash name-of-image
una vez dentro haz:
ls -lsa
o cualquier otro comando de bash como:
cd ..
El -it
significa interactivo ... y tty
Antes de la creación del contenedor:
Si desea explorar la estructura de la imagen que está montada dentro del contenedor, puede hacerlo
sudo docker image save image_name > image.tar
tar -xvf image.tar
Esto le daría la visibilidad de todas las capas de una imagen y su configuración que está presente en los archivos json.
Después de la creación del contenedor:
Para esto ya hay muchas respuestas arriba. Mi forma preferida de hacer esto sería
docker exec -t -i container /bin/bash
Método 1: instantáneas
Puede evaluar el sistema de archivos contenedor de esta manera:
# find ID of your running container:
docker ps
# create image (snapshot) from container filesystem
docker commit 12345678904b5 mysnapshot
# explore this filesystem using bash (for example)
docker run -t -i mysnapshot /bin/bash
De esta manera, puede evaluar el sistema de archivos del contenedor en ejecución en el momento preciso. El contenedor todavía se está ejecutando, no se incluyen cambios futuros.
Más tarde, puede eliminar la instantánea utilizando (¡el sistema de archivos del contenedor en ejecución no se ve afectado!):
docker rmi mysnapshot
Método 2: ssh
Si necesita acceso continuo, puede instalar sshd en su contenedor y ejecutar el demonio sshd:
docker run -d -p 22 mysnapshot /usr/sbin/sshd -D
# you need to find out which port to connect:
docker ps
De esta manera, puede ejecutar su aplicación usando ssh (conectarse y ejecutar lo que desee).
ACTUALIZACIÓN - Método 3: nsenter
Utilice nsenter
, consulte http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/
La versión corta es: con nsenter, puede obtener un shell en un contenedor existente, incluso si ese contenedor no ejecuta SSH o cualquier tipo de demonio de propósito especial
ACTUALIZACIÓN - Método 4: docker exec
La versión 1.3 de Docker (la última versión, es posible que deba usar la reposición apta de Docker para instalar la última versión a partir de noviembre de 2014) es compatible con el nuevo comando exec
que se comporta de manera similar a nsenter
. Este comando puede ejecutar un nuevo proceso en el contenedor que ya se está ejecutando (el contenedor debe tener el proceso PID 1 en ejecución). Puede ejecutar /bin/bash
para explorar el estado del contenedor:
docker exec -t -i mycontainer /bin/bash
Consulte la documentación de la línea de comandos de Docker.