¿Cómo obtener bash o ssh en un contenedor en ejecución en modo de fondo?

934

Quiero ssh o golpear en un contenedor acoplable en ejecución. Por favor, ver ejemplo:

$ sudo docker run -d webserver
webserver is clean image from ubuntu:14.04
$ sudo docker ps
CONTAINER ID  IMAGE            COMMAND    CREATED STATUS  PORTS          NAMES
665b4a1e17b6  webserver:latest /bin/bash  ...     ...     22/tcp, 80/tcp loving_heisenberg 

ahora quiero obtener algo como esto (ir al contenedor en ejecución):

$ sudo docker run -t -i webserver (or maybe 665b4a1e17b6 instead)
$ root@665b4a1e17b6:/# 
However when I run the line above I get new CONTAINER ID
$ root@42f1e37bd0e5:/#

Utilicé Vagrant y me gustaría tener un comportamiento similar al de vagrant ssh.

Timur Fayzrakhmanov
fuente
alternativamente sudo docker exec -i -t 665b4a1e17b6 /bin/shpara poder instalar programas y paquetes apt
fonjeekay
1
Tenga en cuenta que el uso de SSH para golpear el contenedor en ejecución es una mala práctica; consulte la justificación aquí . sudo docker exec -i -t container-name /bin/bashEs un camino a seguir.
patryk.beza

Respuestas:

1306

La respuesta es el attachcomando de Docker . Entonces, para mi ejemplo anterior, la solución será:

$ sudo docker attach 665b4a1e17b6 #by ID
or
$ sudo docker attach loving_heisenberg #by Name
$ root@665b4a1e17b6:/#

Para Docker versión 1.3 o posterior: Gracias al usuario WiR3D que sugirió otra forma de obtener el shell de un contenedor. Si usamos attach, podemos usar solo una instancia del shell. Entonces, si queremos abrir una nueva terminal con una nueva instancia del shell de un contenedor, solo necesitamos ejecutar lo siguiente:

$ sudo docker exec -i -t 665b4a1e17b6 /bin/bash #by ID

o

$ sudo docker exec -i -t loving_heisenberg /bin/bash #by Name
$ root@665b4a1e17b6:/#
Timur Fayzrakhmanov
fuente
55
Alternativamente, ejecutesudo docker attach loving_heisenberg
Thiago Perrotta
51
el comando de conexión no funciona para mí, hace que la ventana acoplable se congele ... ¿alguna idea de por qué está sucediendo?
Mo J. Mughrabi
10
Un recordatorio para los usuarios de boot2docker: eliminar sudo :)
Henno
17
-i -tigual-it
pasha.zhukov
47
Esta es una respuesta peligrosa para ser seleccionada y tan altamente votada. docker attachInvocar una instancia de MongoDB, por ejemplo, matará la instancia. Como se explica con más detalle en esta pregunta attach y execson diferentes animales.
fwc
676

Desde Docker 1.3 en adelante:

docker exec -it <containerIdOrName> bash

Básicamente, si el contenedor Docker se inició utilizando el /bin/bashcomando, puede acceder a él utilizando attach. De lo contrario, debe ejecutar el comando para crear una instancia de Bash dentro del contenedor utilizando exec.

También para salir de Bash sin dejar que Bash se ejecute en un proceso no autorizado:

exit

Sí, es así de simple.

WiR3D
fuente
Todavía no he descubierto cómo hacer que nano funcione. Pensamiento que puede involucrar docker-ssh de phusion
WiR3D
¿Hay alguna manera de configurar bash de manera predeterminada en las ventanas acoplables?
ipeacocks
@ipeacocks sí, si el RUNcomando en el dockerfile es /bin/bash. Pero depende de lo que quieras decir. Si desea ejecutar el contenedor y tienen fiesta disponible de inmediato en ese mismo terminal luego corriendo con -itdeberían hacerlo
WiR3D
10
Usar docker group es una mala práctica. Cualquier usuario que esté en el grupo de acopladores se usa esencialmente con permisos de root sin la necesidad de usar sudo. projectatomic.io/blog/2015/08/…
Maiku Mori
1
Creo que no hace mucha diferencia, desde el punto de vista de seguridad del host, si usa sudovs dockergrupo. De cualquier manera, hay un agujero de seguridad integrado en la ventana acoplable que puede proporcionar privilegios completos en el sistema de archivos del host desde el invitado, independientemente de si usa el grupo de la ventana acoplable o sudopara iniciar el contenedor.
nobar
123

Aunque el autor de la pregunta dijo específicamente que están interesados ​​en un contenedor en ejecución, también vale la pena señalar que si el contenedor no se está ejecutando, pero le gustaría ejecutarlo para hurgar, puede ejecutar:

docker run -i -t --entrypoint /bin/bash <imageID>

Adam Kalnas
fuente
10
Eso le da un contenedor diferente, al igual que la respuesta de @ kraxor.
Blaisorblade
19

Basado en la respuesta de @ Timur, he creado el siguiente script útil

Preparar

Coloque el docker-ssharchivo en su $PATHcon los siguientes contenidos

#!/bin/bash -xe

# docker container id or name might be given as a parameter
CONTAINER=$1

