Cómo ingresar en un contenedor Docker que ya se está ejecutando con un nuevo TTY

545

Tengo un contenedor que ejecuta el servicio Apache en primer plano. Me gustaría poder acceder al contenedor desde otro shell para "hurgar" dentro de él y examinar los archivos. Por el momento, si me adjunto al contenedor, me queda mirando el demonio Apache y no puedo ejecutar ningún comando.

¿Es posible adjuntar otro tty a un contenedor en ejecución? Posiblemente, ¿puedo aprovechar el hecho de que Docker en realidad solo está envolviendo contenedores LXC? Lo he intentado sudo lxc-console -n [container-id] -t [1-4]pero parece que solo hay un tty disponible y ese es el que ejecuta el demonio apache. ¿Quizás haya una manera de habilitar varias consolas lxc durante la compilación?

Prefiero no configurar y construir el contenedor con un servicio openssh si es posible.

Programador
fuente
77
¿Lo intentaste docker attach [conainer-id]?
shabbychef 01 de
13
@shabbychef a menos que Docker Attach haya cambiado, el comando Attach se adjunta al tty en ejecución, no uno nuevo, por lo tanto, el título de la pregunta es "... con nuevo TTY". Es por eso que la respuesta a continuación no utiliza el comando adjuntar.
Programador
1
Desde 1.3 hay una manera más fácil como se describe en esta respuesta
Thomasleveil

Respuestas:

1061

Con docker 1.3, hay un nuevo comando docker exec. Esto le permite ingresar a una ventana acoplable en ejecución:

docker exec -it [container-id] bash
Michael_Scharf
fuente
30
He cambiado esto para que sea la respuesta correcta (por mi cuenta) porque este nuevo método, que no existía en el momento de la pregunta, es el mejor método actual de la OMI.
Programador
3
Sin embargo, tenga en cuenta que execno actúa como un terminal normal. Por ejemplo, no puede cambiar de usuario una vez dentro del contenedor.
Pithikos
3
@Pithikos: Puedo usar exec para ejecutar un shell y luego su someusercambiar de usuario. Ejecutando Docker 1.4.1
lsh
2
Nota para cualquiera que lea esta discusión. Estoy seguro de docker exec -itque eventualmente proporcionará un pseudo tty completamente funcional, pero por ahora (Docker versión 1.9.1), hay algunas deficiencias: github.com/docker/docker/issues/8755
blong
18
si obtiene el error 'exec: "bash": el archivo ejecutable no se encuentra en $ PATH' puede intentar esto: docker exec -it [container-id] / bin / sh
Dai Kaixian el
42

Debe usar la herramienta de Jérôme Petazzoni llamada 'nsenter' para ingresar a un contenedor sin usar SSH. Ver: https://github.com/jpetazzo/nsenter

Instalar simplemente ejecutando: docker run -v /usr/local/bin:/target jpetazzo/nsenter

Luego use el comando docker-enter <container-id>para ingresar al contenedor.

Hiperfocus
fuente
Esta es la manera correcta. Ver el blog .
Jesse Glick
55
Con docker 1.3, hay un nuevo comando docker exec. Esto le permite ingresar a una ventana acoplable en ejecución: docker exec -it <container-id> bash(vea mi respuesta a continuación)
Michael_Scharf
55
¿ docker-enterTodavía existe? Me da command not found.
Snowcrash
22

Actualizar

A partir de docker 0.9, para que los pasos a continuación funcionen, ahora uno tiene que actualizar el /etc/default/dockerarchivo con la '-e lxc'opción de inicio de docker daemon antes de reiniciar el demonio (hice esto reiniciando el host).

actualizar al archivo / etc / default / docker

Todo esto es porque ...

... [docker 0.9] contiene una nueva abstracción de "controlador de motor" para hacer posible el uso de otra API que no sea LXC para iniciar contenedores. También proporciona un nuevo controlador de motor basado en una nueva biblioteca API (libcontainer) que puede manejar Grupos de Control sin usar herramientas LXC. El problema principal es que si confía en lxc-attach para realizar acciones en su contenedor, como iniciar un shell dentro del contenedor, que es increíblemente útil para el entorno de desarrollo ...

fuente

Tenga en cuenta que esto evitará que la nueva función opcional de conexión en red de solo host del docker 0.11 "funcione" y solo verá la interfaz de bucle invertido. informe de error


Resulta que la solución a una pregunta diferente también fue la solución a esta:

... puede usar docker ps -notruncpara obtener la identificación completa del contenedor lxc y luego usar lxc-attach -n <container_id>run bash en ese contenedor como root.

Actualización: pronto tendrá que usar en ps --no-trunclugar de lo ps -notruncque está en desuso.

ingrese la descripción de la imagen aquí Encuentra la ID del contenedor completo

ingrese la descripción de la imagen aquí Ingrese el comando adjunto lxc.

ingrese la descripción de la imagen aquí Arriba muestra mi proceso de apache ejecutándose que inició Docker.

Programador
fuente
Entonces, no hay forma de hacer esto con solo Docker, ¿verdad? Personalmente prefiero no mezclarme en LXC.
qkrijger
¿Hay alguna forma de ejecutar un comando con lxc-attach para iniciar el bash? ¡¡gracias!!
joselo
@qkrijger hasta donde yo sé, eso es correcto. ¿Por qué preocuparse por "mezclar" LXC? Te das cuenta de que Docker está construido sobre LXC ¿verdad?
Programador
@joselo No entiendo tu pregunta, pero ¿te sugiero que crees una nueva publicación con más detalles? Hay muchas formas de iniciar un proceso de acoplador, como con bash o como demonio con -d, etc.
Programador
@programster sí, me doy cuenta de eso :) Aún así, usar LXC directamente en combinación con Docker se siente como pirateo. Divertido, pero no realmente mantenible. En general, se debe codificar en la capa de abstracción en la que se eligió trabajar. Si realmente necesita LXC, podría ser el momento de una solicitud de extracción en Docker :)
qkrijger
7

