tomcat - 如何使用 JMX 从主机连接到 Docker 机器中的 Docker 容器?

标签 tomcat networking docker jmx docker-machine

当我直接在我的主机上运行 Docker 容器时,可以毫无问题地连接到它。

我的主机有网络 192.168.1.0/24,主机的 IP 地址是 192.168.1.20。我的 Docker 容器的 IP 地址为 172.17.0.2。当我从 jconsole 连接到 172.17.0.2:1099 时,它工作正常。

当我将此服务放入 Docker 机器时,无法连接到它。

我的 Docker 机器的 IP 为 192.168.99.100,其中的容器的 IP 地址为 172.17.0.2,但是当我使用 jconsole 连接到 192.168.99.100:1099 时,它不起作用。

重复一遍:

192.168.1.20 --- 172.17.0.2:1099 有效

192.168.1.20 --- (192.168.99.100 --- 172.17.0.2:1099) 从我的主机连接到 192.168.99.100:1099 不工作。

值得一提的是,我可以通过 Docker 机器的外部 IP 地址访问 Docker 机器中容器化的服务,例如这将起作用:

192.168.99.100 --- (192.168.99.100:8080 --- 172.17.0.2:8080)

但是当我使用 JMX 时它就不起作用了。

是Tomcat服务。我在启动 Tomcat 实例的脚本中有这个:

CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n \
-Dcom.sun.management.jmxremote.port=1099 \
-Dcom.sun.management.jmxremote.rmi.port=1099 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=IP address of Docker container 

最佳答案

我认为问题可能出在 java.rmi.server.hostname 的值上属性(property)。这需要是 JMX 客户端用来连接到 JVM 的主机名或 IP 地址。这是第一种情况,您使用 172.17.0.2:1099 直接连接到您的容器。 , 此设置需要设置为 172.17.0.2 .在后一种情况下,您通过 192.168.99.100:1099 上的 docker 机器访问容器。 ,设置需要设置为192.168.99.100 .

在我研究一个非常相似的问题(同时被删除)时,我偶然发现了一个博客条目(同时也被删除了)。虽然它相当古老,但它让我了解了 JMX 连接的工作原理:

  1. JMX 注册表监听端口 <com.sun.management.jmxremote.port>容器的
  2. 如果您使用 JConsole 连接到注册表,注册表会向客户端提供 JMX 服务 URL。
  3. 客户端使用此 URL 获取 JMX 对象

服务 URL 如下所示 service:jmx:rmi:///jndi/rmi://<java.rmi.server.hostname>:<com.sun.management.jmxremote.rmi.port>/jmxrmi .那就是你的情况service:jmx:rmi:///jndi/rmi://172.17.0.2:1099/jmxrmi .由于此地址只能从 docker 机器内部访问,因此无法从远程连接。在我的问题中,我谈到了关于 RMI 端口的相同问题......

这个问题似乎没有现成的解决方案。然而,可以在容器启动时同时提供 JMX 端口和外部主机名(或 IP)作为环境变量,如建议的那样 here .然后可以在 JMX 配置中使用它们:

docker run -p 1099:1099 \
    -e "JMX_HOST=192.168.99.100" \
    -e "JMX_PORT=1099" \
    company/tomcat:8.0.30

CATALINA_OPTS="... \
    -Dcom.sun.management.jmxremote=true \
    -Dcom.sun.management.jmxremote.port=$JMX_PORT \
    -Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Djava.rmi.server.hostname=$JMX_HOST"

不是很好,但应该可以...

关于tomcat - 如何使用 JMX 从主机连接到 Docker 机器中的 Docker 容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35466461/

相关文章:

带有 Go cli 项目的 Docker

java - 我应该如何解决 Springframework.Dispatcherservlet 错误?

tomcat - 由于添加了一些监听器,如何调试 tomcat 启动卡住

spring - 使用 aws ecs 运行图像会抛出 504 网关超时

jsp - Maven 编译/安装更改 JSP 内容

c - getpeername函数的理解

iphone - 将文件从 iphone 应用程序发送到本地服务器?

mysql - [失败] : Starting MySQL in my Ubuntu docker

node.js - 无法从其他容器或主机访问带有 nodejs 应用程序(NestJS)的 Docker 容器

docker - Docker CMD无法识别pm2-runtime