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?
Respuestas:
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/bash
comando, puede acceder a él usando adjuntar, de lo contrario, debe ejecutar el comando para crear una instancia de bash dentro del contenedor usandoexec
.
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
attach
bien no está bien nombrado, particularmente debido al comando LXClxc-attach
(que es más parecidodocker 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/bash
le dará un shell, pero adjuntar a redis-server será como si acabara de iniciar redis directamente sin demonizar.
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.
Como dijo Michael Sun en su respuesta
docker exec
ejecuta un nuevo comando / crea un nuevo proceso en el entorno del contenedor, mientras quedocker attach
simplemente 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 busybox
si aún no está presente. Luego creará un contenedor con el nombre busybox
usando 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
, PPID
y otros valores serán diferentes en su caso. Se pueden usar otras herramientas y servicios públicos, así como pstree
, top
, htop
para ver la lista de PID
y PPID
.
El PID
y PPID
significa 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-q
secuencia. 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 PPID
de los dos procesos será diferente. De hecho, la PPID
del segundo proceso será la misma que PID
la 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 busybox
en 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 PPID
del primer y tercer proceso será el mismo, lo que confirma que docker exec
crea un nuevo proceso en el entorno del contenedor mientras que docker attach
solo 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.
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. .
nsenter
. ¿Puedes elaborar? Explicar las opciones estaría en orden. ¿Por qué no introducir todos los espacios de nombres? ¿Por qué estos en particular?