当我直接在主机上运行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
我认为问题可能在于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。
java.rmi.server.hostname
172.17.0.2:1099
172.17.0.2
192.168.99.100:1099
192.168.99.100
在研究非常相似的问题(同时被删除)的过程中,我偶然发现了一个博客条目(同时也被删除了)。尽管它已经很老了,但它让我知道了JMX连接的工作原理:
<com.sun.management.jmxremote.port>
服务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端口方面的相同问题…
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
似乎没有针对此问题的开箱即用的解决方案。但是一个可以同时提供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"
不太好,但是应该可以…