¿Cómo me meto en la carcasa de un contenedor Docker?


1163

Estoy empezando a trabajar con Docker. Estoy usando la imagen base de WordPress y docker-compose.

Estoy tratando de ingresar a uno de los contenedores para inspeccionar los archivos / directorios que se crearon durante la compilación inicial. Traté de correr docker-compose run containername ls -la, pero eso no hizo nada. Incluso si lo hiciera, prefiero tener una consola donde pueda atravesar la estructura del directorio, en lugar de ejecutar un solo comando. ¿Cuál es la forma correcta de hacer esto con Docker?


Por lo tanto, parece que la respuesta es docker attach Pero, ¿cómo puedo llegar a eso desde docker-compose?
Andrew

3
Use docker exec askubuntu.com/a/543057/35816 . Obtenga la identificación del contenedor usandodocker ps
Mauricio Scheffer

26
sudo docker run -it --entrypoint /bin/bash <container_name>te mete en el contenedor de forma interactiva. Entonces uno puede inspeccionar el sistema de archivos en el contenedor usandocd <path>
Sergei

Respuestas:


1736

docker attachle permitirá conectarse a su contenedor Docker, pero esto no es realmente lo mismo que ssh. Si su contenedor está ejecutando un servidor web, por ejemplo, docker attachprobablemente lo conectará a la salida estándar del proceso del servidor web. No necesariamente te dará una concha.

El docker execcomando es probablemente lo que estás buscando; Esto le permitirá ejecutar comandos arbitrarios dentro de un contenedor existente. Por ejemplo:

docker exec -it <mycontainer> bash

Por supuesto, cualquier comando que esté ejecutando debe existir en el sistema de archivos del contenedor.

En el comando anterior se <mycontainer>encuentra el nombre o ID del contenedor de destino. No importa si estás usando o no docker compose; simplemente ejecute docker psy use la ID (una cadena hexadecimal que se muestra en la primera columna) o el nombre (que se muestra en la columna final). Por ejemplo, dado:

$ docker ps
d2d4a89aaee9        larsks/mini-httpd   "mini_httpd -d /cont   7 days ago          Up 7 days                               web                 

Puedo correr:

$ docker exec -it web ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
18: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:3/64 scope link 
       valid_lft forever preferred_lft forever

Podría lograr lo mismo ejecutando:

$ docker exec -it d2d4a89aaee9 ip addr

Del mismo modo, podría comenzar una cáscara en el contenedor;

$ docker exec -it web sh
/ # echo This is inside the container.
This is inside the container.
/ # exit
$

76
Además, docker execsolo funciona en contenedores en ejecución (de lo contrario, use docker run -it --entrypoint /bin/basho similar).
L0j1k

59
para su conveniencia, -ites una combinación de -iy -tque es --interactive("Mantenga STDIN abierto incluso si no está adjunto") respectivamente --tty("Asigne un pseudo-TTY").
Adrian Föder

23
En los contenedores basados ​​en Alpine Linux, es posible que no tenga bash, por lo tanto, use sh en su lugar.
Robin Green

99
@ L0j1k es docker run -it --entrypoint /bin/bash <imageid> --any --more --args, solo para aclarar a las personas
Alexander Mills

2
@AlexanderMills Sí, y para aclarar más, los --any --more --argsque tiene serán alimentados a lo que la imagen haya definido como su CMDy no Docker (o si su imagen solo define un ENTRYPOINTy no CMD, entonces estas opciones se incorporarán /bin/bashcomo ha especificado aquí ) Entonces, por ejemplo, cualquier otra docker runopción (por ejemplo --net "host") debe ir antes que <imageid>.
L0j1k

302

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

docker exec -t -i container_name /bin/bash

o

docker exec -ti container_name /bin/bash

o

docker exec -ti container_name sh

¿Presumiendo que es un contenedor de Linux?
Peter Mortensen

55
/ bin / bash no era necesario solo bash lo hizo por mí
Anand Varkey Philips

