Help us understand the problem. What are the problem?

posted at

[Docker][Java] Java プロセスのコンテナで jmap/jstack が採れない

前の記事で Java プロセスの docker コンテナの jstat が採れない問題を修正したら、今まで動いていた jmap/jstack が採れなくなった。。

[Docker][Java] Java プロセスのコンテナで jstat が採れない

以下のようなエラーになり、jmap/jstack の結果がアタッチ対象の Java プロセスの標準出力に出てしまう。

Exception in thread "main" com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file /proc/1/root/tmp/.java_pid1: target process 1 doesn't respond within 10500ms or HotSpot VM not loaded
        at jdk.attach/sun.tools.attach.VirtualMachineImpl.<init>(VirtualMachineImpl.java:100)
        at jdk.attach/sun.tools.attach.AttachProviderImpl.attachVirtualMachine(AttachProviderImpl.java:58)
        at jdk.attach/com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:207)
        at jdk.jcmd/sun.tools.jmap.JMap.executeCommandForPid(JMap.java:128)
        at jdk.jcmd/sun.tools.jmap.JMap.histo(JMap.java:174)
        at jdk.jcmd/sun.tools.jmap.JMap.main(JMap.java:112)

対象の Java プロセスも、jmap/jstack もユーザID を変更して実行しているのに、エラーメッセージにあるソケットファイル名は /proc/1/root/tmp/.java_pid1 と root ユーザとなっているので、root として jcmd を実行してみてもダメでした。

$ docker exec -t --user 1000 {container-id} jstack 1  #=> NG
$ docker exec -t             {container-id} jstack 1  #=> NG

root でもアクセスできないとは。。

そもそも、ユーザID を変更して実行しているのにソケットファイル名が root になってるのがおかしいようです。

結局、原因は対象の Java プロセスが entrypoint 内でユーザID を変えて java プロセスを実行していたからのようです。
コンテナ(PID=1) 自体が root で起動しているからソケットファイル名が root なのだと思われます。

chroot --userspec=1000:0 / java -ea ...

なので、jmap/jstack も同じように chroot して実行する必要がありました。

$ docker exec -t {container-id} bash -c "chroot --userspec=1000:0 / jstack 1"

これで jmap/jstack も採れるようになりました。

// EOF

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
Help us understand the problem. What are the problem?