【问题标题】:JMX - remote management into docker-compose container - Failed to retrieve RMIServer stubJMX - 远程管理到 docker-compose 容器 - 无法检索 RMIServer 存根
【发布时间】:2023-04-09 02:22:01
【问题描述】:

我想对运行 Spring Boot 应用程序的 docker 容器进行真正的远程 JMX 管理:

建筑草图

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

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:无法在以下位置检索 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 WORKS 如果我将服务器应用程序配置更改为 -Djava.rmi.server.hostname=172.19.0.6(我使用 BRDIGE docker 网络...因此可以路由到 172.19.0.6)。使用此配置,如果 JVisualVM 在 Docker 主机(机器 2)上启动,我可以进行 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 得到同样的错误行为。

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

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

我的错在哪里?

【问题讨论】:

  • “端口 8600、8601 已暴露”意味着您同时运行 docker run -p 8600:8600 -p 8601:8601 somedockerimage 以在您的主机上拥有这些端口,以及 docker 映像也在内部 EXPOSEs 这些端口(如 @987654322 @)?
  • 完全正确......我不知道这是否重要,但容器由docker-compose 启动/管理......我会测试这是否会改变一些东西
  • @zapl: 哇...它在使用docker run 时有效,但不是通过docker-compose up ...这是我的docker-compose.yml:my-spring-boot-service: ... ports: - "8610:8610" - "8611:8611"

标签: java docker jmx


【解决方案1】:

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

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-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 配置完全相同 - 我的不工作 :-(


操作系统/Arch:linux/amd64 码头工人版本:1.12.2 docker-compose 版本:1.8.0,构建 f3628c7 和 1.9.0,构建 2585387

【讨论】:

    【解决方案2】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      • 1970-01-01
      • 2018-04-04
      相关资源
      最近更新 更多