66
Preferiría en docker exec -itlugar dedocker exec -t -i
VaTo

¿Cuál es la diferencia @ Vato?
AATHITH RAJENDRAN

@AATHITHRAJENDRANI prefiero una forma más corta del comando en lugar de tener dos banderas, puede incluir esas dos opciones en el mismo argumento -it.
VaTo

85

Digamos que, por razones que son propias, realmente desea utilizar SSH. Toma unos pocos pasos, pero se puede hacer. Estos son los comandos que ejecutaría dentro del contenedor para configurarlo ...

apt-get update
apt-get install openssh-server

mkdir /var/run/sshd
chmod 0755 /var/run/sshd
/usr/sbin/sshd

useradd --create-home --shell /bin/bash --groups sudo username ## includes 'sudo'
passwd username ## Enter a password

apt-get install x11-apps ## X11 demo applications (optional)
ifconfig | awk '/inet addr/{print substr($2,6)}' ## Display IP address (optional)

Ahora incluso puede ejecutar aplicaciones gráficas (si están instaladas en el contenedor) utilizando el reenvío X11 al cliente SSH:

ssh -X username@IPADDRESS
xeyes ## run an X11 demo app in the client

Aquí hay algunos recursos relacionados:


34

Si está buscando una respuesta específica de Docker Compose como yo, proporciona una manera fácil de ingresar sin tener que buscar la ID del contenedor generado.

docker-compose exectoma el nombre del servicio según su docker-compose.ymlarchivo.

Entonces, para obtener un shell Bash para su servicio 'web', puede hacer:

$ docker-compose exec web bash

docker-compose runfunciona bien, si su contenedor aún no existe.
Paul

23

Aviso : esta respuesta promueve una herramienta que he escrito.

He creado un servidor SSH en contenedores que puede 'pegar' a cualquier contenedor en ejecución. De esta manera puedes crear composiciones con cada contenedor. El único requisito es que el contenedor tenga Bash.

El siguiente ejemplo iniciaría un servidor SSH conectado a un contenedor con el nombre 'my-container'.

docker run -d -p 2222:22 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e CONTAINER=my-container -e AUTH_MECHANISM=noAuth \
  jeroenpeeters/docker-ssh

ssh localhost -p 2222

Cuando se conecte a este servicio SSH (con su cliente SSH de elección), se iniciará una sesión Bash en el contenedor con el nombre 'my-container'.

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


1
Eso es muy dulce La gran ventaja de hacerlo de esta manera es que obtienes un terminal completamente funcional. Cuando utilicé el enfoque "docker exec", no pude borrar el contenido del terminal, lessestaba mostrando una advertencia cada vez que lo ejecutaba, etc. Usar el contenedor de Jeroen me está dando una experiencia mucho mejor hasta ahora. Solo asegúrate de revisar la documentación . El comando de muestra en la respuesta ya no parece válido.
Rafał G.

1
Es una gran herramienta. ¿Sabes cómo puedo usarlo como un agente de acoplamiento de tuberías de jenkins? Quiero que Jenkins transfiera algunos archivos por SCP a un host remoto y los ejecute con SSH
Gilson

21

Si está utilizando Docker en Windows y desea obtener acceso de shell a un contenedor, use esto:

winpty docker exec -it <container_id> sh

Lo más probable es que ya tenga instalado Git Bash . Si no lo hace, asegúrese de instalarlo.


1
Presume un contenedor Docker de Linux?
Peter Mortensen

1
docker exec -ti <container_id> cmd funciona bien
PBo

17

Si el contenedor ya ha salido (tal vez debido a algún error), puede hacer

$ docker run --rm -it --entrypoint /bin/ash image_name

o

$ docker run --rm -it --entrypoint /bin/sh image_name

o

$ docker run --rm -it --entrypoint /bin/bash image_name

para crear un nuevo contenedor y ponerle un caparazón. Como especificó --rm, el contenedor se eliminaría cuando salga del shell.


16

En algunos casos, su imagen puede estar basada en Alpine. En este caso arrojará:

