【发布时间】:2016-05-20 03:12:57
【问题描述】:
我正在尝试使用 JMX 访问在 docker 容器内运行的应用程序。
这类似于this question,并且当 docker 映像内的端口映射到映像外的相同端口时,该解决方案有效。但是,有时我想将端口映射到不同的端口。
我正在托管应用程序中设置这些属性。
-Dcom.sun.management.jmxremote.port=9832
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.rmi.port=9832
-Djava.rmi.server.hostname=192.168.99.100
-Djava.rmi.server.logCalls=true
当 docker 容器将端口 9832 映射到 9832 时,这可以正常工作。我可以通过 JConsole 或我们自己的应用程序进行连接。如果改为将端口映射到另一个端口,则我无法从 JConsole 或我们的应用程序访问该应用程序。
我怀疑其中一两个端口号需要是外部端口(就像java.rmi.server.hostname 是外部地址,而不是内部地址)。但是,它会因所有四种端口号组合而失败。
其中两种组合不会从服务器产生日志输出。一个(我忘记了)产生这个输出:
Feb 09, 2016 10:35:54 PM org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl start
INFO: AMQ221001: Apache ActiveMQ Artemis Message Broker version 1.1.0 [nodeID=7a6e038e-cf7d-11e5-b566-31dc437b2d1a]
HTTP Server started at http://0.0.0.0:8161
Feb 09, 2016 10:36:06 PM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(1)-192.168.99.1: [192.168.99.1: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
Feb 09, 2016 10:36:08 PM sun.rmi.transport.Transport serviceCall
FINE: RMI TCP Connection(1)-192.168.99.1: [192.168.99.1] exception:
java.rmi.NoSuchObjectException: no such object in table
at sun.rmi.transport.Transport.serviceCall(Transport.java:177)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Feb 09, 2016 10:40:24 PM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(2)-192.168.99.1: [192.168.99.1: sun.rmi.transport.DGCImpl[0:0:0, 2]: void clean(java.rmi.server.ObjID[], long, java.rmi.dgc.VMID, boolean)]
另一个产生这个输出。
HTTP Server started at http://0.0.0.0:8161
Feb 09, 2016 10:14:13 PM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(1)-192.168.99.1: [192.168.99.1: sun.management.jmxremote.SingleEntryRegistry[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
Feb 09, 2016 10:14:17 PM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(1)-192.168.99.1: [192.168.99.1: sun.management.jmxremote.SingleEntryRegistry[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
Feb 09, 2016 10:14:17 PM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(1)-192.168.99.1: [192.168.99.1: sun.management.jmxremote.SingleEntryRegistry[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
鉴于这些故障,我怀疑其中一个或两个端口属性的使用方式有时需要作为内部端口,有时需要作为外部端口。这意味着当端口映射到不同的位置时,JMX 访问是不可能的。
我可以通过telnet 192.168.99.100 <mapped port> 访问映射端口,所以我知道映射正在工作。
【问题讨论】:
-
您是否在无日志期间检查了防火墙没有阻止 docker 容器暴露的端口?
-
@TyagiAkhilesh 我可以用telnet连接到端口,所以端口是可以访问的。
-
从内存中,JMX 告诉客户端在初始连接中要连接的第二个端口是什么。所以客户端希望能够连接到应用程序配置的端口。只需使用映射的端口。如果您确实想使用不同的 NAT 端口,请使用 socks 代理。
-
这个问题我们需要更多的赞。
-
您是否尝试过使用 2 个不同的端口和不同的映射?