咨询:Agones环境下Unreal服务器触发SIGSEGV时preStop未执行是否正常?
是的,默认情况下,当Pod内进程因SIGSEGV(段错误,对应kill -11)直接崩溃时,Kubernetes不会触发preStop钩子。
原因
Kubernetes的preStop钩子仅在优雅终止流程中触发:比如Pod收到SIGTERM(kill -15)信号、被K8s调度器驱逐、Fleet缩容等主动终止场景。而进程因SIGSEGV这类致命信号直接崩溃属于异常退出,不属于K8s的优雅终止流程范畴,kubelet不会主动触发preStop钩子。
针对你的Unreal服务器+Agones场景的解决方案
因为你的服务有较高概率触发SIGSEGV,需要在崩溃时完成日志上传,推荐以下几种方案:
进程内捕获SIGSEGV信号自行处理
在Unreal专用服务器代码中注册SIGSEGV信号处理函数,当触发段错误时,优先执行日志上传逻辑,再让进程正常退出。注意信号处理函数中避免复杂IO操作(可能存在线程安全问题),可以调用轻量化的上传脚本或触发异步任务:#include <signal.h> #include <unistd.h> void sigsegv_handler(int signum) { // 执行日志上传脚本 system("/opt/upload_crash_logs.sh"); // 恢复默认信号行为,让进程正常退出 signal(signum, SIG_DFL); kill(getpid(), signum); } // 在服务器初始化阶段注册处理器 void InitCrashHandler() { signal(SIGSEGV, sigsegv_handler); }用sidecar容器监控主进程状态
给Pod配置shareProcessNamespace: true,添加一个sidecar容器共享主进程的PID命名空间。sidecar通过循环检查主进程的运行状态,当检测到主进程因SIGSEGV退出(退出码为139,即128+11)时,执行日志上传操作。示例shell脚本逻辑:#!/bin/bash MAIN_PID=$(pidof UnrealServer) while true; do if ! kill -0 $MAIN_PID 2>/dev/null; then EXIT_CODE=$(wait $MAIN_PID) if [ $EXIT_CODE -eq 139 ]; then # 执行日志上传 /opt/upload_crash_logs.sh fi exit 0 fi sleep 2 done结合Agones SDK处理状态变更
利用Agones SDK在Unreal服务器中监听GameServer的状态变化,当检测到自身因崩溃即将被回收时(比如状态变为Error或Terminating),触发日志上传逻辑。这种方式更贴合Agones的生命周期管理,能确保在GameServer被Agones清理前完成日志上传。
注意事项
- 日志上传逻辑要尽量轻量化,避免超过K8s默认的30秒优雅终止时间(超时会被强制发送SIGKILL)。
- 如果采用信号处理方案,需注意Unreal引擎本身可能自带信号处理逻辑,要确保自定义处理器能正确协同或覆盖原有逻辑。
内容的提问来源于stack exchange,提问作者Masuri