if [[ "$CONTAINER" == "" ]]; then
  # if no id given simply just connect to the first running container
  CONTAINER=$(docker ps | grep -Eo "^[0-9a-z]{8,}\b")
fi

# start an interactive bash inside the container
# note some containers don't have bash, then try: ash (alpine), or simply sh
# the -l at the end stands for login shell that reads profile files (read man)
docker exec -i -t $CONTAINER bash -l

Nota : Algunos contenedores no contienen bash, pero ash, shetc. En estos casos bashse reemplazarán en el script anterior.

Uso

Si solo tiene una instancia en ejecución, simplemente ejecute

$> docker-ssh 

De lo contrario, proporcione un parámetro de id de docker que obtenga de docker ps(primer col)

$> docker-ssh 50m3r4nd0m1d
Matyas
fuente
¿Puedo saber por qué necesitamos -l al final?
Nam G VU
para comenzar bash como un shell de inicio de sesión, leyendo los parámetros del entorno (descritos en la línea arriba del comando)
Matyas
13

Si su contenedor no tiene bash instalado, puede probar sh:

docker exec -it CONTAINER /bin/sh

O busque conchas en / bin primero:

docker export CONTAINER|tar -t|egrep ^bin/
laktak
fuente
¿Qué es el "cónsul" ? ¿Tienes una referencia para ello? ¿Te refieres a "consola" ?
Peter Mortensen
9

He creado un servidor SSH en contenedores que proporciona capacidades SSH a cualquier contenedor en ejecución. No necesita cambiar su contenedor. El único requisito es que el contenedor tenga bash.

Si tiene un contenedor con el nombre 'web-server1'. El siguiente comando de ejecución de docker iniciaría un segundo contenedor que proporcionaría SSH para el primer contenedor.

docker run -ti --name sshd-web-server1 -e CONTAINER=web-server1 -p 2222:22 \
-v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker \
jeroenpeeters/docker-ssh

Para obtener más sugerencias, consulte https://github.com/jeroenpeeters/docker-ssh

Jeroen Peeters
fuente
Esta debería ser la respuesta aceptada ^
Nam G VU
Por cierto, ¿cómo podemos tener .bashrc cargado automáticamente al comenzar una sesión ssh con su solución? También publicó un problema en github github.com/jeroenpeeters/docker-ssh/issues/30
Nam G VU
6

@jpetazzo tiene una publicación increíble sobre este tema . La respuesta corta sería usar nsenter:

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

PD: No te olvides de revisar la discusión en los comentarios de la publicación ...

Salud

Ricardo
fuente
1
Esa es una publicación bastante antigua que ya no es realmente necesaria . La docker execsolución de @ WiR3D es bastante más conveniente.
drevicko
4

También puede darle al contenedor Docker una dirección IP enrutable con Pipework, y luego SSH en la máquina con esa nueva dirección IP.

Esto será más "tradicional" (ssh), en lugar de usar un comando específico de la aplicación como docker attach, y eventualmente lo hará más "portátil" en todos los sistemas y versiones.

radriaanse
fuente
Por favor, agregue la forma más simple de cómo hacerlo. Para ser honesto, realmente lo necesito, pero no tengo tiempo para buscar la solución más simple para eso. ¿Podría publicar su respuesta aquí? Sería genial ..
Timur Fayzrakhmanov
2
Hay 2 formas de lograr esto, pero no es simple y se convertiría en una gran publicación. Puede consultar este enlace usted mismo, para usar tuberías o este enlace , que esencialmente logra lo mismo que las tuberías y es un poco más simple, pero debe hacerlo manualmente. Por lo tanto, depende de cuántos servidores hablen. Si no puede resolver algo más específico, avíseme. Pero tampoco tengo tiempo para escribir un tutorial completo.
radriaanse
Tienes razón: no hay una forma obvia y simple de hacerlo (gracias por los enlaces, creo que lo volveré a visitar más tarde.)
Timur Fayzrakhmanov
2
docker run -it openjdk:8

Esto funciona :-)

Kishan B
fuente
1

VE ADENTRO

instale la goinsideherramienta de línea de comandos con:

sudo npm install -g goinside

e ingrese a un contenedor acoplable con un tamaño de terminal adecuado con:

goinside docker_container_name

para más detalles mira esto .

Soorena
fuente
0

Para golpear en un contenedor en ejecución, escriba esto:

docker exec -t -i container_name /bin/bash
Agustí Sánchez
fuente
1
sin embargo
Bruni el
0

Solo para información. Si necesita iniciar sesión en un contenedor simple que no sea un demonio, debe usar los siguientes comandos:

docker start {id}
docker attach {id}
Nek
fuente
-1

si el contenedor se detiene como, por ejemplo, un contenedor de solo datos, entonces una buena solución es ejecutar un contenedor desechable cada vez que quiera adjuntarlo al contenedor de datos. En este caso, el contenedor de datos podría estar completamente vacío, ya que el contenedor temporal tendría las herramientas del sistema operativo.

$ docker run --rm --volumes-from mydata -it ubuntu bash
root@645045d3cc87:/# ls /mydata
root@645045d3cc87:/# touch /mydata/foo
root@645045d3cc87:/# exit
exit
David Dehghan
fuente