最近在处理项目上问题发现之前同事构建的AlpineLinux的镜像不能执行jstack等JDK命令,报错如下。
Unable to get pid of LinuxThreads manager thread
问题的根本原因有两点:
这两个原因导致了一个神奇的现象:当Java进程PID=1时,通过OpenJDK8执行JDK命令调用底层时会提示Unable to get pid of LinuxThreads manager thread
,这个错误信息来源于Alpine仓库中OpenJDK源码中的一个失误,没处理musl libc仍去调用了glibc的底层接口导致的。
如下是亚马逊工程师对此仓库中底层OpenJDK8源码做的patch修复。
https://git.alpinelinux.org/aports/tree/community/openjdk8/icedtea-issue13032.patch
解决方法有以下几种:
启动容器命令参考如下:
docker run -d --init 省略其他参数镜像名等
Dockerfile中使用如下方式
RUN apk --update --no-cache add tini #利用ENTRYPOINT一定会执行的特点,将它作为PID=1托管进程 ENTRYPOINT ["tini"] CMD java $JAVA_OPTS -jar app.jar
编写脚本 docker-entrypoint.sh
# !/bin/bash java $JAVA_OPTS -jar app.jar
Dockerfile中使用如下方式
CMD /docker-entrypoint.sh
Dockerfile中使用如下方式
CMD /bin/sh -c "java $JAVA_OPTS -jar app.jar"
如 debian、ubuntu、centos等基础镜像封装