Skip to main content

Docker 容器停止耗时

停止项目时,部分 Docker 容器需要约 5 秒才退出,而另一些瞬间完成。为什么?

这是 Docker 容器内 PID 1 进程对 SIGTERM 信号的响应行为差异导致的。

日志时间线示例(2026-06-03):

时间事件
22:32:58开始 fix ownership 处理(AlpineLinux-1, Chromium-1, OstinatoWireshark-1)
22:32:58Chromium-1 已停止 ✅
22:32:59webterm-1 已停止 ✅
22:33:03AlpineLinux-1 已停止 ❌(耗时 ~5s)
22:33:03OstinatoWireshark-1 已停止 ❌(耗时 ~5s)

根因: Docker 的 stop 命令会给容器内 PID 1 进程发送 SIGTERM 信号,等待 t 秒(GNS3 设为 5s)后发送 SIGKILL 强制终止。慢的容器是因为 PID 1 进程不响应 SIGTERM,只能等超时后被强制杀死。

各容器分析:

容器PID 1SIGTERM 行为耗时
Chromium/usr/bin/chromiumChromium 自带信号处理,收到后立即退出~0s
webtermdumb-init → firefox ✅Firefox 响应 SIGTERM 快速退出~0s
AlpiNetdumb-initbash -ibash 交互模式(-i)忽略 SIGTERM~5s
OstinatoWiresharkbash (PID 1)Linux 内核不向 PID 1 施加 SIGTERM 默认动作~5s

详细原因:

  • AlpiNet 入口脚本最终执行 bash -i -l(交互模式),bash 交互 shell 的设计行为是忽略 SIGTERM,不会因该信号退出
  • OstinatoWireshark 入口脚本最后停在 /bin/bash,且它是 PID 1。Linux 内核的特殊保护机制下,PID 1 如果不显式安装信号处理器,SIGTERM 被内核直接丢弃
note

这是容器镜像本身的入口脚本设计问题,并非 GNS3 的缺陷。GNS3 的 Docker 停止逻辑(SIGTERM 等待 5 秒后 SIGKILL)符合 Docker 标准行为。