How to access JMX interface in docker from outside?

前端 未结 5 1108
情深已故
情深已故 2020-12-02 07:54

I am trying to remotely monitor a JVM running in docker. The configuration looks like this:

  • machine 1: runs a JVM (in my case, running kafka) in docker on

5条回答
  •  有刺的猬
    2020-12-02 08:13

    To add some additional insights, I had some Docker port mappings in use, and none of the previous answers worked directly for me. After investigation, I found the answer here: How to connect with JMX from host to Docker container in Docker machine? to provide the required insights.

    This is what I believe happens:

    I set up JMX as suggested in other answers here:

    -Dcom.sun.management.jmxremote.ssl=false 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.port=1098
    -Dcom.sun.management.jmxremote.rmi.port=1098
    -Djava.rmi.server.hostname=localhost
    -Dcom.sun.management.jmxremote.local.only=false
    

    Program flow:

    • I run the Docker container and expose/map the port from host to container. Say I map port host:1099->container:1098 in Docker.
    • I run the JVM inside the docker with the above JMX settings.
    • The JMX agent inside the Docker container now listens to the given port 1098.
    • I start JConsole on the host (outside Docker) with URL localhost:1099. I use 1099, since I used host:docker port mapping of 1099:1098.
    • JConsole connects fine to the JMX agent inside Docker.
    • JConsole asks JMX where to read the monitoring data.
    • JMX agent responds with the configured information and address: localhost:1098
    • JConsole now tries to connect to the given address localhost:1098
    • This fails since port 1098 on localhost (outside Docker) is not listening. Port 1099 was mapped to Docker:1098. Instead of localhost:1098, JMX should tell JConsole to read monitoring information from localhost:1099, since 1099 was the port mapped from host to 1098 inside Docker container.

    As a fix, I changed my host:docker port mapping from 1099:1098 to 1098:1098. Now, JMX still tells JConsole to connect to localhost:1098 for monitoring information. But now it works since the outside port is the same as advertised by JMX inside Docker.

    I expect the same applies also for SSH tunnels and similar scenarios. You have to match what you configure JMX to advertise and what JConsole sees as the address space on the host where you run it.

    Maybe it is possible to play a bit with the jmxremote.port, jmxremove.rmi.port, and hostname attributes to make this work using different port mappings. But I had the opportunity to use the same ports, so using them simplified it, and this works (for me).

提交回复
热议问题