2016-01-31 32 views
25

In realtà volevo una soluzione funzionante per contenitori JEE, in particolare per Glassfish, ma dopo aver provato molte combinazioni di impostazioni e non ci sono riuscito, ho ridotto la configurazione a il caso più semplice possibileCome si collega VisualVM a un semplice processo Java in esecuzione in un contenitore Docker

Ecco il mio daemon Hello World avviato in un contenitore Docker. Voglio allegare jconsole o VisulaVM ad esso. Tutto è sulla stessa macchina.

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"] 

costruzione: docker build -t hello-world-daemon .

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

Domande:

  • quali parametri JVM dovrebbe essere aggiunto al 01.231.riga di comando?
  • quali porte devono essere esposte e pubblicate?
  • quale modalità di rete deve utilizzare il contenitore Docker?

Non mostro i miei tentativi falliti qui in modo che le risposte corrette non siano di parte. Questo dovrebbe essere un problema abbastanza comune, ma non sono riuscito a trovare una soluzione funzionante.

Aggiornamento . soluzione ha funzionato

Questo Dockerfile funziona

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 combinazione con il comando di marcia finestra mobile

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

VisualVM collega tramite click destro Local-> Aggiungi JMX Connection, e immettendo localhost:9010, o aggiungendo un host remoto.

JConsole si collega tramite selezione di un processo remoto con localhost:9010.

Quando si definisce la connessione come remota, è possibile utilizzare qualsiasi interfaccia elencata da ifconfig. Ad esempio, l'interfaccia docker0 con l'indirizzo 172.17.0.1 funziona. Anche l'indirizzo del contenitore 172.17.0.2 funziona.

risposta

23

In un primo momento si dovrebbe eseguire voi l'applicazione con queste params JVM:

-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 

allora si dovrebbe esporre porta per finestra mobile:

EXPOSE 9010 

specificare anche la porta di legame con il comando di marcia finestra mobile:

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

Successivamente è possibile connettersi con Jconsole alla porta 9010 locale e gestire l'applicazione in esecuzione in Docker.

+2

No .. VisualVM: 'Impossibile connettersi al localhost: 9010 utilizzando il servizio: JMX: rmi: /// jndi/rmi: // localhost: 9010/jmxrmi'. Jconsole: 'Connessione fallita: errore durante la creazione della connessione JRMP; l'eccezione annidata è: java.net.SocketException: Connection reset' – nolexa

+0

perché esponi la stessa porta due volte? – nolexa

+0

Connetti non a localhost, alla tua interfaccia di rete. – eg04lt3r

4

Ho seguito an other SO response to a similar question e ha funzionato.

ho iniziato il mio processo di Java all'interno del contenitore con l'aggiunta di questi params JVM:

-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 

e ha iniziato il contenitore Docker specificando -e HOST_HOSTNAME=$HOSTNAME -p <port> al comando docker run.

Quindi sono stato in grado di accedere a questa app Java remota dal mio JVisualVm locale aggiungendo una connessione JMX remota ("File"> "Aggiungi una connessione JMX ...") e specificando <dockerhostname>:<port> nella "Connessione" input e controllo "Non richiede connessione SSL".

0

Come risposta Anthony. Ho dovuto usare l'opzione java -Djava.rmi.server.hostname sul mio computer Windows.

Assicurati di non utilizzare il CMD in formato JSON nel Dockerfile in quanto non supporta l'espansione della shell.

Dockerfile esempio:

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