Docker发了SIGTERM服务却没收到,怎样检查启动脚本与PID1
容器收到SIGTERM,业务程序却没留下接收记录,先检查信号发给了谁。shell包装脚本可能成为PID1,业务进程只是子进程;启动脚本使用exec则可以用业务进程替换shell。本文提供两份假入口做静态检查,没有启动Linux容器或实测信号。
两种入口只差一个关键动作
附件shell版本在脚本中执行python /app/fake_service.py;exec版本执行exec python /app/fake_service.py。后者让当前shell被目标程序替换,不再保留一层普通包装。Docker官方Dockerfile参考解释了shell形式入口与exec对信号处理的影响。实际复杂脚本如果还要管理多个子进程,应使用清晰的信号转发和回收策略,不能只机械加一个单词。
运行器实际读取两份脚本,检查第二份存在行首exec,再比较示例清理预算四秒与停止宽限八秒。输出exec_detected为假、真,budget_fits为真。这些只是静态结构与算术断言,不代表业务进程已经收到SIGTERM,也没有生成真实进程树或退出码。
在独立假容器中补做信号验收
完整实验可以准备只记录启动PID、父PID、收到信号和清理结束的假服务,不接任何模型。分别使用两种入口启动,保存进程树;停止时观察PID1和业务进程是否各有接收标记,再记录退出码。要清楚区分未收到信号、收到但清理太慢,以及脚本提前退出留下子进程。
不要拿正式网关容器做停止试验。入口路径、权限、解释器和镜像平台都要匹配独立测试环境,附件中的/app/fake_service.py只是接口示意,不能直接用不存在的文件启动。Windows上没有可用Linux容器环境时,应保留静态验收状态,不应把PowerShell进程结束行为冒充Linux PID1信号语义。
宽限时间应容纳真实清理预算
Compose的stop_grace_period定义停止等待宽限,超出后可能进入强制结束;它本身不会修复信号没有到达的问题。预算里应包括应用排空、连接关闭和日志收尾,并考虑外层编排给的总期限。仅把宽限改得很长,可能只是让一个收不到信号的进程多等一会儿。
本篇与排空教程的区别是定位“业务有没有接到停机意图”,而非收到之后怎样处理旧请求。生产验收应把实际启动命令、进程树、信号标记、清理耗时与版本放在一起。只看到docker stop最终返回,不能推断应用完成了优雅退出,因为它也可能最后被强制终止。先验证信号路径,再验证清理逻辑,才有完整证据链。
配套样本与复核入口
下载本篇独立合成输入和实验运行器,并下载运行器实际读取的c037-shell.sh、c037-exec.sh。上述文件放在同一目录后运行 python run_lab.py C037。完整运行需要全部四十四份输入及相关配置。结果中的method区分离线计算、静态参考检查与回环实测,不能把前两者当成真实网关已通过。
资料核对日期:2026-10-24。官方依据1;官方依据2。
与本站相关基础教程的区别:旧文未测试容器入口信号;本文定位进程启动包装层是否转发SIGTERM,区别于C036收到停机信号后服务怎样排空。
不想自己搭网关、自己维护渠道?
力达云是托管的 OpenAI / Anthropic 双格式端点,一期提供 DeepSeek,注册送 ¥5 额度。