【问题标题】:How can I connect to JMX through Kubernetes managed Docker containers?如何通过 Kubernetes 管理的 Docker 容器连接到 JMX?
【发布时间】:2017-04-25 11:30:06
【问题描述】:

我正在尝试使用 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 端口);这表明我的课有效。我还确保 Kubernetes 端的 1099 端口是开放的,所以这不是阻塞它的原因。

正如许多关于 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 完成这个工作?

【问题讨论】:

  • 你试过用kubectl port-forward [podname] 1099:1099 来测试它是否在听吗?
  • 另外,10.xxx.xxx.xxx range of IPs are reserved。这不是公共 IP,因此您可能无法连接到它。您可能需要设置服务和入口以通过节点的 IP 地址与您的 pod 对话。
  • @3ocene 端口转发在我们的例子中不是一个选项。我们需要能够针对我们的情况使用节点端口。 10.xxx.xxx.xxx 地址是私有 IP,集群是我们私有网络的一部分。请注意,我们从集群中的一个节点到 podIP:1099 进行了 ssh 隧道,并且连接正常,但它不适用于 node:nodePort。
  • 需要明确的是,@realgenob 也在与我合作并遇到同样的问题。
  • 您是否尝试过指定-Djava.rmi.server.hostname=10.x.x.x?我们对 Openstack 虚拟机进行了类似的设置,其中 OpenStack 将内部 IP 分配给虚拟机,但您使用外部路由 IP 来访问应用程序。所以我们用外部 IP 指定了那个参数并且它起作用了(当然,当你想要动态地制作它时,你会遇到下一个问题)。

标签: java docker spring-boot kubernetes jmx


【解决方案1】:

jmx 远程连接使用起来很痛苦,在我看来,代理它是不可能的。我有类似的问题,最后我只是使用 jolokia 连接。

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

【讨论】:

  • 感谢分享 Jolokia。那么,您是否最终在容器中安装了代理(看起来像是给 Java 应用程序提供了一个带有 .jar 文件路径的参数)?或者,如果您有一个 Spring 应用程序上下文,您是否只是添加了一个简单的 Maven 依赖项?
  • 就我而言,我只使用战争版本。非常适合我的需求。
  • 很高兴听到。如果我目前的方法一切都失败了,我可能会走这条路;它是否涉及任何持续监控(例如通过套接字)还是只是请求和响应?
  • 就我使用它而言的请求和响应。
猜你喜欢
  • 1970-01-01
  • 2020-10-05
  • 1970-01-01
  • 2016-11-23
  • 2017-06-30
  • 1970-01-01
  • 2016-05-29
  • 2021-03-11
  • 2019-03-07
相关资源
最近更新 更多