OCI runtime exec falló: exec falló: container_linux.go: 348: el inicio del proceso del contenedor provocó "exec: \" bash \ ": archivo ejecutable no encontrado en $ PATH": desconocido

Porque /bin/bashno existe En lugar de esto, debes usar:

docker exec -it 9f7d99aa6625 ash

o

docker exec -it 9f7d99aa6625 sh

15

SSH en un contenedor Docker con este comando:

sudo docker exec -i -t (container ID) bash

12

Para conectarse a cmd en un contenedor de Windows, use

docker exec -it d8c25fde2769 cmd

Donde d8c25fde2769 es la identificación del contenedor.


11

Es simple !

Enumere todas sus imágenes de Docker:

sudo docker images

En mi sistema mostró el siguiente resultado:

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
bash                latest              922b9cc3ea5e        9 hours ago
14.03 MB
ubuntu              latest              7feff7652c69        5 weeks ago         81.15 MB

Tengo dos imágenes Docker en mi PC. Digamos que quiero ejecutar el primero.

sudo docker run -i -t ubuntu:latest /bin/bash

Esto le dará el control terminal del contenedor. Ahora puede hacer todo tipo de operaciones de shell dentro del contenedor. Al igual que hacerlo, lsgenerará todas las carpetas en la raíz del sistema de archivos.

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

11

Para inspeccionar archivos, ejecute docker run -it <image> /bin/shpara obtener una terminal interactiva. La lista de imágenes se puede obtener por docker images. Al contrario de docker execesta solución, también funciona en caso de que una imagen no se inicie (o se cierre inmediatamente después de ejecutarse).


¿Presumiendo una imagen Docker de Linux?
Peter Mortensen

10

Solución interior

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

vieja respuesta

Hemos puesto este fragmento en ~/.profile:

