登录
    Technology changes quickly but people's minds change slowly.

Arthas 在docker 容器中诊断java应用问题-Unable to get pid of LinuxThreads manager thread

技术宅 破玉 6527次浏览 1个评论

    我们使用的基础镜像是openjdk:8-jdk-alpine。容器启动时第一个进程就是java:

PID   USER     TIME  COMMAND
    1 root      0:50 java -Xms256m -Xmx512m ......
   94 root      0:00 sh
   99 root      0:00 ps

    使用alpine镜像会有个问题,如果java进程的pid=1,那么无法执行jdk的各种连接java进程的命令,会报如下错误:

Unable to get pid of LinuxThreads manager thread

    我们的docker文件如下:

FROM openjdk:8-jdk-alpine
MAINTAINER david "[email protected]"
# copy arthas
COPY --from=hengyunabc/arthas:latest /opt/arthas /opt/arthas
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ADD rpt-answerall-1.0-SNAPSHOT.jar answerall.jar
ADD /script /script
EXPOSE 9089
ENTRYPOINT ["java","-Xms750m","-Xmx900m","-server","-jar","/hello.jar"]

    其他os镜像未验证,相关issue:https://github.com/docker-library/openjdk/issues/76
解决的方法是:启动一个init进程(pid=1)来接收docker stop and docker kill的信号,它会转发信号给其他进程,负责关闭僵尸进程。java进程由init进程启动。
具体有以下两种做法。

方法一:docker run –init

    在docker 1.13 之后的版本,可以在docker run时加上 –init 参数来实现。

docker run -i --restart=always -v /etc/localtime:/etc/localtime --name hello-m 1024m -p 7005:7005 --net=host --log-opt max-size=500m --log-opt  max-file=3 --init hello

方法二:krallin/tini

    安装Tini,使用tini作为入口进程,配置启动java进程。

RUN apk add --no-cache tini
# Tini is now available at /sbin/tini
ENTRYPOINT ["/sbin/tini", "--", "java", "-Xms256m", "-Xmx512m", ......]

实际上,docker的–init参数也是通过集成Tini实现的。

参考链接:openjdk-alpine容器中的jvm如何dump


华裳绕指柔, 版权所有丨如未注明 , 均为原创|转载请注明Arthas 在docker 容器中诊断java应用问题-Unable to get pid of LinuxThreads manager thread
喜欢 (6)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(1)个小伙伴在吐槽
  1. --init 应该是 1.25 以上哦, https://docs.docker.com/engine/reference/commandline/run/
    黄金键盘2020-07-22 16:47 回复