我试图在远程Java-in-Docker进程中获取一些CPU采样工作。将VisualVM或JConsole附加到GCE上的Docker中的Java
我已经看过这里的相关问题,并尝试了一切,无济于事,所以我在这里发布我的设置。
我有一个在谷歌计算引擎(GCE)实例的Docker容器中运行的Java进程(openjdk-8)。 GCE实例和容器都运行Debian-9。我想将VisualVM或JConsole附加到我的Java进程。
我能够在本地运行我的码头集装箱,并使用localhost:9010与visualvm和jconsole连接。
我开始容器的虚拟机启动脚本:
docker run -d -p 9010:9010 <my container>
的Dockerfile还具有:
EXPOSE 9010
Java进程,由Dockerfile CMD开始,具有以下相关ARGS:
"-Dcom.sun.management.jmxremote", \
"-Dcom.sun.management.jmxremote.port=9010", \
"-Dcom.sun.management.jmxremote.rmi.port=9010", \
"-Dcom.sun.management.jmxremote.local.only=false", \
"-Dcom.sun.management.jmxremote.authenticate=false", \
"-Dcom.sun.management.jmxremote.ssl=false", \
我在我的gcloud防火墙中打开了端口9010,使用:
gcloud compute firewall-rules create jmx-port --allow=tcp:9010,udp:9010
我用netcat验证过端口是开放的,我可以与它建立TCP连接。
我从同一个Docker容器打开其他端口,客户端连接成功到这些端口。它们被暴露并以相同的方式映射到主机端口(-p port:port),并以相同的方式在防火墙中打开。
我正在传递GCE实例的外部IP地址。举例来说,如果我做的:
gcloud compute instances list
,它告诉我:
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
my-server-b23j us-central1-d n1-standard-1 10.240.0.2 108.357.213.99 RUNNING
然后,我将使用参数:
108.357.213.99:9010
为远程JMX连接主机:端口对。
VisualVM和JConsole都告诉我他们无法连接到远程JMX服务。在这两种情况下,我拒绝了安全连接,然后他们说:
Cannot connect to 108.357.213.99:9010 using
service:jmx:rmi:////jndi/rmi://108.357.213.99:9010/jmxrmi
在绝望中,我添加了一个防火墙规则,允许在所有端口65535 TCP/UDP连接,但它并没有区别 - 他们仍然无法连接。
我读过,JMX-RMI打开了匿名端口,你可以(至少部分地?)通过指定两种禁用此行为:
"-Dcom.sun.management.jmxremote.port=9010", \
"-Dcom.sun.management.jmxremote.rmi.port=9010", \
但是,它不会做的伎俩在我的情况。
我读过here,你需要指定RMI服务器主机名:
-Djava.rmi.server.hostname='192.168.99.100'
,但我的服务器IP是短暂的 - 它是由谷歌Compute Engine的,当我创建实例分配的,所以我不能用Java参数的其余部分将它硬连接到Dockerfile中。
我必须得到一个静态IP地址才能使这项工作?
一般来说visualvm在同一主机上效果最好。你可以在云实例中执行它吗? –