例如我运行
docker run --rm --name mycontainer -p 8080:8080 myrepo/myimage
然后我看到我的应用程序的输出,一切正常。然后我按 Ctrl + C 但容器仍在运行,我被迫明确停止并删除它:
docker rm -f <container_id>
甚至更糟:
docker stop <container_id>
docker rm <container_id>
有没有办法自动完成?如果没有,那就没关系。
PS:所有停止的容器仍保留在硬盘驱动器上的目的是什么?!
答案 0 :(得分:1)
所有停止的容器仍保留在硬盘驱动器上的目的是什么?!
运行容器包括您运行的进程以及命名空间环境,以便在(网络,pid,文件系统等)内运行该进程。
已停止的容器具有容器特定的读/写文件系统层,运行容器时包含的任何配置(例如环境变量),以及使用json日志记录驱动程序时的日志(默认)。
删除容器会删除RW文件系统层,json日志和配置,这也会从已停止的容器列表中删除容器。这是一个永久性操作,因此不要删除您可能希望稍后检查或重新启动的容器。
我按 Ctrl + C 但容器仍在运行,我被迫明确停止并将其删除
首先,确保您运行的是当前版本的docker。我相信大约在1.13左右,他们将--rm
选项的处理从客户端迁移到服务器。接下来,确保您的应用程序处理 Ctrl + C 命令。在shell脚本中,这将是SIGTERM
的处理程序。您还需要以交互方式运行容器,以便将键盘输入发送到容器,即-it
标志。完成所有这三个后,您应该看到容器自动清理:
docker run --rm -it --name mycontainer -p 8080:8080 myrepo/myimage
后跟 Ctrl + C 。 -it
会将SIGTERM
传递给容器,然后该容器应停止进程,从而停止正在运行的容器。而--rm
将导致容器被自动删除。
如果由于某种原因您无法让容器处理SIGTERM
,那么您可以使用SIGKILL
命令发送docker kill
,该命令不会被应用程序捕获和忽略。
请注意,如果您在容器上运行docker stop
并在停止之前看到10秒的延迟,那么您的应用程序将忽略SIGTERM
。造成这种情况的一个常见原因是/bin/sh
以pid 1运行。如果您处于信号用户模式,shell默认运行时会忽略此信号,假设您处于信号用户模式。
答案 1 :(得分:-1)
默认情况下,docker以pid 1的形式运行image命令.pid 1由内核特殊处理,因为它通常用于系统初始化进程。因此,CTRL+C
/ SIGTERM
对pid 1无效。
实际的docker版本提供选项--init
以运行最小的init系统(tini
)作为pid 1.您的image命令以tini
的子项运行。由于不再是pid 1,您的图像命令将再次接受CTRL+C
。
将--init
添加到您的示例命令中,您可以使用CTRL+C
docker run --rm --init --name mycontainer -p 8080:8080 myrepo/myimage
在您的情况下不需要,只需要其他信息:您可以使用docker stop
更改来自--stop-signal SIGNAL
的信号,其中SIGNAL
是kill -L
显示的众多信号之一,例如SIGHUP
或SIGINT
。