繁体   English   中英

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

[英]How to connect with JMX from host to Docker container in Docker machine?

当我直接在主机上运行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 在后一种情况下,您通过192.168.99.100:1099上的docker机器访问容器,该设置需要设置为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 由于此地址只能从泊坞机内部访问,因此无法从远程连接。 在我的问题中,我讨论了与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"

不是很好,但它应该工作......

如果有人有问题。 我已经使用以下参数在docker容器中启动了java进程:

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=9876 
-Dcom.sun.management.jmxremote.rmi.port=9876 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Djava.rmi.server.hostname=<name of the docker container>

重要的是设置docker容器的名称。 EXPOSE容器9876中的端口。我还设置了一个ssh连接并将9876转发到localhost。

以下内容适用于您的SSH配置:

LocalForward 127.0.0.1:9876 127.0.0.1:9876

我也在本地机器上设置了/ etc / hosts

127.0.0.1 <name of the docker container>

现在将控制台连接到“docker容器的名称”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM