it-swarm.dev

docker attach和docker exec之间的区别

两者都能够在容器中执行命令。两者都可以分离容器。

那么docker exec和docker attach之间的真正区别是什么?

59
MJL

有一个 commit PR 添加到doc:

注意: 此命令(attach)不用于在容器中运行新进程。见:docker exec

答案“ Docker。如何在运行容器(run -d)中获取bash\ssh? ”说明了区别:

(docker> = 1.3)如果我们使用 docker attach 我们只能使用一个Shell实例
因此,如果我们想要使用容器Shell的新实例打开新终端,我们只需要运行 docker exec

如果docker容器是使用/bin/bash命令启动的,则可以使用attach访问它,如果没有,则需要execute命令使用exec在容器内创建bash实例。

本期 中所述:

  • Attach不是用于在容器中运行额外的东西,而是用于附加到正在运行的进程。
  • docker exec”专门用于在已启动的容器中运行新事物,无论是Shell还是其他进程。

同样的问题增加了:

虽然attach没有很好地命名,特别是因为LXC命令lxc-attach(更像是docker exec <container> /bin/sh,但LXC特定),它确实有一个特定的目的,即将字面上附加到Docker启动的进程。
根据进程的不同,行为可能会有所不同 ,例如附加到/bin/bash会给你一个Shell,但是附加到redis-server就像你刚刚直接启动redis一样没有守护进程。

68
VonC

当使用/ bin/bash启动容器时,它变为容器 PID 1 并且docker attach用于获取容器的PID 1内部。所以 docker attach <container-id> 将带你进入bash终端,就像我们在启动容器时提到的PID 1一样。从容器中退出将停止容器。

而在 docker exec 命令中,您可以指定要输入的Shell。它不会将您带到容器的PID 1。它将为bash创建一个新进程。 docker exec -it <container-id> bash 。从容器中退出不会阻止容器。

您还可以使用 nsenter 输入容器内部。 nsenter -m -u -n -p -i -t <容器的pid> 您可以使用以下命令找到容器的PID:docker inspect <container-id> | grep PID

注意: 如果你用-d标志启动了容器,那么退出容器将不会停止容器,无论你使用attach还是exec进入容器。

12
Samrat Priyadarshi

Docker exec在容器环境中执行新命令/创建新进程,而docker attach只是将容器内主进程(带PID 1)的标准输入/输出/错误连接到相应的标准输入/输出/当前错误终端(用于运行命令的终端)。

容器是一个隔离的环境,其中一些进程在环境中运行。具体来说,容器有自己的文件系统空间和PID空间,它们与Host和其他容器隔离。当使用“docker run -it ...”启动容器时,主进程将具有伪tty并且STDIN保持打开状态。在tty模式下连接时,您可以使用可配置的键序列从容器中分离(并使其保持运行)。默认序列是CTRL-p CTRL-q。您可以使用--detach-keys选项或配置文件配置密钥序列。您可以使用docker attach重新连接到分离的容器。

Docker exec只是在容器的环境中启动一个新进程,即属于容器的PID空间。

例如,如果使用“docker run -dit XXX/bin/bash”启动容器,则可以使用两个不同的终端连接到容器(主进程)。当您在一个终端输入时,您可以看到它出现在另一个终端中,因为两个终端都连接到相同的tty。小心你现在在容器的主进程中,如果你输入“exit”,你将退出容器( 所以要小心,使用分离键分离 ),你会看到两个终端都退出。但是如果你在两个终端中运行“docker exec -it XXX/bin/bash”,你已经在容器内启动了两个新进程,它们彼此之间以及与主进程无关,你可以安全地从它们中退出。

0
Michael.Sun