2016-01-31 3 views
25

Eigentlich wollte ich eine Lösung für JEE-Container, speziell für Glassfish, aber nachdem ich viele Kombinationen von Einstellungen ausprobiert und nicht erfolgreich war, reduzierte ich das Setup auf der einfachste mögliche Fall.Wie verbinde ich VisualVM mit einem einfachen Java-Prozess in einem Docker Container

Hier ist mein Hello World-Daemon in einem Docker-Container gestartet. Ich möchte jconsole oder VisulaVM daran anhängen. Alles ist auf derselben Maschine.

public class Main { 
    public static void main(String[] args) { 
    while (true) { 
     try { 
     Thread.sleep(3000); 
     System.out.println("Hello, World"); 
     } catch (InterruptedException e) { 
     break; 
     } 
    } 
    } 
} 

Dockerfile

FROM java:8 
COPY . /usr/src/myapp 
WORKDIR /usr/src/myapp 
RUN javac Main.java 
CMD ["java", "Main"] 

Gebäude: docker build -t hello-world-daemon .

Running: docker run -it --rm --name hwd hello-world-daemon

Fragen:

  • welche JVM Parameter sollten auf 01.231.556 hinzugefügt werdenBefehlszeile?
  • Welche Ports sollten veröffentlicht und veröffentlicht werden?
  • Welchen Netzwerkmodus sollte der Docker-Container verwenden?

Ich zeige meine gescheiterten Versuche hier nicht, so dass richtige Antworten nicht voreingenommen sind. Dies sollte ein ziemlich häufiges Problem sein, aber ich konnte keine funktionierende Lösung finden.

Aktualisierung. Arbeitete Lösung

Diese Dockerfile arbeitet

FROM java:8 
COPY . /usr/src/myapp 
WORKDIR /usr/src/myapp 
RUN javac Main.java 
CMD ["java", \ 
"-Dcom.sun.management.jmxremote", \ 
"-Dcom.sun.management.jmxremote.port=9010", \ 
"-Dcom.sun.management.jmxremote.local.only=false", \ 
"-Dcom.sun.management.jmxremote.authenticate=false", \ 
"-Dcom.sun.management.jmxremote.ssl=false", "Main"] 
EXPOSE 9010 

in Kombination mit dem Docker Fahrbefehl

docker run -it --rm --name hwd -p 9010:9010 hello-world-daemon 

VisualVM über rechts verbindet klicken Local-> JMX-Verbindung, hinzufügen und dann localhost:9010 Eingabe, oder durch Hinzufügen eines Remote-Hosts.

JConsole verbindet einen Fern Prozess mit localhost:9010 über die Auswahl.

Bei der Definition der Verbindung als remote kann jede von ifconfig aufgelistete Schnittstelle verwendet werden. Zum Beispiel funktioniert docker0 Schnittstelle mit Adresse 172.17.0.1 funktioniert. Die Adresse des Containers 172.17.0.2 funktioniert auch.

Antwort

23

Zuerst sollten Sie Ihre Anwendung mit dieser JVM params laufen:

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=9010 
-Dcom.sun.management.jmxremote.local.only=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 

Dann sollten Sie Port für Docker aussetzen:

EXPOSE 9010 

auch angeben Port mit Docker Fahrbefehl Bindung:

docker run -p 9010:9010 -it --rm --name hwd hello-world-daemon 

Danach können Sie mit JConsole zu lokal 9010-Port anschließen und verwalten applicati in Docker laufen.

+2

Nope .. VisualVM: 'Es kann keine Verbindung zu localhost: 9010 mit Service: JMX: rmi: /// jndi/rmi: // localhost: 9010/jmxrmi'. Jconsole: 'Verbindung fehlgeschlagen: Fehler während JRMP-Verbindungsaufbau; verschachtelte Ausnahme ist: java.net.SocketException: Connection reset' – nolexa

+0

Warum belichten Sie denselben Port zweimal? – nolexa

+0

Verbinden Sie sich nicht mit localhost mit Ihrer Netzwerkschnittstelle. – eg04lt3r

4

Ich folgte an other SO response to a similar question und es funktionierte.

Ich begann im Innern des Behälters meinen Java-Prozess, indem diese JVM params Zugabe:

-Dcom.sun.management.jmxremote.port=<port> \ 
-Dcom.sun.management.jmxremote.authenticate=false \ 
-Dcom.sun.management.jmxremote.ssl=false \ 
-Dcom.sun.management.jmxremote.rmi.port=<port> \ 
-Djava.rmi.server.hostname=$HOST_HOSTNAME 

und begann -e HOST_HOSTNAME=$HOSTNAME -p <port> zum docker run Befehl Docker Container angeben.

Dann konnte ich von meiner lokalen JVisualVm aus auf diese entfernte Java-Anwendung zugreifen, indem ich eine entfernte JMX-Verbindung hinzufügte ("Datei"> "Eine JMX-Verbindung hinzufügen ...") und <dockerhostname>:<port> in der "Verbindung" spezifizierte Eingabe und Überprüfung "Keine SSL-Verbindung erforderlich".

0

Wie Anthony beantwortet. Ich hatte die -Djava.rmi.server.hostname Java-Option auf meinem Windows-Rechner zu verwenden.

Stellen Sie sicher, dass Sie das CMD nicht im JSON-Format in Ihrer Dockerfile verwenden, da dies die Shell-Erweiterung nicht unterstützt.

Dockerfile Beispiel:

FROM java:8 
COPY . /usr/src/myapp 
WORKDIR /usr/src/myapp 
RUN javac Main.java 
#Do not use CMD in JSON format here because shell expansion doesn't work in JSON format 
#Shell expansion is needed for the ${HOST} variable. 
CMD java -Dcom.sun.management.jmxremote=true \ 
-Dcom.sun.management.jmxremote.rmi.port=9010 \ 
-Dcom.sun.management.jmxremote.port=9010 \ 
-Dcom.sun.management.jmxremote.ssl=false \ 
-Dcom.sun.management.jmxremote.authenticate=false \ 
-Dcom.sun.management.jmxremote.local.only=false \ 
-Djava.rmi.server.hostname=${HOST} \ 
Main 
Verwandte Themen