我想在运行Spring Boot应用程序的docker容器中进行REAL远程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中使用的网址应为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 -
和telnet 10.0.2.15 8600
是可能的。
我在docker容器和docker主机(运行JVisualVM)上使用Java 1.8.0_111
和1.7.0_80
获得了相同的错误行为。
BTW:如果Spring Boot应用程序直接在机器2上运行(没有Docker),则此配置有效。
我知道JMX通常协商随机端口......我尝试在我的配置中明确它们。还可以设置一个额外的属性-Dcom.sun.aas.jconsole.server.cbport=8602
,但这并没有解决问题。
我的错在哪里?
答案 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)
也许我应该切换到JMXMP而不是JMXRMI - https://github.com/oracle/docker-images/tree/master/OracleCoherence/docs/5.monitoring