JMX – 远程pipe理到docker-compose容器中 – 无法检索RMIServer存根

我想将REAL远程JMXpipe理放入运行Spring Boot应用程序的Docker容器中:

build筑学剪影

在这里输入图像说明

我读过很多文档,我的理解是这应该是服务器端configuration:

java \ -Djava.rmi.server.hostname=10.0.2.15 \ -Dcom.sun.management.jmxremote.port=8600 \ -Dcom.sun.management.jmxremote.rmi.port=8601 \ -Dcom.sun.management.jmxremote.ssl=false \ -Dcom.sun.management.jmxremote.authenticate=false \ -Dcom.sun.management.jmxremote.local.only=false \ -jar my-spring-boot-app.jar 

在JVisualVM中使用的URL应该是service:jmx:rmi://10.0.2.15:8601/jndi/rmi://10.0.2.15:8600/jmxrmi

但是这个失败无法检索RMIServer存根 )在JVisualVM(在机器1上启动) – 这是日志输出:

导致:java.io.IOException:未能在javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:369)上的com.sun.tools.visualvm.jmx.impl.JmxModelImpl $ ProxyClient.tryConnect上检索RMIServer存根(JmxModelImpl.java:549)[catch] at com.sun.tools.visualvm.jmx.impl.JmxModelImpl $ ProxyClient.connect(JmxModelImpl.java:486)at com.sun.tools.visualvm.jmx.impl.JmxModelImpl。连接(JmxModelImpl.java:214)

如果我将服务器应用程序configuration更改为-Djava.rmi.server.hostname=172.19.0.6 (我使用BRDIGE dockernetworking…,因此可以路由到172.19.0.6 )。 有了这个configuration,如果在Docker主机(机器2)上启动JVisualVM,我能够执行JMX监视。 但是这是没有实际的远程pipe理,因为路由到172.19.0.6通常是不可能的。


一些额外的信息:

端口8600,8601暴露在外,显示为LISTEN:

pfh@workbench ~/temp/ % netstat -taupen | grep 860 tcp6 0 0 :::8600 :::* LISTEN 0 254349 - tcp6 0 0 :::8601 :::* LISTEN 0 254334 -

和机器1的telnet 10.0.2.15 8600是可能的。

1.7.0_80容器和Docker主机(运行JVisualVM)上,Java 1.8.0_1111.7.0_80行为1.8.0_111出现同样的错误行为。

顺便说一下:如果Spring Boot应用程序直接在机器2上运行(没有Docker),这个configuration工作。

我知道JMX通常会协调随机端口…我尝试在我的configuration中使它们显式化。 还有一个额外的属性-Dcom.sun.aas.jconsole.server.cbport=8602可以设置,但这并没有解决问题。

我的错在哪里?

在我的问题描述中,我隐藏了docker容器,通过docker-compose启动了这个configuration:

my-spring-boot-service: ... ports: - "8610:8610" - "8611:8611"

…这样的结果是开放的端口似乎是绑定到所有的接口,你可以通过docker inspect my-spring-boot-app

"NetworkSettings": { "Bridge": "", "SandboxID": "ac1a27e2696fd4ac2fcddf6e0935716304e348203ddbe1a0f8e31114cc6e289b", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": { "8610/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "8610" } ], "8611/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "8611" } ],

我在这里看不到问题… 但这似乎是问题,因为如果我通过docker本身启动容器(如@zapl所示)

docker run -p 8610:8610 -p 8611:8611 my-spring-boot-app-image

它工作 – 但不是我想要的方式 – 我想使用docker撰写

两个部署之间有一个区别… docker inspect network <foo>

在工作docker网上看起来就是这样:

  "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, 

在非工作的docker-composenetworking看起来这样:

  "Options": {}, 

两个容器configuration都不使用明确定义的networking,而是默认的networking。

问题:是否有configuration丢失? 我应该在docker-compose明确定义一个networking吗?

docker-elk是一个基于docker-compose的部署。 我configuration了JMX接口的描述configuration,并能够远程JMX这台机器。

我的JMXconfiguration是完全一样的 – 矿不工作:-(


OS / Arch:linux / amd64 docker版本:1.12.2 docker-compose版本:1.8.0,build f3628c7和1.9.0,build 2585387