¿Es posible iniciar una sesión de shell en un contenedor en ejecución (sin ssh)


341

Ingenuamente esperaba que este comando ejecutara un shell bash en un contenedor en ejecución:

docker run "id of running container" /bin/bash

parece que no es posible, me sale el error:

2013/07/27 20:00:24 Internal server error: 404 trying to fetch remote history for 27d757283842

Entonces, si quiero ejecutar bash shell en un contenedor en ejecución (por ejemplo, para fines de diagnóstico)

¿Tengo que ejecutar un servidor SSH en él e iniciar sesión a través de ssh?


1
docker run CONTAINERestá previsto en 1.0
kolypto

77
Desde docker 1.3 realmente deberías hacer lo que se describe en esta respuesta
Thomasleveil

1
justdocker attach container_name
maxbellec

1
Parece que la segunda respuesta es mucho mejor hoy en día que la aceptada, ¿podría reconsiderar cambiar la respuesta aceptada?
jsbueno

Respuestas:


285

EDITAR: ahora puedes usar docker exec -it "id of running container" bash( doc )

Anteriormente, la respuesta a esta pregunta era:

Si realmente debe hacerlo y está en un entorno de depuración, puede hacer esto: sudo lxc-attach -n <ID> Tenga en cuenta que la identificación debe ser completa ( docker ps -notrunc).

Sin embargo, lo recomiendo en contra de esto.

aviso: -notruncestá en desuso, será reemplazado por --no-truncpronto.


1
¿Por qué me recomiendan contra eso?
Max L.

77
Recomiendo no hacerlo porque 1) requiere un kernel muy reciente, 2) está haciendo cosas fuera de la ventana acoplable, por lo que no podrá rastrearlo (registros, archivos adjuntos, etc.). Además, Docker podría usar lxc en este momento, pero no hay garantía de que lo haga para siempre.
chirrido

1
Intenta actualizar a 0.7.6. Docker todavía está usando lxc en este momento y lxc-attachdebería funcionar bien. Acabo de duplicar la comprobación y funciona para mí. (Tenga en cuenta que no funcionará con el núcleo antes de 3.8).
chirrido

2
a partir de 0.9 docker ya no se ejecuta con LXC por defecto. Tendrías que lanzar el Docker Deamon condocker -d -e lxc
kevzettler

2
Max L., su caso de uso se puede resolver con volúmenes de datos . No se ha probado ejemplo: 1) contenedor ejecuta con los registros de nginx en volumen de datos: docker run -v /var/log/nginx -name somename imagename command; 2) ejecutar otro recipiente para ver el contenido de volumen de datos: docker run -volumes-from somename -i -t busybox /bin/sh.
ciastek

615

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

docker exec -it "id of running container" bash

2
Esto funciono muy bien para mi. Muy útil además de Docker Run.
oraserrata

¿Qué sucede si realicé cambios mientras ejecuto un contenedor en ejecución y quería reflejar los cambios en línea? ¿Cuáles son las mejores prácticas?
mediaroot

Muy útil. Gracias
luongnv89

utilizar docker pspara conseguir Identificación de instancias corriendo
muón

Nota: El contenedor puede no tener bash (»exec:" bash ": archivo ejecutable no encontrado«). Use docker inspect <image>para ver qué shell está disponible. Ej docker exec -it <container id> /bin/sh. Correr en su lugar.
pixelbrackets

14

Solo haz

docker attach container_name

Como se mencionó en los comentarios, para separarlo del contenedor sin detenerlo, escriba Ctrlpentonces Ctrlq.


55
¡¡Gracias!! Eso ayudo. Y en el contexto de la pregunta real, me gustaría agregar algo. Después de depurar nuestro contenedor usando, docker attach container_nameuse ctrl py en ctrl qlugar de exit. exitel comando detiene el contenedor, donde como ctrlpy ctrl qsolo separa ese contenedor y lo mantiene en funcionamiento
phoenix

10

Como las cosas están cambiando, en este momento está utilizando la forma recomendada de acceder a un contenedor en ejecución nsenter.

Puede encontrar más información sobre este repositorio de github . Pero, en general, puede usar nsenter de esta manera:

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid

o puedes usar el envoltorio docker-enter:

docker-enter <container_name_or_ID>

Puede encontrar una buena explicación sobre el tema en la entrada del blog de Jérôme Petazzoni: ¿Por qué no necesita ejecutar sshd en los contenedores de la ventana acoplable?


