diferencia entre docker attach y docker exec

81

Ambos podrán ejecutar comandos en contenedor. Ambos podrían desprender el contenedor.

Entonces, ¿cuál es la diferencia real entre docker exec y docker attach?

MJL
fuente

Respuestas:

85

Hubo un compromiso PR que se agregó al documento:

Nota: este comando ( attach) no es para ejecutar un nuevo proceso en un contenedor. Ver: docker exec.

La respuesta a " Docker. ¿Cómo obtener bash \ ssh dentro del contenedor ejecutado ( run -d)? " Ilustra la diferencia:

(Docker> = 1.3) Si usamos docker attach, podemos usar solo una instancia de shell .
Entonces, si queremos abrir una nueva terminal con una nueva instancia del shell del contenedor, solo necesitamos ejecutardocker exec

Si el contenedor de la ventana acoplable se inició usando el /bin/bashcomando, puede acceder a él usando adjuntar, de lo contrario, debe ejecutar el comando para crear una instancia de bash dentro del contenedor usando exec.

Como se menciona en este número :

  • Adjuntar no es para ejecutar una cosa adicional en un contenedor, es para adjuntar al proceso en ejecución.
  • " docker exec" es específicamente para ejecutar cosas nuevas en un contenedor ya iniciado, ya sea un shell o algún otro proceso.

El mismo tema agrega:

Si attachbien no está bien nombrado, particularmente debido al comando LXC lxc-attach(que es más parecido docker exec <container> /bin/sh, pero específico de LXC), tiene un propósito específico de adjuntarlo literalmente al proceso que inició Docker.
Dependiendo de cuál sea el proceso, el comportamiento puede ser diferente , por ejemplo, adjuntar a /bin/bashle dará un shell, pero adjuntar a redis-server será como si acabara de iniciar redis directamente sin demonizar.

VonC
fuente
23

Cuando un contenedor se inicia con / bin / bash, se convierte en el contenedor PID 1 y el acoplamiento de la ventana acoplable se usa para ingresar al PID 1 de un contenedor. Entonces, docker attach <container-id> lo llevará dentro de la terminal bash, ya que es PID 1, como mencionamos al iniciar el contenedor. Salir del contenedor lo detendrá.

Mientras que en el comando docker exec puede especificar en qué shell desea ingresar. No lo llevará al PID 1 del contenedor. Creará un nuevo proceso para bash. docker exec -it <id-contenedor> bash . Salir del contenedor no detendrá el contenedor.

También puede usar nsenter para ingresar al interior de contenedores. nsenter -m -u -n -p -i -t <pid del contenedor> Puede encontrar el PID del contenedor usando: docker inspect <container-id> | grep PID

Nota: Si ha iniciado su contenedor con la bandera -d, salir del contenedor no detendrá el contenedor, ya sea que use adjuntar o exec para entrar.

Samrat Priyadarshi
fuente
Interesante idea sobre el uso nsenter. ¿Puedes elaborar? Explicar las opciones estaría en orden. ¿Por qué no introducir todos los espacios de nombres? ¿Por qué estos en particular?
x-yuri
6

Como dijo Michael Sun en su respuesta

docker execejecuta un nuevo comando / crea un nuevo proceso en el entorno del contenedor, mientras que docker attachsimplemente conecta la entrada / salida / error estándar del proceso principal (con PID 1) dentro del contenedor a la entrada / salida / error estándar correspondiente del terminal actual (el terminal que está utilizando para ejecutar el comando).

Mi respuesta se centrará más en permitirle validar la declaración anterior y comprenderla con mayor claridad.

Abra una ventana de terminal y ejecute el comando docker run -itd --name busybox busybox /bin/sh. El comando extraerá la imagen busyboxsi aún no está presente. Luego creará un contenedor con el nombre busyboxusando esta imagen.

Puede verificar el estado de su contenedor ejecutando el comando docker ps -a | grep busybox.

