Enable JMX RMI access to a docker container

Hi, my name is Alejandro and I’m trying to perform some profiling using JCM or JVM tools (included in java jdk).
My application is running in a glassfish server inside the docker container.
I’ve added the following properties to the glassfish JVM options:

-Djava.rmi.server.hostname=10.116.66.175 <Host IP, not docker internal IP>
-Dcom.sun.management.jmxremote.port=9090
-Dcom.sun.management.jmxremote.rmi.port=9090
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

And, at time to execute the docker run command I’ve added the port mapping option:
-p 9090:9090.
I know the port 9090 is open in server 10.116.66.175 because i can connect it by telnet.
But, when I try to connect to the application, I receive the following error:

Could not connect to 10.116.66.175:9090 : Connection refused to host: 172.17.0.16; nested exception is:
java.net.ConnectException: Connection timed out: connect
Could not connect to 10.116.66.175:9090. Make sure the JVM is running and that you are using the correct protocol in the Service URL (service:jmx:rmi:///jndi/rmi://10.116.66.175:9090/jmxrmi).

Can you give me some clue, some idea about the reason of this error? I suppose that exist some IP incompatibility or something like this.
Thanks in advance guys

Alejandro

I have the same problem. I’m using jconsole from jdk 1.8.0_40, container runs java 1.8.0_20.
Using java args:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.rmi.port=9110

Jconsole will “usually” connect initially, after warning about insecure connection, then becomes disconnected immediately. After that I cannot typically reconnect, and often (always?) need to force quite jconsole.

Any advice appreciated…

Thanks
Tyson

FYI mine started working after adding:
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=‘192.168.99.100’

1 Like

Have anybody been successful running multiple containers?
I have tomcat image that I use port 7777 for jmx, I have 3 containers running.
container1 port 7777 > host port 7777
container2 port 7777> host port 32786
containerr3 port 7777>host port 32789

I am only able to connect to the first container.
I can probably change the images to have different -Dcom.sun.management.jmxremote.port settings but I would like to use 1 image and just run it multiple times.

Is there a way to do that?

Thanks
G

Hi Team,

At first point consider: sun.management.jmxremote dynamically assigns a second port to use for RMI (https://ptmccarthy.github.io/2014/07/24/remote-jmx-with-docker/)

These are some scenarios to we need to consider for some JMX Docker Monitoring configuration:

  • Your Local Machine: 192.168.1.10 [docker0: 172.17.0.1 --> 172.22.0.**]
  • Your Remote Machine: 192.168.1.108 [docker0: 172.17.0.1 --> 172.22.0.**]
  • JMX port trying to expose for our docker container 6001

Local (192.168.1.10) --> Local Docker Service (192.168.1.10) [Local Container Spring Boot JMX Enabled]:
This is working as expected and able to connect from jmc, jconsole, jvisualvm:
java -Dcom.sun.management.jmxremote.port=6001 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -jar /app.jar

Or thru docker compose expose port 6001 (it does not matter if the external host port is the same or not):
ports:
- “6001”

Local (192.168.1.10) --> Non Local Docker Service (192.168.1.108) [Remote Container Spring Boot JMX Enabled]:
Suppose that you are continue using the same configuration:
java -Dcom.sun.management.jmxremote.port=6001 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -jar /app.jar

  • 1st attempt to solve: You are ready to use Java Mission Control and start your JMC to monitor JMX Remotely and you are seeing:
    Caused by: java.rmi.ConnectException: Connection refused to host: 172.22.0.6; nested exception is: _
    _ java.net.ConnectException: Expiró el tiempo de conexión

  • 2nd attempt to solve: Then you add this parameter -Djava.rmi.server.hostname=192.168.1.108 to your JMX, start your JMC to monitor JMX Remotely and you are seeing:
    Caused by: java.rmi.ConnectException: Connection refused to host: 192.168.1.108

  • 3rd attempt to solve: Then … you have no more options … BUT this parameter is going to help us -Dcom.sun.management.jmxremote.rmi.port=6001 , start your JMC to monitor JMX Remotely and you are seeing:

java -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=6001 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.1.108 -Dcom.sun.management.jmxremote.rmi.port=6001 -jar /app.jar

With these parameters you are able to connect from jmc, jconsole, jvisualvm to remote docker containers.

In my case, I am working with docker-compose please DON FORGET to expose the SAME PORT 6001 in the remote docker host (it won’t work if you expose in another port differently that jmxremote.port and jmxremote.rmi.port):
Ports

0.0.0.0:6001->6001/tcp


Hi @gshemtov, in your case you could connect to any JMX Docker Container on the same host but consider to manage the same por for:

  • management.jmxremote.port
  • jmxremote.rmi.port
  • and port to expose