tag library imagenes hub dockers container compose docker jmx apache-kafka jmxtrans

library - download docker image



¿Cómo acceder a la interfaz JMX en docker desde el exterior? (4)

Descubrí que tratar de configurar JMX sobre RMI es una molestia, especialmente debido a -Djava.rmi.server.hostname=<IP> que debe especificar en el inicio. Estamos ejecutando nuestras imágenes docker en Kubernetes donde todo es dinámico.

Terminé usando JMXMP en lugar de RMI, ya que solo necesitaba un puerto TCP abierto y ningún nombre de host.

Mi proyecto actual usa Spring, que se puede configurar agregando esto:

<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean"/>

(Fuera de Spring, debe configurar su propio JMXConncetorServer para que esto funcione)

Junto con esta dependencia (ya que JMXMP es una extensión opcional y no es parte de JDK):

<dependency> <groupId>org.glassfish.main.external</groupId> <artifactId>jmxremote_optional-repackaged</artifactId> <version>4.1.1</version> </dependency>

Y debe agregar el mismo archivo jar que su classpath cuando inicie JVisualVM para conectarse a través de JMXMP:

jvisualvm -cp "$JAVA_HOME/lib/tools.jar:<your_path>/jmxremote_optional-repackaged-4.1.1.jar"

Luego conecte con la siguiente cadena de conexión:

service:jmx:jmxmp://<url:port>

(El puerto predeterminado es 9875)

Estoy tratando de monitorear remotamente una JVM que se ejecuta en la ventana acoplable. La configuración se ve así:

  • máquina 1: ejecuta una JVM (en mi caso, ejecutando kafka) en la ventana acoplable en una máquina ubuntu; la IP de esta máquina es 10.0.1.201; la aplicación que se ejecuta en la ventana acoplable está en 172.17.0.85.

  • máquina 2: ejecuta monitoreo JMX

Tenga en cuenta que cuando ejecuto la supervisión JMX desde la máquina 2, falla con una versión del siguiente error (nota: el mismo error ocurre cuando ejecuto jconsole, jvisualvm, jmxtrans y node-jmx / npm: jmx):

El seguimiento de la pila al fallar se parece a lo siguiente para cada una de las herramientas de monitoreo JMX:

java.rmi.ConnectException: Connection refused to host: 172.17.0.85; nested exception is java.net.ConnectException: Operation timed out at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619) (followed by a large stack trace)

Ahora, la parte interesante es cuando ejecuto las mismas herramientas (jconsole, jvisualvm, jmxtrans y node-jmx / npm: jmx) en la misma máquina que ejecuta la ventana acoplable (máquina 1 desde arriba), la supervisión de JMX funciona correctamente.

Creo que esto sugiere que mi puerto JMX está activo y funcionando correctamente, pero que cuando ejecuto la supervisión de JMX de forma remota (desde la máquina 2) parece que la herramienta JMX no reconoce la IP de la ventana acoplable interna (172.17.0.85)

A continuación, se encuentran los elementos de configuración de red relevantes (creo) en la máquina 1 donde funciona la supervisión de JMX (observe el docker ip, 172.17.42.1):

docker0 Link encap:Ethernet HWaddr ... inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr:... Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:6787941 errors:0 dropped:0 overruns:0 frame:0 TX packets:4875190 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1907319636 (1.9 GB) TX bytes:639691630 (639.6 MB) wlan0 Link encap:Ethernet HWaddr ... inet addr:10.0.1.201 Bcast:10.0.1.255 Mask:255.255.255.0 inet6 addr:... Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:4054252 errors:0 dropped:66 overruns:0 frame:0 TX packets:2447230 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2421399498 (2.4 GB) TX bytes:1672522315 (1.6 GB)

Y estos son los elementos de configuración de red relevantes en la máquina remota (máquina 2) de los cuales recibo los errores de JMX:

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 options=3<RXCSUM,TXCSUM> inet6 ::1 prefixlen 128 inet 127.0.0.1 netmask 0xff000000 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 nd6 options=1<PERFORMNUD> en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 ether .... inet6 ....%en1 prefixlen 64 scopeid 0x5 inet 10.0.1.203 netmask 0xffffff00 broadcast 10.0.1.255 nd6 options=1<PERFORMNUD> media: autoselect status: active


Para completar, la siguiente solución funcionó. La JVM debe ejecutarse con los parámetros específicos establecidos para habilitar la supervisión remota JMX de la ventana acoplable, como se muestra a continuación:

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.rmi.port=<PORT> -Djava.rmi.server.hostname=<IP> where: <IP> is the IP address of the host that where you executed ''docker run'' <PORT> is the port that must be published from docker where the JVM''s JMX port is configured (docker run --publish 7203:7203, for example where PORT is 7203)

Una vez hecho esto, debería poder ejecutar la supervisión JMX (jmxtrans, node-jmx, jconsole, etc.) desde una máquina local o remota.

Gracias a @Chris-Heald por hacer de esto una solución realmente rápida y simple.


Para el entorno de desarrollo, puede establecer java.rmi.server.hostname en la dirección IP de captura de todos 0.0.0.0

Ejemplo:

-Djava.rmi.server.hostname=0.0.0.0 / -Dcom.sun.management.jmxremote / -Dcom.sun.management.jmxremote.port=${JMX_PORT} / -Dcom.sun.management.jmxremote.rmi.port=${JMX_PORT} / -Dcom.sun.management.jmxremote.local.only=false / -Dcom.sun.management.jmxremote.authenticate=false / -Dcom.sun.management.jmxremote.ssl=false


Creé un proyecto de GitHub que contiene una implementación lista para usar de JMX desde un contenedor Docker.

Contiene un Dockerfile con un entrypoint.sh adecuado, y un docker-compose.yml para una fácil implementación.