web-dev-qa-db-ja.com

VisualVMをDockerコンテナで実行されている単純なJavaプロセスに接続するにはどうすればよいですか

実際に、JEEコンテナー、特にGlassfishで動作するソリューションが必要でしたが、設定の多くの組み合わせを試して成功しなかった後、セットアップを可能な限り単純なケースに減らしました。

これは、Dockerコンテナーで開始されたHello Worldデーモンです。 jconsoleまたはVisulaVMを添付したい。すべてが同じマシン上にあります。

public class Main {
  public static void main(String[] args) {
    while (true) {
      try {
        Thread.sleep(3000);
        System.out.println("Hello, World");
      } catch (InterruptedException e) {
        break;
      }
    }
  }
}

Dockerfile

FROM Java:8
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN javac Main.Java
CMD ["Java", "Main"]

建物:docker build -t hello-world-daemon .

実行中:docker run -it --rm --name hwd hello-world-daemon

質問:

  • CMDコマンドラインに追加するJVMパラメーターは何ですか?
  • どのポートを公開して公開する必要がありますか?
  • dockerコンテナはどのネットワークモードを使用すべきですか?

ここでは失敗した試行を表示しないため、正解が偏らないようにします。これはかなり一般的な問題であるはずですが、実用的な解決策は見つかりませんでした。

更新されたソリューション

このDockerfileは動作します

FROM Java:8
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN javac Main.Java
CMD ["Java", \
"-Dcom.Sun.management.jmxremote", \
"-Dcom.Sun.management.jmxremote.port=9010", \
"-Dcom.Sun.management.jmxremote.local.only=false", \
"-Dcom.Sun.management.jmxremote.authenticate=false", \
"-Dcom.Sun.management.jmxremote.ssl=false", "Main"]
EXPOSE 9010

docker runコマンドと組み合わせて

docker run -it --rm --name hwd -p 9010:9010 hello-world-daemon

VisualVMは、右クリックLocal-> Add JMX Connectionを介して接続し、localhost:9010を入力するか、リモートホストを追加します。

JConsoleは、localhost:9010Remoteプロセスを選択することで接続します

接続をリモートとして定義する場合、ifconfigでリストされた任意のインターフェイスを使用できます。たとえば、docker0アドレスが172.17.0.1のインターフェイスは機能します。コンテナのアドレス172.17.0.2も機能します。

43
nolexa

最初に、これらのJVMパラメーターを使用してアプリケーションを実行する必要があります。

-Dcom.Sun.management.jmxremote
-Dcom.Sun.management.jmxremote.port=9010
-Dcom.Sun.management.jmxremote.local.only=false
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false

次に、Dockerのポートを公開する必要があります。

EXPOSE 9010

Docker runコマンドでポートバインディングも指定します。

docker run -p 9010:9010 -it --rm --name hwd hello-world-daemon

その後、Jconsoleを使用してローカルの9010ポートに接続し、Dockerで実行されるアプリケーションを管理できます。

38
eg04lt3r

同様の質問に対する他のSO応答 をたどり、うまくいきました。

これらのJVMパラメーターを追加して、コンテナー内でJavaプロセスを開始しました。

-Dcom.Sun.management.jmxremote.port=<port> \
-Dcom.Sun.management.jmxremote.authenticate=false \
-Dcom.Sun.management.jmxremote.ssl=false \
-Dcom.Sun.management.jmxremote.rmi.port=<port> \
-Djava.rmi.server.hostname=$Host_HOSTNAME

-e Host_HOSTNAME=$HOSTNAME -p <port>コマンドにdocker runを指定してDockerコンテナーを開始しました。

次に、リモートJMX接続を追加し(「ファイル」>「JMX接続を追加...」)、<dockerhostname>:<port>を指定することで、ローカルJVisualVmからこのリモートJavaアプリにアクセスできました。 「接続」入力、および「SSL接続を必要としない」のチェック。

8
Anthony O.

Anthony で回答したとおり。 Windowsマシンで-Djava.rmi.server.hostname Javaオプションを使用する必要がありました。

DockerfileでJSON形式のCMDを使用しないようにしてください。これはシェル拡張をサポートしていないためです。

Dockerfileの例:

FROM Java:8
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN javac Main.Java
#Do not use CMD in JSON format here because Shell expansion doesn't work in JSON format
#Shell expansion is needed for the ${Host} variable.
CMD Java -Dcom.Sun.management.jmxremote=true \
-Dcom.Sun.management.jmxremote.rmi.port=9010 \
-Dcom.Sun.management.jmxremote.port=9010 \
-Dcom.Sun.management.jmxremote.ssl=false \
-Dcom.Sun.management.jmxremote.authenticate=false \
-Dcom.Sun.management.jmxremote.local.only=false \
-Djava.rmi.server.hostname=${Host} \
Main
2
Chris