Si lo ejecuta docker top busybox, debería ver una salida similar a esta.

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh

Por supuesto, el PID, PPIDy otros valores serán diferentes en su caso. Se pueden usar otras herramientas y servicios públicos, así como pstree, top, htoppara ver la lista de PIDy PPID.

El PIDy PPIDsignifica que el identificador de proceso y proceso primario de identificación. El proceso comenzó cuando creamos e iniciamos nuestro contenedor con el comando /bin/sh. Ahora, ejecute el comando docker attach busybox. Esto adjuntará el flujo de entrada / salida / error estándar del contenedor a su terminal.

Después de adjuntar el contenedor, cree una sesión de shell ejecutando el comando sh. Presione CTRL-p CTRL-qsecuencia. Esto separará la terminal del contenedor y mantendrá el contenedor en funcionamiento. Si ahora va a ejecutar docker top busybox, debería ver dos procesos en la lista.

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh
root                7737                7469                0                   11:43               pts/0               00:00:00            sh

Pero el PPIDde los dos procesos será diferente. De hecho, la PPIDdel segundo proceso será la misma que PIDla del primero. El primer proceso actúa como proceso padre para la sesión de shell que acabamos de crear.

Ahora, corre docker exec -it busybox sh. Una vez dentro del contenedor, verifique la lista de procesos en ejecución para el contenedor busyboxen otra ventana de terminal ejecutando el comando docker top busybox. Debería ver algo como esto

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh
root                7737                7469                0                   11:43               pts/0               00:00:00            sh
root                7880                7451                0                   11:45               pts/1               00:00:00            sh

El PPIDdel primer y tercer proceso será el mismo, lo que confirma que docker execcrea un nuevo proceso en el entorno del contenedor mientras que docker attachsolo conecta la entrada / salida / error estándar del proceso principal dentro del contenedor a la entrada / salida / error estándar correspondiente de la corriente. terminal.

Kartik Chauhan
fuente
5

Docker exec ejecuta un nuevo comando / crea un nuevo proceso en el entorno del contenedor, mientras que docker attach solo conecta la entrada / salida / error estándar del proceso principal (con PID 1) dentro del contenedor a la entrada / salida / error estándar correspondiente de la corriente terminal (el terminal que está utilizando para ejecutar el comando).

Un contenedor es un entorno aislado, con algunos procesos ejecutándose en el entorno. Específicamente, un contenedor tiene su propio espacio de sistema de archivos y espacio PID que están aislados del host y otros contenedores. Cuando el contenedor se inicia usando "docker run –it ...", el proceso principal tendrá un pseudo-tty y STDIN abiertos. Cuando se adjunta en el modo tty, puede desconectarse del contenedor (y dejarlo funcionando) mediante una secuencia de teclas configurable. La secuencia predeterminada es CTRL-p CTRL-q. La secuencia de teclas se configura mediante la opción --detach-keys o un archivo de configuración. Puede volver a conectarlo a un contenedor separado con la ventana acoplable adjunta.

Docker exec acaba de iniciar un nuevo proceso, dentro del entorno del contenedor, es decir, pertenece al espacio PID del contenedor.

Por ejemplo, si inicia su contenedor usando “docker run –dit XXX / bin / bash”, puede adjuntarlo al contenedor (proceso principal) usando dos terminales diferentes. Mientras ingresa en un terminal, puede ver que aparece en el otro terminal, ya que ambos terminales están conectados al mismo tty. Tenga cuidado de que ahora está en el proceso principal del contenedor, si escribe “salir”, saldrá del contenedor ( así que tenga cuidado, use las teclas de separación para desconectar ), y verá que ambos terminales salen. Pero si ejecuta "docker exec –it XXX / bin / bash" en dos terminales, ha iniciado dos procesos nuevos dentro del contenedor, y no están relacionados entre sí ni con el proceso principal, y puede salir de ellos de forma segura. .

Michael.Sun
fuente