容器可配置为响应 SIGUSR1 信号,需在 Dockerfile 中用 STOPSIGNAL SIGUSR1 声明,并在应用中显式捕获处理,如 Node.js、Python、Go 中注册信号处理器执行优雅关闭、状态保存等逻辑后退出。
在 docker 中,容器默认使用 sigterm 作为停止信号,但你可以通过 stopsignal 指令和自定义信号处理逻辑,让容器响应 sigusr1 并执行特定业务逻辑(如优雅关闭连接、保存状态、触发清理任务等)。
配置容器的停止信号为 SIGUSR1
在 Dockerfile 中使用 STOPSIGNAL 指令声明容器期望接收的停止信号:
STOPSIGNAL SIGUSR1
该指令仅设置容器运行时的默认停止信号,**不会自动处理该信号**——你仍需在应用中显式捕获并响应 SIGUSR1。
在应用中捕获并处理 SIGUSR1
不同语言的处理方式略有差异,核心是:注册信号处理器,在收到 SIGUSR1 时执行你的业务逻辑(例如 flush 缓存、断开数据库连接、写 checkpoint 文件),然后可选择退出或继续运行。
-
Node.js 示例:
process.on('SIGUSR1', () => { console.log('Received SIGUSR1: running graceful shutdown...'); // 执行你的业务逻辑:关闭 HTTP server、保存状态等 gracefulShutdown().then(() => process.exit(0)); }); -
Python 示例(使用 signal 模块):
import signal import sys <p>def handle_usr1(signum, frame): print("Received SIGUSR1: triggering cleanup...")</p><h1>执行清理逻辑</h1><pre class="brush:php;toolbar:false;">perform_cleanup() sys.exit(0)signal.signal(signal.SIGUSR1, handle_usr1)
-
Go 示例:
sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGUSR1) go func() {
向运行中的容器发送 SIGUSR1
当容器启动后,可通过 docker kill 显式发送 SIGUSR1(即使未设 STOPSIGNAL 也能发,但设了后 docker stop 会自动发它):
- 手动触发:
docker kill -s SIGUSR1 <container-id-or-name></container-id-or-name> - 使用
docker stop(前提是已设STOPSIGNAL SIGUSR1):docker stop <container-id-or-name></container-id-or-name>→ 自动发送SIGUSR1,而非默认的SIGTERM - 注意:
docker stop仍会等待超时(默认 10 秒),若你的SIGUSR1处理耗时较长,可通过--time调整:docker stop --time=30 <container></container>
验证与调试技巧
确保信号真正送达并被处理:
- 进入容器检查进程是否监听信号:
docker exec -it <container> ps auxf</container>→ 确认主进程 PID 正确
再用cat /proc/<pid>/status | grep Sig</pid>查看信号掩码(非必需,但可辅助排查屏蔽问题) - 在应用中加日志,明确打印 “SIGUSR1 received” 和后续动作结果;
- 避免在信号处理器中做阻塞操作(如同步网络请求、大文件 I/O);建议异步触发或用超时控制;
- 注意:Docker 不支持向 Windows 容器发送
SIGUSR1(仅 Linux 容器可用)。