desafortunadamente, las variables env están en mal estado utilizando este enfoque (si desea verificar las variables creadas por enlace). Sugiero hacer source /proc/*/environ.
Tomás Tomecek

8

Lo primero que no puedes correr

docker run "existing container" command

Debido a que este comando espera una imagen y no un contenedor , de todos modos se generaría un nuevo contenedor (por lo tanto, no el que desea ver)

Estoy de acuerdo con el hecho de que con Docker debemos esforzarnos para pensar de una manera diferente (por lo que debe encontrar formas para que no necesite iniciar sesión en el contenedor), pero todavía lo encuentro útil y así es como trabajo alrededor.

Ejecuto mis comandos a través del supervisor en modo DEAMON.

Luego ejecuto lo que llamo docker_loop.sh El contenido es más o menos esto:

#!/bin/bash
/usr/bin/supervisord
/usr/bin/supervisorctl
while ( true )
    do
    echo "Detach with Ctrl-p Ctrl-q. Dropping to shell"
    sleep 1
    /bin/bash
done

Lo que hace es que le permite "adjuntar" al contenedor y se le presentará la supervisorctlinterfaz para detener / iniciar / reiniciar y verificar los registros. Si eso no fuera suficiente, puedes Ctrl+Dy caerás en un caparazón que te permitirá echar un vistazo como si fuera un sistema normal.

TENGA EN CUENTA TAMBIÉN que este sistema no es tan seguro como tener el contenedor sin carcasa, así que tome todas las medidas necesarias para asegurar su contenedor.


5

Esté atento a esta solicitud de extracción: https://github.com/docker/docker/pull/7409

Que implementa la próxima docker exec <container_id> <command>utilidad. Cuando esté disponible, debería ser posible, por ejemplo, iniciar y detener el servicio ssh dentro de un contenedor en ejecución.

También hay nsinitque hacer esto: "nsinit proporciona una forma práctica de acceder a un shell dentro del espacio de nombres de un contenedor en ejecución" , pero parece difícil de ejecutar. https://gist.github.com/ubergarm/ed42ebbea293350c30a6


docker execaterrizó en Docker 1.3, por lo que ahora es posible crear y unirse a una nueva sesión de shell en un contenedor en ejecución
foz


1

En realidad, hay una manera de tener un caparazón en el contenedor.

Suponga que /root/run.shinicia el proceso, el administrador de procesos (supervisor) o lo que sea.

Crea /root/runme.shcon algunos trucos de gnu-screen:

# Spawn a screen with two tabs
screen -AdmS 'main' /root/run.sh
screen -S 'main' -X screen bash -l
screen -r 'main'

Ahora, tiene sus demonios en la pestaña 0, y un shell interactivo en la pestaña 1. docker attachen cualquier momento para ver qué sucede dentro del contenedor.

Otro consejo es crear una imagen de "paquete de desarrollo" encima de la imagen de producción con todas las herramientas necesarias, incluido este truco de pantalla.


1

aqui esta mi solucion

parte de DOckerfile:

...
RUN mkdir -p /opt
ADD initd.sh /opt/
RUN chmod +x /opt/initd.sh
ENTRYPOINT ["/opt/initd.sh"]

parte de "initd.sh"

#!/bin/bash
...
/etc/init.d/gearman-job-server start
/etc/init.d/supervisor start
#very important!!!
/bin/bash

después de construir la imagen, tiene dos opciones usando exec y adjuntar:

  1. con exec (que uso), ejecuta:

docker run --name $ CONTAINER_NAME -dt $ IMAGE_NAME

entonces

docker exec -it $ CONTAINER_NAME / bin / bash

y use

CTRL + D para separar

  1. con adjuntar, ejecutar:

docker run --name $ CONTAINER_NAME -dit $ IMAGE_NAME

entonces

ventana acoplable $ CONTAINER_NAME

y use

CTRL + P y CTRL + Q para separar

la diferencia entre las opciones está en el parámetro -i


1

Hay dos maneras.

Con adjuntar

$ sudo docker attach 665b4a1e17b6 #by ID

Con el ejecutivo

$ sudo docker exec - -t 665b4a1e17b6 #by ID


0

Es útil asignar nombre cuando se ejecuta el contenedor. No necesita referir container_id.

docker run --name container_name yourimage docker exec -it container_name bash


0

primero, obtenga la identificación del contenedor deseado

docker ps

obtendrás algo como esto:

CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                          PORTS                    NAMES
3ac548b6b315        frontend_react-web     "npm run start"     48 seconds ago      Up 47 seconds                   0.0.0.0:3000->3000/tcp   frontend_react-web_1

ahora copie esta ID de contenedor y ejecute el siguiente comando:

docker exec -it container_id sh

docker exec -it 3ac548b6b315 sh


-2

Tal vez te engañaste como yo a pensar en términos de máquinas virtuales al desarrollar contenedores. Mi consejo: intenta no hacerlo.

Los contenedores son como cualquier otro proceso. De hecho, es posible que desee "adjuntar" a ellos con fines de depuración (piense en / proc // env o strace -p) pero ese es un caso muy especial.

Normalmente, simplemente "ejecuta" el proceso, por lo que si desea modificar la configuración o leer los registros, simplemente cree un nuevo contenedor y asegúrese de escribir los registros fuera de él compartiendo directorios, escribiendo en stdout (para que los registros de Docker funcionen) o algo así.

Para fines de depuración, es posible que desee iniciar un shell, luego su código, luego presione CTRL-p + CTRL-q para dejar el shell intacto. De esta manera, puede volver a conectar usando:

docker attach <container_id>

Si desea depurar el contenedor porque está haciendo algo que no esperaba que hiciera, intente depurarlo: /server/596994/how-can-i-debug-a-docker-container -inicialización


Esto está completamente mal. Poder introspectar el espacio de nombres LXC en el que se ejecuta su aplicación no es un "caso muy especial", es una actividad común / diaria para cualquier desarrollador.
sleepycal

@sleepycal "cualquier desarrollador" suena un poco sesgado. En cualquier caso, uso introspección de procesos, por lo que lo mismo se aplica a los contenedores. Esa es la idea detrás de la depuración. Adjunta un depurador al proceso (que podría tener un cli). Pensar que estás "conectado" en el contenedor todavía me parece engañoso.
estani

-4

No. Esto no es posible. Use algo como supervisordobtener un servidor ssh si es necesario. Aunque, definitivamente cuestiono la necesidad.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.