docker run
命令新建容器常常采用-d
flag,我们如果需要进入容器操作,常会用到docker attach
命令或docker exec
命令,实际使用中我们一般使用后者搭配-it
flag,因为后者可以采用exit
退出并且保持容器在后台运行,而前者exit
退出会导致容器停止。attach 可以将当前终端的标准输入、标准输出和标准错误连接到指定的容器中,可以显示容器 ENTRYPOINT/CMD 进程的输出,它还有两种主要的退出方式,分别是^C
和^P^Q
(注意两者连用)。更多详细解释请参考深入探究docker attach的退出方式和docker container attach。
^P^Q
只能用于run命令-it
flag的情况,退出容器并保持后台运行;^C
的情况比较复杂,和-i
-t
以及attach命令的--sig-proxy
参数都有关系,当存在-t
flag 的时候,该参数无效。
demo0:$ docker run -di --name demo0 alpine /bin/sh $ docker attach demo0 # 没有任何输出 ls # 输出容器内根目录下的文件 ^C # --sig-proxy 默认为true,^C 发送SIGINT给容器中PID为1的进程,即sh,但sh不对信号做任何反应,容器保持运行,无法退出。 $ docker attach --sig-proxy=false demo0 ^C # --sig-proxy 设置为false,^C 发送给attach进程,attach停止,容器保持后台运行。
demo1:
$ docker run -dt --name demo1 alpine /bin/sh $ docker attach demo1 ^C # --sig-proxy 无效,没有-i flag进行交互,^C 直接发送给attach,attach停止,容器保持后台运行。
demo2:
$ docker run -dit --name demo2 alpine /bin/sh $ docker attach demo2 ^C # --sig-proxy 无效,^C 发送指令给sh,和demo0类似,容器保持运行,无法退出。
topdemo0:
$ docker run -di --name topdemo0 alpine top -b $ docker attach topdemo0 # 有top输出 ls # 没有反应,因为attach命令从容器 ENTRYPOINT/CMD 进入,此时被top占据,不接受任何输入。 ^C # --sig-proxy 默认为true,^C 发送给top,top停止导致容器停止并退出。 $ docker attach --sig-proxy=false topdemo0 ^C # --sig-proxy 设置为false,和demo0类似,容器保持后台运行。
topdemo1:
$ docker run -dt --name topdemo1 alpine top -b $ docker attach topdemo1 ^C # 和demo1类似,容器保持后台运行。
topdemo2:
$ docker run -dit --name topdemo2 alpine top -b $ docker attach topdemo2 ^C # 和topdemo0类似,容器停止并退出。