我正在尝试让一些CPU采样在远程Java-in-Docker进程上工作。
我已经查看了这里的相关问题,并尝试了所有方法,但都没有用,所以我在这里发布了我的设置。
我有一个Java进程(openjdk-8)在Google Compute Engine (GCE)实例上的Docker容器中运行。GCE实例和容器都在运行Debian-9。我希望将VisualVM或JConsole附加到我的Java进程。
我能够在本地运行我的docker容器,并使用localhost:9010连接到visualvm和jconsole。
我在VM启动脚本中使用以下命令启动容器:
docker run -d -p 9010:9010 <my container>Dockerfile还具有:
EXPOSE 9010由Dockerfile CMD启动的Java进程具有以下相关参数:
"-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端口:端口),并以相同的方式在防火墙中打开。
我正在传递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连接host:port对。
VisualVM和JConsole都告诉我他们无法连接到远程JMX服务。在这两种情况下,我都拒绝了安全连接,然后他们会说:
Cannot connect to 108.357.213.99:9010 using
service:jmx:rmi:////jndi/rmi://108.357.213.99:9010/jmxrmi无奈之下,我添加了一条防火墙规则,在所有端口0-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是短暂的--它是由Google Compute Engine在我创建实例时分配的,所以我不能将它与其他Java参数一起硬连接到Dockerfile中。
我是否必须获得静态IP地址才能正常工作?
发布于 2017-08-02 16:52:38
一种可能的解决方案是ssh到您的GCE机器和端口转发端口9010。可以从本地控制台使用以下命令完成此操作:
gcloud compute ssh name-of-your-gce-engine -- -L 9010:localhost:9010然后在jconsole或jvisualvm中连接到localhost:9010。在这里使用localhost意味着jconsole/jvisualvm将连接到您的本地计算机,这个连接由ssh隧道传输到您的GCE引擎,然后连接到-L参数中定义的主机和端口,该参数是localhost:9010,但是从GCE- engine的角度来看。这意味着你将在你的应用程序中结束。
在启动程序之前,您仍然需要设置rmi服务器名称,但您必须使用
-Djava.rmi.server.hostname='localhost'因此RMI将告诉jconsole/jvisualvm使用本地主机,然后这将解析到本地隧道端点。当然,你仍然需要这些:
"-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", \https://stackoverflow.com/questions/45448881
复制相似问题