使用映射端口访问Docker容器内的JMX

Tro*_*els 8 port jmx docker

我正在尝试使用JMX访问在docker容器内运行的应用程序.

这与此问题类似,当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
Run Code Online (Sandbox Code Playgroud)

当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)]
Run Code Online (Sandbox Code Playgroud)

另一个产生这个输出.

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)]
Run Code Online (Sandbox Code Playgroud)

鉴于这些失败,我怀疑一个或两个端口属性的使用方式有时需要是内部端口,有时需要是外部端口.这意味着当端口映射到不同位置时,无法进行JMX访问.

我可以通过访问映射端口telnet 192.168.99.100 <mapped port>,所以我知道映射正在工作.

Fel*_*ati 0

我遇到了同样的问题,连续三天,我刚刚放弃,我做了一个不是很好但有效的解决方案。所以,我的解决方案是:我没有为 JMX 连接设置固定端口并使用不同的外部端口映射它,而是在 docker-compose.yml 上创建了一个名为 JMX_MNG_PORT 的环境变量。

...
ports:
  - '9011:9011'
...
environment:
  - JMX_MNG_PORT=9011
...
Run Code Online (Sandbox Code Playgroud)

然后我在 docker-entrypoint.sh 上配置 JAVA_OPTS 变量来接收 JMX_MNG_PORT。

...
JAVA_OPTS=$JAVA_OPTS -Dcom.sun.management.jmxremote.port=${JMX_MNG_PORT}
JAVA_OPTS=$JAVA_OPTS -Dcom.sun.management.jmxremote.rmi.port=${JMX_MNG_PORT}
...
Run Code Online (Sandbox Code Playgroud)

现在,在配置的每个容器 (docker-compose.yml) 上,我只需配置 JMX_MNG_PORT 并使用相同的编号公开端口。

请记住,我不知道为什么,但如果您使用另一个端口,然后使用 jmxremote.port 和 jmxremote.rmi.port 上配置的端口,它将无法工作。

我希望它能为像我这样的其他人解决这个问题。