问题描述
我的主机有网络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它不起作用。 p>
重复:
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.28080)
但是当我使用JMX它不起作用。
它是Tomcat服务。我有脚本启动Tomcat实例:
CATALINA_OPTS = - Xdebug -Xrunjdwp:transport = dt_socket,address = 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 = Docker的IP地址容器
我认为问题可能是 java.rmi.server.hostname
属性,这需要是JMX客户端用于连接到JVM的主机名或IP地址,这是第一个直接使用 172.17.0.2:1099
连接到您的容器的情况,此设置需要设置为 172.17.0.2
在后一种情况下,您可以通过码头机上的 192.168.99.100:109访问容器9
,设置需要设置为 192.168.99.100
。
在我的研究我偶然发现。虽然它比较老了,但是它给了我一个JMX连接如何工作的想法:
- JMX注册表侦听端口
; com.sun.management.jmxremote.port>
容器 - 如果使用JConsole连接到注册表,则注册表提供JMX服务URL客户端。
- 客户端使用此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
。由于此地址只能从码头机内部进行,远程连接是不可能的。在我的问题中,我涉及与RMI端口相同的问题...
似乎没有一个开箱即用的解决方案问题。但是,可以在容器启动时提供JMX端口和外部主机名(或IP)作为环境变量,如。这些可以在JMX配置中使用:
docker run -p 1099:1099 \
-e JMX_HOST = 192.168.99.100\
-eJMX_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
不是很好,但它应该工作...
When I have running Docker container directly at my host, it is possible to connect to it without any problems.
My host has network 192.168.1.0/24 and IP address of the host is 192.168.1.20. My Docker container has IP address 172.17.0.2. When I connect to 172.17.0.2:1099 from jconsole it works.
When I put this service into Docker machine, it is not possible to connect to it.
My Docker machine has IP 192.168.99.100 and container in it has IP address 172.17.0.2 but when I use jconsole to connect to 192.168.99.100:1099 it does not work.
To repeat it:
192.168.1.20 --- 172.17.0.2:1099 works
192.168.1.20 --- (192.168.99.100 --- 172.17.0.2:1099) and connecting to 192.168.99.100:1099 from my host does not work.
It is worth to say that I can access services containerized in Docker machine via external IP address of the Docker machine, e.g. this will work:
192.168.99.100 --- (192.168.99.100:8080 --- 172.17.0.2:8080)
But when I use JMX it just does not work.
It is Tomcat service. I have this in scripts which starts Tomcat instance:
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
I think the problem is probably the value of the java.rmi.server.hostname
property. This needs to be the hostname or IP address that should be used by the JMX client to connect to your JVM. That is in the first case where you connect to your container directly using 172.17.0.2:1099
, this setting needs to be set to 172.17.0.2
. In the latter case where you access the container through the docker machine on 192.168.99.100:1099
, the setting needs to be set to 192.168.99.100
.
During my research for this very similar question I stumbled across this blog entry. Although It's rather old it gave me an idea how the JMX connectivity works:
- The JMX registry listens on port
<com.sun.management.jmxremote.port>
of the container - If you connect to the registry with JConsole, the registry provides the JMX service URL to the client.
- This URL is used by the client to obtain the JMX objects
The service URL looks like this service:jmx:rmi:///jndi/rmi://<java.rmi.server.hostname>:<com.sun.management.jmxremote.rmi.port>/jmxrmi
. That is in your case service:jmx:rmi:///jndi/rmi://172.17.0.2:1099/jmxrmi
. As this address is only reachable from within the docker machine, connecting from remote is not possible. In my question I cover the same problem in regards to the RMI port...
There doesn't seem to be an out-of-the-box solution to this problem. However one can provide both JMX port and the external hostname (or IP) on startup of the container as environment variables, as suggested here. These could than be used in the JMX config:
docker run -p 1099:1099 \
-e "JMX_HOST=192.168.99.100" \
-e "JMX_PORT=1099" \
company/tomcat:8.0.30
and
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"
Not very nice, but it should work...
这篇关于如何将JMX从主机连接到Docker机器中的Docker容器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!