Rundeck点击KILL JOB按钮时Python脚本无法捕获终止信号如何解决
Rundeck KILL JOB 终止机制问题排查结论
核心机制确认
从提供的debug日志可以直接确认:默认SSH执行模式下点击KILL JOB按钮时,Rundeck不会主动向远端运行的业务进程发送SIGINT/SIGTERM信号,首个动作是直接断开与目标节点的SSH连接。
日志中Disconnecting from 9.11.56.44 port 22、Connection was interrupted、Socket closed条目就是直接证据:Rundeck服务端触发Kill操作时,会先中断自身工作流引擎的执行任务,直接关闭SSH连接句柄,不会通过SSH通道向远端投递标准终止信号。
信号捕获失效的原因
编写的信号处理逻辑在本地命令行可以正常生效,是因为本地终端按Ctrl+C会向进程发送SIGINT,手动执行kill命令默认发送SIGTERM,正好匹配注册的信号监听范围。但Rundeck SSH执行场景下的信号流转逻辑完全不同:
- SSH连接被服务端强制断开后,远端节点的sshd服务会向该会话关联的所有进程发送SIGHUP(终端挂断信号),而非SIGINT/SIGTERM
- 现有代码没有监听SIGHUP信号,自然无法触发自定义清理逻辑,进程要么被默认的SIGHUP处理规则直接终止,要么被sshd的会话回收逻辑强制销毁
修复方案
- 代码层面:在原有信号注册逻辑基础上,补充SIGHUP信号的监听,复用已有的清理处理函数即可覆盖SSH断开场景,参考代码:
import signal # 原有SIGINT、SIGTERM注册保留 signal.signal(signal.SIGINT, sigint_handler) signal.signal(signal.SIGTERM, sigint_handler) # 新增SIGHUP捕获,覆盖SSH连接断开场景 signal.signal(signal.SIGHUP, sigint_handler)
- 加固建议:如果脚本会启动多层子进程,可在脚本启动时将自身设置为进程组组长,清理时直接向整个进程组发送信号,避免出现孤儿进程。
- 配置层面:高版本Rundeck可在节点配置中开启Kill操作时优先发送SIGTERM信号的相关参数,但该能力依赖远端sshd的信号转发兼容性,稳定性不如代码层面直接捕获SIGHUP。
内容的提问来源于stack exchange,提问作者Mario Alvarado
相关产品推荐
相关产品推荐

