Windows Docker下GitLab Runner运行Python3时os.kill执行失败问题咨询
问题根因
该报错的核心原因是GitLab Runner的docker-windows执行器默认不会为作业容器分配伪终端(TTY),而Windows系统的CTRL_BREAK_EVENT信号投递逻辑强依赖控制台会话存在:
- 你手动执行
docker run -it命令时,-i(交互式)和-t(分配伪终端)参数会为容器绑定一个可用的控制台会话,msys2 Python调用os.kill发送CTRL_BREAK_EVENT时,底层Win32 APIGenerateConsoleCtrlEvent可以正常找到目标进程组完成信号投递,所以脚本运行正常。 - GitLab Runner默认启动作业容器时不会携带
-t参数,容器内所有进程都运行在无关联控制台的无头环境下,此时调用GenerateConsoleCtrlEvent会因为没有可用的控制台触发事件直接返回错误,最终被Python封装抛出WinError 1 Incorrect function异常。
你可以通过以下命令手动复现GitLab Runner环境的报错,验证根因:
docker run --rm -v C:\TMP:C:\build test_image python3 C:\build\silly.py
解决方案
方案一:为docker-windows执行器开启TTY配置
修改GitLab Runner的config.toml配置文件,在对应docker-windows执行器的配置段添加tty = true参数即可,示例配置如下:
[[runners]] name = "Windows Docker 执行器" executor = "docker-windows" shell = "powershell" [runners.docker] tty = true image = "你的自定义镜像名称" isolation = "process" # 其余原有配置保持不变
配置修改完成后重启GitLab Runner服务,作业容器就会分配伪终端,脚本可以正常运行。
方案二:替换信号发送逻辑(无需修改Runner配置)
如果无法修改Runner配置,可以放弃使用CTRL_BREAK_EVENT,改用Windows原生的taskkill命令完成进程树终止,替换proc.send_signal( signal.CTRL_BREAK_EVENT )代码为如下内容即可:
subprocess.run(['taskkill', '/F', '/T', '/PID', str(proc.pid)], capture_output=True, check=True)
该命令不需要控制台会话支持,在无头环境下也能正常终止目标进程及其所有子进程。
内容的提问来源于stack exchange,提问作者susundberg
相关产品推荐
相关产品推荐

