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

标签 docker port jmx

我正在尝试使用 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> 访问映射的端口,所以我知道映射正在工作。

最佳答案

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

...
ports:
  - '9011:9011'
...
environment:
  - JMX_MNG_PORT=9011
...

然后我在 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}
...

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

记住,我不知道为什么,但是如果您使用另一个端口,那么在 jmxremote.port 和 jmxremote.rmi.port 上配置的那个端口将不起作用。

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

关于docker - 使用映射端口访问 docker 容器内的 JMX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35303837/

相关文章:

linux - 如何在 Docker 中处理对/dev/(u)random 等的请求?

sockets - 如何在 fork 进程中处理套接字连接

docker - curl (56) 接收失败 : Connection reset by peer - when hitting docker container

java - 在同一进程中使用 SMSLib 发送多条短信

java - MBean 和 MXBean 的区别

tomcat - 从 JMX MBeans 了解 tomcat HTTP 连接器端口

mysql - 更改 Docker 容器中的 mysql 密码

docker - 在运行时在Pod中创建其他容器的正确方法是什么?

docker - 在docker中提交子图像后如何删除父图像?

java - 如何从命令行将参数传递到 JMX MBean 函数