如何通过Kubernetes托管的Docker容器连接到JMX?

时间:2016-12-09 22:14:02

标签: java docker spring-boot kubernetes jmx

我正在尝试使用JConsole,Java Mission Control等客户端连接到我在Java应用程序(Java 8和Spring Boot 1.4和Tomcat)上定义为1099(默认情况下)的JMX端口或Java VisualVM,但我遇到了错误:

java.rmi.ConnectException: Connection refused to host: 10.xxx.xxx.xx, nested exception is:
     java.net.ConnectException: Connection timed out
     ...

请注意,我隐藏了确切的主机IP,但它是部署了我的服务的特定Kubernetes管理的Docker容器的pod IP。我尝试使用以下服务URL连接到JMX端口:

jconsole service:jmx:rmi://<nodeIP>:<nodePort>/jndi/rmi://<nodeIP>:<nodePort>/jmxrmi 

我知道JMX会打开random high port,我试图通过加入custom @Configuration class that forces that high port to also serve on port 1099来解决这个问题。我已经进入实际的容器和pod并运行

netstat -tulpn

查看打开的端口,我已确认打开的唯一端口是8443(我的应用程序正在运行)和1099(JMX端口);这表明我的班级有效。我还确保端口1099在Kubernetes端打开,因此不会阻止它。

关于JMX远程连接的许多答案已经提出,我尝试了以下Java选项的许多变体无济于事:

-Dcom.sun.management.jmxremote  -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.jmi.port=1099 -Djava.rmi.server.hostname=0.0.0.0

答案建议强制JMX端口和RMI注册表端口相同,但这些都没有奏效。

我认为问题可能是因为主机名(因为我试图用-Djava.rmi.server.hostname = 0.0.0.0创建动态)无法解析为每次我创建的不同主机名(pod IP)服务已部署。

因此,看起来连接无法完成,因为在部署服务后,JMX无法查看Kubernetes分配的主机名。

JMX有没有办法识别Kubernetes主机名?或者,是否有其他方法通过Kubernetes部署的服务远程连接到JMX端口?

编辑1:我做了一些额外的研究,也许可选的JMXMP而不是RMI可能有用吗?有没有人让这个与Tomcat合作?

1 个答案:

答案 0 :(得分:1)

jmx远程连接很难处理,从我看来代理它是不可能的。我有类似的问题,最后我只是用jolokia连接。

Jolokia是一个JMX-HTTP桥接器,可替代JSR-160连接器。它是一种基于代理的方法,支持许多平台。除了基本的JMX操作之外,它还通过批量请求和细粒度安全策略等独特功能增强了JMX远程处理功能。 - &GT; http://jolokia.org