一尘不染

如何将JMX从主机连接到Docker机器中的Docker容器?

tomcat

当我直接在主机上运行Docker容器时,可以毫无问题地连接到它。

我的主机的网络为192.168.1.0/24,主机的IP地址为192.168.1.20。我的Docker容器的IP地址为172.17.0.2。当我从jconsole连接到172.17.0.2:1099时,它可以工作。

当我将此服务放入Docker机器时,无法连接到它。

我的Docker机器的IP地址为192.168.99.100,容器中的IP地址为172.17.0.2,但是当我使用jconsole连接到192.168.99.100:1099时,它不起作用。

要重复它:

192.168.1.20 — 172.17.0.2:1099有效

192.168.1.20 —(192.168.99.100 —
172.17.0.2:1099)并无法从我的主机连接到192.168.99.100:1099。

值得一提的是,我可以通过Docker计算机的外部IP地址访问Docker计算机中容器化的服务,例如,这可以工作:

192.168.99.100 —(192.168.99.100:8080 — 172.17.0.2:8080)

但是,当我使用JMX时,它将无法正常工作。

它是Tomcat服务。我在启动Tomcat实例的脚本中有这个:

CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n \
-Dcom.sun.management.jmxremote.port=1099 \
-Dcom.sun.management.jmxremote.rmi.port=1099 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=IP address of Docker container

阅读 535

收藏
2020-06-16

共1个答案

一尘不染

我认为问题可能在于java.rmi.server.hostname财产的价值。这必须是JMX客户端用于连接到JVM的主机名或IP地址。在第一种情况下,您直接使用来连接到容器172.17.0.2:1099,此设置需要设置为172.17.0.2。在后一种情况下,您通过docker机器访问容器192.168.99.100:1099,则需要将设置设置为192.168.99.100

在研究非常相似的问题(同时被删除)的过程中,我偶然发现了一个博客条目(同时也被删除了)。尽管它已经很老了,但它让我知道了JMX连接的工作原理:

  1. JMX注册表侦听<com.sun.management.jmxremote.port>容器的端口
  2. 如果使用JConsole连接到注册表,则注册表将向客户端提供JMX服务URL。
  3. 客户端使用此URL来获取JMX对象

服务URL如下所示service:jmx:rmi:///jndi/rmi://<java.rmi.server.hostname>:<com.sun.management.jmxremote.rmi.port>/jmxrmi。那是你的情况service:jmx:rmi:///jndi/rmi://172.17.0.2:1099/jmxrmi。由于只能从docker机器内部访问此地址,因此无法从远程连接。在我的问题中,我涉及RMI端口方面的相同问题…

似乎没有针对此问题的开箱即用的解决方案。但是一个可以同时提供JMX端口和容器的环境变量启动外部主机名(或IP),如建议在这里。这些可以在JMX配置中使用:

docker run -p 1099:1099 \
    -e "JMX_HOST=192.168.99.100" \
    -e "JMX_PORT=1099" \
    company/tomcat:8.0.30

CATALINA_OPTS="... \
    -Dcom.sun.management.jmxremote=true \
    -Dcom.sun.management.jmxremote.port=$JMX_PORT \
    -Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Djava.rmi.server.hostname=$JMX_HOST"

不太好,但是应该可以…

2020-06-16