goinside(){
    docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f goinside

Esto no solo hace que todos puedan ingresar a un contenedor con:

goinside containername

También resuelve un problema de larga duración sobre los tamaños fijos de terminales de contenedores Docker . Lo cual es muy molesto si lo enfrentas.

Además, si sigue el enlace, también tendrá que completar el comando para los nombres de los contenedores de la ventana acoplable.


1
Gracias. Funciona de maravilla, al menos para aquellas imágenes que ya tienen bash incluido. No podría funcionar para imágenes basadas alpinos, sin embargo, se puede fijar con una función diferente escrito específicamente para sh / ceniza etc
Gaurav Bhaskar

8
$ docker exec -it <Container-Id> /bin/bash

O dependiendo del caparazón, puede ser

$ docker exec -it <Container-Id> /bin/sh

Puede obtener el ID del contenedor a través del docker pscomando

-i = interactivo

-t = para asignar un psuedo-TTY


8

He creado una función de terminal para facilitar el acceso a la terminal del contenedor. Quizás también sea útil para ustedes:

Entonces el resultado es, en lugar de escribir:

docker exec -it [container_id] /bin/bash

escribirás:

dbash [container_id]

Ponga lo siguiente en su ~ / .bash_profile (o cualquier otra cosa que funcione para usted), luego abra una nueva ventana de terminal y disfrute del acceso directo:

#usage: dbash [container_id]
dbash() {
    docker exec -it "$1" /bin/bash
}

7

puede interactuar con la terminal en el contenedor acoplable pasando la opción -ti

docker run --rm -ti <image-name>
eg: docker run --rm -ti ubuntu

-t significa terminal -i significa interactivo


6

docker execDefinitivamente será una solución. Una manera fácil de trabajar con la pregunta que hizo es montando el directorio dentro de Docker en el directorio del sistema local .

Para que pueda ver los cambios en la ruta local al instante.

docker run -v /Users/<path>:/<container path> 

1
su comando en realidad está montando el directorio del host en el contenedor.
Demonbane

¡Si! Realice una copia de seguridad en otro directorio y luego monte el volumen, luego mueva la copia de seguridad a la carpeta montada.
Pratik

6

Utilizar:

docker attach <container name/id here>

La otra forma, aunque existe un peligro, es usar attach, pero si Ctrl+ Cpara salir de la sesión, también detendrá el contenedor. Si solo quieres ver lo que está sucediendo, úsalo docker logs -f.

:~$ docker attach --help
Usage:  docker attach [OPTIONS] CONTAINER

Attach to a running container

Options:
      --detach-keys string   Override the key sequence for detaching a container
      --help                 Print usage
      --no-stdin             Do not attach STDIN
      --sig-proxy            Proxy all received signals to the process (default true)


4

Si tiene instalado Docker Kitematic, puede usar la GUI. Abra Kitematicdesde el icono de Docker y en la Kitematicventana seleccione su contenedor, y luego haga clic en el execicono.

También puede ver el registro del contenedor y mucha información del contenedor (en la pestaña de configuración) en esta GUI.

Seleccione Kitematic del menú

Haga clic en exec


2

En mi caso, por alguna razón (es) necesito verificar toda la información involucrada en la red en cada contenedor. Entonces, los siguientes comandos deben ser válidos en un contenedor ...

ip
route
netstat
ps
...

Revisé todas estas respuestas, ninguna fue útil para mí. He buscado información en otros sitios web. No agregaré un súper enlace aquí, ya que no está escrito en inglés. Así que acabo de publicar esta publicación con una solución de resumen para las personas que tienen los mismos requisitos que yo.

Digamos que tiene un contenedor en ejecución llamado prueba de luz. Sigue los pasos a continuación.

  • docker inspect light-test -f {{.NetworkSettings.SandboxKey}}. Este comando recibirá respuesta como /var/run/docker/netns/xxxx.
  • Entonces ln -s /var/run/docker/netns/xxxx /var/run/netns/xxxx. Es posible que el directorio no exista, mkdir /var/run/netnsprimero.
  • Ahora puede ejecutar ip netns exec xxxx ip addr showpara explorar el mundo de la red en contenedor.

PD. xxxxes siempre el mismo valor recibido del primer comando. Y, por supuesto, cualquier otro comando es válido, es decir ip netns exec xxxx netstat -antp|grep 8080.


1

Otra opción es usar nsenter .

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

2
Hay una serie de problemas con nsenter. La primera es que requiere que tengas acceso físico al host de Docker, lo cual no es un hecho (es posible que estés trabajando con una API de Docker remota). Además, ejecutar bajo lo nsenterexime de varias de las restricciones de seguridad y recursos que Docker establece (que puede ser un profesional o un estafador, dependiendo de su entorno).
Larsks

1
Incluso el autor de nsenter dice que use docker execestos días.
L0j1k

1
@larsks Sí, ambos tienen sus propios beneficios. Por ejemplo, este es un beneficio de nsenter over docker exec. docker execme parece más elegante.
xuhdev

2
@ L0j1k Para ser menos confuso: la publicación que ha referido no es del autor de nsenter, sino del autor de una imagen de Docker que ejecuta nsenter.
xuhdev

1

Si está usando Docker Compose, esto lo llevará dentro de un contenedor Docker.

docker-compose run container_name /bin/bash

Dentro del contenedor lo llevará a WORKDIR definido en el Dockerfile. Puedes cambiar tu directorio de trabajo por

WORKDIR directory_path # E.g  /usr/src -> container's path

0

Para ejecutar en un contenedor en ejecución llamado test, a continuación se muestran los siguientes comandos

Si el contenedor tiene bashcáscara

docker exec -it test /bin/bash

Si el contenedor tiene bournecaparazón y la mayoría de los casos está presente

docker run -it test /bin/sh

-3

Para docker-compose up (Docker4Drupal)

docker-compose exec php bash

Yo uso Docker para Drupal en una computadora portátil Linux. Después de ejecutar el contenedor, uso ' docker-compose exec php bash' para conectarme con el contenedor y poder ejecutar comandos drush. Funciona bien para mí.

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.