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

Jib打包SpringBoot容器启动报pthread_create failed (EPERM)如何排查

问题背景
  • SpringBoot应用通过Jib 3.2.0打包为Docker镜像,基础镜像采用Temurin JDK 17.0.3+7
  • 在故障Linux服务器(Docker版本20.10.4)上启动容器时立即崩溃,启动日志报错如下:
[0.012s][warning][os,thread] Failed to start thread - pthread_create failed (EPERM) for attributes: stacksize: 1024k, guardsize: 4k, detached.
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create worker GC thread. Out of system resources.
# An error report file with more information is saved as:
# //hs_err_pid1.log
  • 容器启动后直接退出,无法通过docker exec进入容器查看hs_err_pid1.log文件
  • 容器使用特权模式启动可正常运行,但不符合安全规范要求
  • 提前释放4G可用内存后问题仍复现,使用docker run、docker-compose两种方式启动结果一致
  • 相同镜像在硬件配置相近的其他服务器上可正常启动运行
根因分析

该报错和宿主机实际剩余内存无关,是安全规则拦截导致的JVM误报:

  1. Temurin JDK 17.0.3版本创建线程时会调用clone3系统调用
  2. Docker 20.10.4是20.10系列的早期版本,默认内置的seccomp安全配置未将clone3加入允许列表,会直接拦截该系统调用并返回EPERM(操作无权限)错误
  3. JVM未识别到该错误属于权限拦截,误判为系统内存不足无法创建GC工作线程,最终抛出内存不足的错误日志
  4. 特权模式会绕过所有seccomp安全限制,因此容器可以正常启动;其他可正常运行镜像的服务器,大概率Docker版本更高,默认seccomp配置已经兼容clone3系统调用,因此不会触发该问题。
解决方案

按推荐优先级从高到低排序:

  • 方案一(生产环境首选):将故障服务器的Docker版本升级到20.10.9及以上,该版本之后的Docker默认seccomp配置已经加入clone3系统调用的允许规则,无需额外修改启动参数即可兼容JDK17,无额外安全风险。
  • 方案二(无法升级Docker时使用):启动容器时手动指定兼容clone3规则的seccomp配置文件,启动命令添加参数:
    --security-opt seccomp=/path/to/your/compatible-seccomp.json
    
    该方案不需要放开全量权限,仅补充缺失的系统调用允许规则,安全风险远低于特权模式。
  • 方案三(临时应急使用):通过JVM启动参数降低GC线程数,减少线程创建触发频率,添加参数如下:
    -XX:ParallelGCThreads=2 -XX:ConcGCThreads=1
    
    注意:该方案属于临时规避手段,GC线程数过低会影响应用垃圾回收性能,不建议生产环境长期使用
  • 补充排查项:执行docker info | grep Pids查看Docker默认的进程数限制,如果默认pids limit低于1024,启动容器时可添加--pids-limit=2048设置合理的进程数阈值,排除进程数限制导致的线程创建失败问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 03:22:04