在Docker容器内进行操作的attach和exec的区别是什么?
根据Hidekuro先生的评论进行修正。
连接到正在运行的Docker容器中的shell的方法。
有以下两种方法可以在不在容器内启动sshd的情况下连接到shell。
-
- 进入 Docker 容器名为”コンテナ名”的容器
- 运行 Docker 容器名为”コンテナ名”的容器,并执行 /bin/bash 命令
那么,这两者之间有什么区别呢?
因此,我来整理一下。
docker attach 容器名称
在这种情况下,是将图像连接到Docker容器中已经启动的Shell的标准输出吗?
连接到容器中正在运行的PID为1的进程的标准输入/输出(STDIN/STDOUT)。
使用Docker执行以下命令并进入容器:docker exec -it コンテナ名 /bin/bash
我可以在这边的Docker容器中执行任意命令。
关于-it选项的含义似乎是如下所述。
オプション名内容i標準入力(STDIN)を開いたままにするt擬似ttyに接続する。ディスプレイ(STDOUT)をつなぐイメージ
(结果)根据登录方法的不同所产生的影响
似乎在`attach`和`exec`中执行`exit`命令时的行为是不同的。
- (補足) 以下の様な形でnodejs001コンテナを立ち上げている
sudo docker run -d --name nodejs001 --hostname nodejs001 -p 80:80 -i -t node /bin/bash
嗯,很普通。
端口转发或者是由于偶尔启动的容器的原因,所以不用在意。
在attach的情况下
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55905169b4b0 node "/bin/bash" 29 hours ago Up 11 minutes 0.0.0.0:80->80/tcp nodejs001
$ sudo docker attach nodejs001
root@nodejs001:/#
root@nodejs001:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 13:23 ? 00:00:00 /bin/bash
root 12 1 0 13:35 ? 00:00:00 ps -ef
root@nodejs001:/# exit
exit
sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55905169b4b0 node "/bin/bash" 29 hours ago Exited (0) 4 seconds ago nodejs001
如您所见,对于attach的情况,它是将标准输入输出与已在容器中运行的PID=1的/bin/bash连接起来。
当退出时,容器本身将停止运行。(因为主要进程 (PID=1) 结束了吗?)
在exec的情况下
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55905169b4b0 node "/bin/bash" 29 hours ago Up 32 seconds 0.0.0.0:80->80/tcp nodejs001
$ sudo docker exec -it nodejs001 /bin/bash
root@nodejs001:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 13:40 ? 00:00:00 /bin/bash
root 6 0 0 13:41 ? 00:00:00 /bin/bash
root 11 6 0 13:41 ? 00:00:00 ps -ef
root@nodejs001:/# exit
exit
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55905169b4b0 node "/bin/bash" 29 hours ago Up About a minute 0.0.0.0:80->80/tcp nodejs001
这是一个新的/bin/bash进程正在运行,它在那里进行标准输入输出。
即使退出并执行了exec命令时启动的/bin/bash进程会结束,但容器不会停止。
在使用exec和attach时应该选择哪个。(Conclusion)
如果是个人的话,请随意。
如果你实际上在使用面向外部的服务或与他人共享同一个容器,我认为使用exec命令会更好,因为这样容器不太可能意外停止。
嗯,就从为自己使用的Shell进程的角度来说,我觉得用exec的方式更为合适,不要依赖他人,自己确保自己。