Dockerfile ENTRYPOINT中date命令未生效 无法生成带时间戳堆转储文件
问题核心原因
你遇到的问题本质是Docker exec 形式的ENTRYPOINT不会主动调用shell,因此不会做环境变量替换和命令替换,$MY_POD_ID、$(date)都会被当成普通字符串处理,所以时间戳不会动态生成。
而你之前用的无方括号shell形式ENTRYPOINT环境变量失效,大概率是基础镜像默认shell配置异常,或者环境变量未被非交互shell加载导致的。
解决方法
方案1:JVM内置占位符实现(推荐)
OpenJDK 8u92及更高版本原生支持-XX:HeapDumpPath的动态占位符,不需要额外调用shell命令:
%t:OOM发生时的实时时间戳,格式为YYYY-MM-DD-HH-MM-SS,比容器启动时生成的时间戳更贴合故障发生时间%p:发生OOM的Java进程ID
配合显式调用shell的exec写法,既可以保留exec形式的特性,又能完成环境变量解析:
ENTRYPOINT ["sh", "-c", "exec java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=mountpath-heapdump/$MY_POD_ID_%t_heapdump.bin -jar /app.jar"]
前面加
exec是为了将sh进程替换为Java进程,让Java成为PID 1进程,可以正常接收docker stop等容器信号,避免僵尸进程问题。
方案2:兼容低版本JDK的date命令实现
如果你的JDK版本不支持%t占位符,可以用shell的date命令生成时间戳,写法如下:
ENTRYPOINT ["sh", "-c", "exec java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=mountpath-heapdump/$MY_POD_ID$(date +'%Y-%m-%d_%H-%M-%S')_heapdump.bin -jar /app.jar"]
验证方法
容器启动后执行ps -ef | grep java,查看Java进程的启动参数,确认-XX:HeapDumpPath后的路径已经完成变量和命令替换,不是原始的字符串模板即可。
内容的提问来源于stack exchange,提问作者lucky
相关产品推荐
相关产品推荐

