Extract Java Thread Dump from Alpine Docker Container

Extract Java Thread Dump from Alpine Docker Container

Extracting Java dump is usually straightforward task, until I tried to get the thread dump from the Java process with PID 1 in the alpine based docker container, based on docker image openjdk:8-jre-alpine. Everyone love alpine variant because it’s so small in size, light and secure!

From the snippet below you can see that the Java process is running with PID 1, which is the root process. I then attempt to get a thread dump with jstack, oopssss…

$ docker exec -ti 202 sh

/opt/app $ ps
PID   USER     TIME   COMMAND
  1   root     9:54   java -server -Xms2g -Xmx4g ...
203   root     0:00   ps

/opt/app $ jstack 1
Unable to get pid of LinuxThreads manager thread

kill -3 doesn’t work either! After some poking at Google, I learnt that this was because PID 1 is special and it doesn’t handle any signal unless explicitly declared. So the workaround is to have the java process spawned at non PID 1. Here comes Tini into play!

All Tini does is spawn a single child (Tini is meant to be run in a container), and wait for it to exit. All the while reaping zombies and performing signal forwarding.

In the docker file, I made the following changes (git diff).

FROM openjdk:8-jre-alpine

...

+ # Install Tini
+ RUN apk add --no-cache tini

- ENTRYPOINT ["sh", "entrypoint.sh"]
+ ENTRYPOINT ["/sbin/tini", "--", "sh", "entrypoint.sh"]

Redeployed the application, and I can finally run some analysis on the JVM with jstack, jmap etc. Now the process will look like this. See that tini is running on PID 1 and it spawn the Java process at PID 6. Sweet!

/opt/app # ps
PID   USER     TIME  COMMAND
  1   root     0:23  /sbin/tini -- sh entrypoint.sh
  6   root     2d00  java -server -Xms2g -Xmx4g ...
984   root     0:00  ps

Love and hate of Alpine pffff…

One Reply to “Extract Java Thread Dump from Alpine Docker Container”

Leave a Reply

Your email address will not be published. Required fields are marked *