【问题解决】Alpine镜像中执行jstack、arthas等命令提示Unable to get pid of LinuxThreads manager thread
问题现象
最近在处理项目上问题发现之前同事构建的AlpineLinux的镜像不能执行jstack等JDK命令,报错如下。
Unable to get pid of LinuxThreads manager thread
问题原因
问题的根本原因有两点:
- Alpine Linux 使用的不是标准gnu libc (glibc),而是musl libc
- apk包管理器安装的OpenJDK是IceTea补丁版本的,已经停止维护了
这两个原因导致了一个神奇的现象:当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
解决方法
解决方法有以下几种:
方案1、添加 docker 启动参数
启动容器命令参考如下:
docker run -d --init 省略其他参数镜像名等
方案2、镜像安装tini,由它管理进程
Dockerfile中使用如下方式
RUN apk --update --no-cache add tini #利用ENTRYPOINT一定会执行的特点,将它作为PID=1托管进程 ENTRYPOINT ["tini"] CMD java $JAVA_OPTS -jar app.jar
方案3、用Shell脚本启动Java进程
编写脚本 docker-entrypoint.sh
# !/bin/bash java $JAVA_OPTS -jar app.jar
Dockerfile中使用如下方式
CMD /docker-entrypoint.sh
方案4、安装glibc
https://github.com/sgerrand/alpine-pkg-glibc
此方案仅适用于X86_64 CPU架构,分在线与离线安装两种方法,以下举例说明
Dockerfile中在线安装:
RUN curl -kLo /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \ curl -kLo glibc-2.35-r0.apk https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-2.35-r0.apk && \ apk add glibc-2.35-r0.apk && \ rm -f glibc-2.35-r0.apk
方案5、推荐:换一种基于glibc的镜像
如 debian、ubuntu、centos等基础镜像封装
本文作者:东北小狐狸
本文链接:https://www.cnblogs.com/hellxz/p/16428013.html
版权声明:本作品采用自由转载-非商用-非衍生-保持署名 (CC BY-NC-ND 3.0)许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2020-06-30 通过yum展示安装包依赖关系,下载rpm包