In an earlier blog post, I talked about flame graphs and how I implemented those for a Scala app. Ever since I have been thinking if it would be possible to grab a flame graph from a container.
Some time ago I made that happen inspired by this post. It was not enough for me, I wanted to go deeper. I wanted also the profiler to run inside a container profiling another container. So I ended up making this
It uses the JVM async-profiler tool so not quite the same that in my previous blog post but the results are similar.
To profile another container, you can use the one-liner and replace the $CONTAINER_ID with the id of the running JVM container you want to profile, $PERF_IMAGE as the built image id of the described container and $JAVA_PID with the, you guessed it, the JVM pid inside the subject container. You also need to set a couple of runtime variables on the docker host as described in the async-profiler setup instructions.
There are a couple of drawbacks. Firstly you need to run the profiler as root. This could be altered somehow but I don't actually see this as a huge problem since the async-profiler should switch to the user the JVM belongs to anyway. This brings up the second limitation. The profiler container user needs to be the same user that the JVM process belongs to. This is a limitation in the JVM. Some further annoyances include that the JDK paths need to match in both containers and also the async profiler agent library needs to be copied to the JVM container.
Some time ago I made that happen inspired by this post. It was not enough for me, I wanted to go deeper. I wanted also the profiler to run inside a container profiling another container. So I ended up making this
It uses the JVM async-profiler tool so not quite the same that in my previous blog post but the results are similar.
To profile another container, you can use the one-liner and replace the $CONTAINER_ID with the id of the running JVM container you want to profile, $PERF_IMAGE as the built image id of the described container and $JAVA_PID with the, you guessed it, the JVM pid inside the subject container. You also need to set a couple of runtime variables on the docker host as described in the async-profiler setup instructions.
There are a couple of drawbacks. Firstly you need to run the profiler as root. This could be altered somehow but I don't actually see this as a huge problem since the async-profiler should switch to the user the JVM belongs to anyway. This brings up the second limitation. The profiler container user needs to be the same user that the JVM process belongs to. This is a limitation in the JVM. Some further annoyances include that the JDK paths need to match in both containers and also the async profiler agent library needs to be copied to the JVM container.
Comments
Post a Comment