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

时间:2016-11-30 08:36:14

标签: java docker jmx

我想在运行Spring Boot应用程序的docker容器中进行REAL远程JMX管理:

架构草图

enter image description here

我已经阅读了很多文档,我的理解是这应该是服务器端配置:

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中使用的网址应为service:jmx:rmi://10.0.2.15:8601/jndi/rmi://10.0.2.15:8600/jmxrmi

但是这次失败无法检索RMIServer存根)在JVisualVM中(在计算机1上启动) - 这是日志输出:

  

引发:java.io.IOException:无法检索RMIServer存根   javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:369)     在   com.sun.tools.visualvm.jmx.impl.JmxModelImpl $ ProxyClient.tryConnect(JmxModelImpl.java:549)   [抓住]   com.sun.tools.visualvm.jmx.impl.JmxModelImpl $ ProxyClient.connect(JmxModelImpl.java:486)     在   com.sun.tools.visualvm.jmx.impl.JmxModelImpl.connect(JmxModelImpl.java:214)

IT工作如果我将服务器应用程序配置更改为-Djava.rmi.server.hostname=172.19.0.6(我使用BRDIGE docker网络......因此可以路由到172.19.0.6)。使用此配置,如果在Docker主机(计算机2)上启动JVisualVM,我可以执行JMX监视。但这不是真正的远程管理,因为通常不可能路由到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是可能的。

我在docker容器和docker主机(运行JVisualVM)上使用Java 1.8.0_1111.7.0_80获得了相同的错误行为。

BTW:如果Spring Boot应用程序直接在机器2上运行(没有Docker),则此配置有效。

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

我的错在哪里?

2 个答案:

答案 0 :(得分:1)

在我的问题描述中,我隐藏了使用此配置通过docker-compose启动了docker容器:

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

IT工作 - 但不是我想要的方式 - 我想使用docker-compose

两个部署之间存在差异...... 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-compose网络上的

看起来像这样:

    "Options": {},

两个容器配置都不使用明确定义的网络,而是使用默认网络。

问题:是否缺少配置?我应该在docker-compose中明确定义网络吗?

docker-elk是基于docker-compose的部署。我配置了described configuration of the JMX interface并能够远程JMX这台机器。

我的JMX配置完全一样 - MINE不工作:-(

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

答案 1 :(得分:1)