代码编织梦想

1. 问题现象

最近在处理项目上问题发现之前同事构建的AlpineLinux的镜像不能执行jstack等JDK命令,报错如下。

Unable to get pid of LinuxThreads manager thread

2. 问题原因

问题的根本原因有两点:

  1. Alpine Linux 使用的不是标准gnu libc (glibc),而是musl libc
  2. 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

img

3. 解决方法

解决方法有以下几种:

方案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

不能写为下面方式,否则java进程的pid是1:

ENTRYPOINT exec java $JAVA_OPTS -jar app.jar

方案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://blog.csdn.net/agonie201218/article/details/127119359

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/agonie201218/article/details/127117898

jstack on alpine:unable to get pid of linuxthreads manager thread_xianzi1261618338的博客-爱代码爱编程

jstack on alpine:Unable to get pid of LinuxThreads manager thread 在docker 中使用jstack 报错: bash-4.3# jps 112

线上问题处理干货(系列二)--如何分析docker java项目内存泄露和溢出等问题?_weixin_33980459的博客-爱代码爱编程

2019独角兽企业重金招聘Python工程师标准>>> 01、线上JVM调优 1.主要参数 #JVM x参数 #非标准化参数 -Xint: 解释执行 -Xcomp:第一次使用就编译成本地代码 -Xmixed:混合模式,JVM自己来决定是否编译成本代码 #XX参数分类 格式:-XX:[+-]<nam

Java 线程调优 JDK常用命令行工具 Jstack & Arthas使用笔记 查找耗时线程-爱代码爱编程

文章目录 1. JDK 命令行工具1.1 `jps`:查看所有 Java 进程1.2 `jstat`: 监视虚拟机各种运行状态信息1.3 ` jinfo`: 实时地查看和调整虚拟机各项参数1.4 `jmap`:生成堆转储快照1.5 `jhat`: 分析 heapdump 文件1.6 `jstack` :生成虚拟机当前时刻的线程快照2. Arthas

docker 运行并使用 arthas 的方式-爱代码爱编程

docker 运行并使用 arthas 的方式 docker run --initFROM openjdk:8-jdk-alpine # copy arthas COPY --from=hengyunabc/arthas:latest /opt/arthas /opt/arthas ENV LOG_PATH=/opt/logs \ LOG_H

python需要linux系统吗_学Python一定要Linux系统吗-爱代码爱编程

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里云数据库专家保驾护航,为用户的数据库应用系统进行性能和风险评估,参与配合进行数据压测演练,提供数据库优化方面专

alpine安装及使用-爱代码爱编程

1、下载alpine 清华大学镜像站 alpine官网下载 2、安装alpine 以iso为例,以esxi为例 直接创建虚拟机,然后创建CD/DVD选择上传的iso镜像,然后配置一下机器cpu、内存等。启动 默认用户名root 无密码 3、配置本机hostname #修改主机名为jenreyAlpine echo 'jenreyAlpin

解决spring boot应用以docker容器方式启动后,进程ID是1而导致的jstack和jmap等命令不可用的问题-爱代码爱编程

解决spring boot应用以docker容器方式启动后,进程ID是1而导致的jstack和jmap等命令不可用的现象 默认将spring boot工程打包成镜像的方式 当我们把spring boot打包成一个可执行jar编写Dockerfile 将jarcopy到容器中,在cmd 中执行java -jar ***.jar 启动,Dockerfile

【问题解决】alpine镜像中执行jstack、arthas等命令提示unable to get pid of linuxthreads manager thread_东北小狐狸-hellxz的博客-爱代码爱编程

问题现象 最近在处理项目上问题发现之前同事构建的AlpineLinux的镜像不能执行jstack等JDK命令,报错如下。 Unable to get pid of LinuxThreads manager thread 问题原因 问题的根本原因有两点: Alpine Linux 使用的不是标准gnu libc (glibc),而是musl li

docker镜像alpine上运行arthas-爱代码爱编程

问题描述: 现场环境下的镜像包无法确定部分源码,需要通过arthas监控查询代码。arthas需要基于jps寻找java进程,但是该镜像中的jdk为openjdk没有jps命令。复制hotspot jdk到镜像中执行java -jar arthas-boot.jar 报错: ./bin/java: not found 以为是权限的问题,chmod