Primer paso para obtener la identificación del contenedor:

docker ps

Esto te mostrará algo como

ID DE CONTENEDOR MANDO DE IMAGEN ESTADO CREADO NOMBRES DE PUERTOS

1170fe9e9460 localhost: 5000 / python: env-7e847468c4d73a0f35e9c5164046ad88 "./run_notebook.sh" Hace 26 segundos Arriba 25 segundos 0.0.0.0:8989->9999/tcp SLURM_TASK-303337_0

1170fe9e9460 es la identificación del contenedor en este caso.

En segundo lugar , ingrese a la ventana acoplable:

docker exec -it [container_id] bash

entonces en el caso anterior: docker exec -it 1170fe9e9460 bash

patapouf_ai
fuente
5

¿Qué pasa con ejecutar tmux / GNU Screen dentro del contenedor? Parece la forma más sencilla de acceder a tantos vty como desee con un simple:

$ docker attach {container id}
cig0
fuente
Esta es una solución correcta si sabe que querrá obtener acceso a un contenedor (por ejemplo, para depurarlo), pero esto no ayudaría a OP, quien afirma que quiere mirar alrededor de un contenedor existente.
Luca Spiller
1
Mi problema con esta respuesta es que la gente ya ha preguntado sobre el uso docker attachy señalé que:...the attach command attaches to the running tty, not a new one, hence the question title is "...with new TTY"
Programster
Bueno, si el contenedor ya se está ejecutando, esta solución no lo ayudará, pero si previamente se ocupó de dejar un multiplexor en funcionamiento, no necesitará ttys adicionales ... De hecho, desde que comencé a usar tmux, uso un tty y solo uno para hacer todo lo que necesito, ya que una vez en tmux puedo generar tantos vtys como quiera.
cig0
4

nsenterhace eso. Sin embargo, también necesitaba ingresar a un contenedor de una manera simple y nsenter no era suficiente para mis necesidades. Estaba defectuoso en algunas ocasiones (la pantalla negra más la bandera -wd no funcionaban) Además, quería iniciar sesión como usuario específico y en un directorio específico.

Terminé haciendo mi propia herramienta para ingresar contenedores. Puede encontrarlo en: https://github.com/Pithikos/docker-enter

Su uso es tan fácil como

./docker-enter [-u <user>] [-d <directory>] <container ID>
Pithikos
fuente
Solo lo intenté, ¡genial! En ubuntu tuve que ejecutar sudo apt-get build-essential -y gcc docker-enter.c -o docker-enter sudo ./docker-enter <short-container-id> Es bueno que no tenga que obtener la identificación completa como con lxc-attach -n Codebase es lo suficientemente corto como para que uno pueda escanear todo rápidamente para buscar cualquier cosa maliciosa.
Programador
Puse un ebuild disponible en gentoo en github.com/steveeJ/personal-portage-overlay como app-emulation / docker-enter.
stefanjunker
He agregado un tutorial / script para esto automático para usuarios de ubuntu en programster.blogspot.co.uk/2014/01/…
Programster
2

La forma "nsinit" es:

instalar nsinit

git clone git@github.com:dotcloud/docker.git
cd docker
make shell

desde el interior del contenedor:

go install github.com/dotcloud/docker/pkg/libcontainer/nsinit/nsinit

desde afuera:

docker cp id_docker_container:/go/bin/nsinit /root/

úsalo

cd /var/lib/docker/execdriver/native/<container_id>/
nsinit exec bash
Ivailo Bardarov
fuente
2
docker exec -t -i container_name /bin/bash

Te llevará a la consola de contenedores.

Danstan
fuente
Aterricé en esta pregunta porque tenía el mismo problema. La respuesta que parece similar no funcionó para mí hasta que modifiqué. Sin embargo, puedo eliminar esto.
Danstan
2
docker exec -ti 'CONTAINER_NAME' sh

or

docker exec -ti 'CONTAINER_ID' sh
Flavio
fuente
1

Comencé powershell en un microsoft / iis run como daemon usando

docker exec -it <nameOfContainer> powershell
Ahmed Samir
fuente
Parece que la pregunta era sobre un contenedor basado en Linux. Es probable que esta respuesta solo funcione si tiene un contenedor basado en Windows, o si tiene instalada la versión .NET Core de PowerShell, por ejemplo, PowerShell 6 o posterior.
Manfred el
0

En Windows 10 , tengo docker instalado. Estoy ejecutando Jnekins en un contenedor y encontré el mismo mensaje de error. Aquí hay una guía paso a paso para resolver este problema:

Paso 1: Abra gitbash y ejecute docker run -p 8080: 8080 -p 50000: 50000 jenkins.

Paso 2: abre una nueva terminal.

Paso 3: Haz "docker ps" para obtener una lista del contenedor en ejecución. Copie la identificación del contenedor.

Paso 4: Ahora, si haces "docker exec -it {container id} sh" o "docker exec -it {container id} bash", recibirás un mensaje de error similar a "el dispositivo de entrada no es un TTY. Si eres usando mintty, intente anteponer el comando con 'winpty' "

Paso 5: Ejecute el comando " $ winpty docker exec -it {container id} sh "

vola !! Ahora estás dentro de la terminal.

Dev 00721
fuente