You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes删除Pod时未发送SIGTERM信号问题排查

问题根因

问题出在Dockerfile的CMD指令写法上,和Kubernetes配置、权限配置均无关。
你当前使用的是shell格式的启动命令CMD ${CMD},Docker执行这类格式的命令时,会自动通过/bin/sh -c包裹启动目标程序,最终容器内PID为1的进程是shell,而非你实际运行业务服务的进程。
Linux系统中PID 1进程有特殊的信号处理规则:默认情况下shell进程不会将收到的SIGTERM信号转发给它拉起的子进程,这就导致Kubernetes发送的终止信号被PID 1的shell拦截,根本没有传递到业务进程,直到默认30秒宽限期结束后发送SIGKILL强制销毁整个容器。
你手动通过kubectl exec进入Pod执行kill -15能正常触发优雅关停逻辑,是因为该操作直接将信号发送给了业务进程本身,绕过了PID 1的shell层,和Kubernetes发信号的链路不一样。

修复方案

核心思路是让你的业务服务进程直接成为容器内的PID 1进程,直接接收Kubernetes传递的信号,有两种可行写法:

  • 使用exec格式的CMD指令(推荐)
    exec格式是JSON数组形式,Docker不会额外调用shell包裹启动,会直接运行业务进程成为PID 1。注意该格式不支持shell变量展开,你可以直接写入确定的服务启动路径:
    # 替换原有的ENV和CMD配置
    CMD ["./你的服务二进制文件名"]
    
  • 保留变量传参的写法,加exec前缀
    如果你需要保留通过ARG SERVICE传入服务名的逻辑,可以在启动命令前加exec,让shell启动业务进程后主动退出,由业务进程接管PID 1:
    ENV CMD=./${SERVICE}
    CMD exec ${CMD}
    
验证方法

修改配置重新构建镜像启动Pod后,可以通过以下方式确认修复生效:

  • 进入容器执行ps aux,查看PID为1的进程是否为你的业务服务进程,而非/bin/sh
  • 触发Pod删除/滚动更新操作,观察业务进程是否能在30秒宽限期内收到SIGTERM执行优雅退出逻辑,不需要等满30秒被强制杀死

内容的提问来源于stack exchange,提问作者abcalphabet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 01:39:24