docker stopdocker kill有什么区别?

Afaik,两者都会停止正在运行的容器。是docker stop尝试以正确的方式停止在容器内部运行的进程,而docker kill会发送终止信号吗?如果是这样,docker stop将如何知道如何正确停止正在运行的进程。 (由于每个过程的不同而异)

#1 楼


docker stop是否试图以正确的方式停止容器中运行的进程,而docker kill会发送kill信号?


基本上是的,区别很小,但在命令行参考中概述:



docker stop:停止运行容器(在宽限期后发送SIGTERM,然后发送SIGKILL)[...]容器内的主进程将收到SIGTERM,在宽限期之后,发送SIGKILL。 [强调我]


docker kill:杀死正在运行的容器(发送SIGKILL或指定的信号)[...]容器内的主进程将被发送SIGKILL或任何信号用选项--signal指定。 [强调我的]


因此,stop尝试通过发送标准POSIX信号SIGTERM来触发正常关机,而kill在默认情况下只是终止了该进程(还允许发送任何其他信号) :


SIGTERM信号被发送到进程以请求终止。与SIGKILL信号不同,该信号可以被过程捕获,解释或忽略。这允许进程执行适当的终止,从而释放资源并在适当时保存状态。应该注意的是,SIGINT与SIGTERM几乎相同。


虽然没有强制执行,但是通常希望进程能够优雅地处理SIGTERM并根据其职责执行正确的操作-这可以但是,由于正常关机尝试花费的时间长于宽限期,因此很容易失败,如果数据完整性至关重要(例如,对于数据库),则需要考虑这一点;参见例如海顿少校的SIGTERM与SIGKILL进行更详细的解释:


收到SIGTERM后,应用程序可以确定其要执行的操作。虽然大多数应用程序将清理其资源并停止运行,但有些可能不会。接收到SIGTERM时,可以将应用程序配置为执行完全不同的操作。另外,如果应用程序处于不良状态(例如,等待磁盘I / O),则它可能无法对已发送的信号进行操作。


评论


因此,如果我想对容器使用通用的关闭程序,就必须在主管/单元过程中抓住SIGTERM吗?

– CMCDragonkai
14年8月15日在9:01

这里的最佳做法是什么?我了解为什么我们要使用docker kill手动关闭以节省一些时间,但是在脚本中,通过docker stop尝试正常关闭不是总会更好吗?我仍然在脚本中看到很多docker kills。

–丹尼斯
18年6月26日在16:52

值得一提的是,默认情况下,容器的PID 1将忽略SIGTERM,从而超过了停止点。使用带有显式陷阱的入口点脚本可能会有所帮助;一个更简单的选择是使用专用的“容器初始化系统”作为入口点,docker run --init透明地进行排列而不更改映像。

–贝尼(Beni Cherniavsky)-帕斯金(Paskin)
20 May 19 '18:07



#2 楼

docker kill将突然停止主入口点进程/程序

docker stop将尝试正常停止它(礼貌地询问:P)

在两种情况下文件系统更改都将保留(在停止或杀死时),因此如果您docker start <container>,它将从那里继续。

评论


...但是如果docker杀死主进程仍在内存中的所有未决文件系统更改,这些丢失将丢失,那么文件系统可能最终损坏了吗?

– Arjan
17年4月29日在14:35

显然,由于是突然停止,因此仅杀死时的更改将被保留。任何待处理的内容都会丢失。我的观点是,docker kill并不是真的...杀死容器,从而停止进程。例如当您关闭计算机电源而不是关闭电源时

–awkwardarts
17-4-30在8:11



Docker容器不是VM,并且内核通过杀死保持活动。因此,到达内核的任何文件系统更改都将原封不动地提交。不可能损坏文件系统(从fsck的角度来看;应用程序可能不喜欢丢失一些写入)。 docker kill类似于杀死进程,而不是关闭计算机电源。

–伊恩·豪森(Ian Howson)
'18 / 12/31在16:40

#3 楼

除了前面添加的答案之外,在docker events之后运行docker stop还会显示事件


kill(信号15):其中信号15 = SIGTERM
die
停止

docker events显示事件后运行docker kill


kill(信号9):其中信号9 = SIGKILL
Die(退出代码137) )

docker stop在终止进程之前已超时。默认值为10秒。

此表具有更多详细信息。

#4 楼

类似于拔下桌面的插头并关闭计算机

就像拔下插头意味着硬关闭电源,docker kill意味着杀死my_container的直接方法,它不会尝试关闭进程

关闭计算机意味着向OS发送信号以关闭所有进程,其中docker stop意味着向正在运行的容器发送SIGTERM信号以优雅地停止进程。