openjdk8-openj9:alpine-slim容器由于是slim版,只包含了java运行的必须的包,像jstack这样的用于调试的工具没有包含在其中。因此,当容器中java进程运行出现内存、线程方面的问题,我们要调试的时候,找不到jstack这样的工具。
为了解决这个问题,我尝试过在容器中通过apk add java-1.8-openjdk的方式,安装一个带jstack的jdk。但是安装后,发现jstack命令不能用,提示jstack的某些依赖找不到。我猜这是因为openjdk1.8和openj9是不同的虚拟机实现,基础的工具包不兼容。
后来我终于摸索到一个简单的解决方案:既然alpine-slim版中没有jstack,那标准版中总有吧,那我启动一个基于标准版镜像的容器,从这个容器中找到jstack,拷贝出来,放到slim版中是不是就可以了。
我按照这个方案试了,果然奏效。大概步骤如下:
1、创建一个新的镜像和容器,在Dockerfile中将基础镜像openjdk8-openj9:alpine-slim中的alpine-slim去掉,即基于openjdk8-openj9的最新标准版来构造镜像。
2、启动这个容器后,通过docker exec 容器ID /bin/sh,进入容器,在/opt/java/openjdk/bin下,发现有jstack;
3、执行命令:docker cp 容器id:/opt/java/openjdk/bin/jstack /opt/,将jstack拷贝出来;
4、执行命令:docker cp /opt/jstack slim版容器id:/opt/java/openjdk/bin/,将jstack拷贝到slim版容器中;
5、在slim版容器中,分配给jstack的可执行权限;
这样,jstack就可以使用了。
当然,也可以找一个现成的适用于openj9的jstack文件,放到容器中/opt/java/openjdk/bin/下。我把这个文件打了个包,您可以点击下载使用。
jstack用来分析java进程的线程信息,非常有用。