2016-02-17 45 views
5

Quando eseguo il contenitore Docker direttamente sul mio host, è possibile connettersi ad esso senza problemi.Come connettersi con JMX dall'host al contenitore Docker nella macchina Docker?

Il mio host ha la rete 192.168.1.0/24 e l'indirizzo IP dell'host è 192.168.1.20. Il mio contenitore Docker ha l'indirizzo IP 172.17.0.2. Quando mi collego a 172.17.0.2:1099 da jconsole funziona.

Quando si inserisce questo servizio nella macchina Docker, non è possibile connettersi ad esso.

La mia macchina Docker ha IP 192.168.99.100 e il contenitore al suo interno ha l'indirizzo IP 172.17.0.2 ma quando uso jconsole per connettersi a 192.168.99.100:1099 non funziona.

di ripeterlo:

192.168.1.20 --- 172.17.0.2:1099 funziona

192.168.1.20 --- (192.168.99.100 --- 172.17.0.2:1099) e la connessione a 192.168.99.100:1099 dal mio host non funziona.

Vale la pena affermare che è possibile accedere ai servizi containerizzati nella macchina Docker tramite l'indirizzo IP esterno della macchina Docker, ad es. questo funzionerà:

192.168.99.100 --- (192.168.99.100:8080 --- 172.17.0.2:8080)

Ma quando lo uso JMX semplicemente non funziona.

È un servizio Tomcat. Ho questo negli script che inizia esempio Tomcat:

CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n \ 
-Dcom.sun.management.jmxremote.port=1099 \ 
-Dcom.sun.management.jmxremote.rmi.port=1099 \ 
-Dcom.sun.management.jmxremote.authenticate=false \ 
-Dcom.sun.management.jmxremote.ssl=false \ 
-Djava.rmi.server.hostname=IP address of Docker container 
+0

È avviato dalla libreria docker-java ... non è così importante, ma quando faccio "docker-machine ssh" e in esso "docker ps -a" posso vedere che il mio contenitore ha questo port binding/esposizioni: ad6be9184855 company/tomcat: 8.0.30 0.0.0.0:1099->1099/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8009->8009/tcp, 0.0.0.0:8080->8080/tcp – stewenson

risposta

4

Credo che il problema è probabilmente il valore della proprietà java.rmi.server.hostname. Questo deve essere il nome host o l'indirizzo IP che deve essere utilizzato dal client JMX per connettersi alla JVM. Questo è il primo caso in cui ci si connette direttamente al contenitore utilizzando 172.17.0.2:1099, questa impostazione deve essere impostata su 172.17.0.2. Nel secondo caso in cui si accede al contenitore tramite la macchina mobile in 192.168.99.100:1099, l'impostazione deve essere impostata su 192.168.99.100.

Durante la mia ricerca per una domanda molto simile (che è stata cancellata nel frattempo) mi sono imbattuto in un post di blog (che è stato cancellato nel frattempo). Anche se è piuttosto vecchio mi ha dato un'idea di come funziona la connettività JMX:

  1. Il Registro di JMX in ascolto sulla porta <com.sun.management.jmxremote.port> del contenitore
  2. Se si collega al Registro di sistema con JConsole, il Registro di sistema fornisce l'URL del servizio JMX al cliente.
  3. Questo URL viene utilizzato dal client per ottenere gli oggetti di JMX

l'URL del servizio assomiglia a questo service:jmx:rmi:///jndi/rmi://<java.rmi.server.hostname>:<com.sun.management.jmxremote.rmi.port>/jmxrmi. Questo è nel tuo caso service:jmx:rmi:///jndi/rmi://172.17.0.2:1099/jmxrmi. Poiché questo indirizzo è raggiungibile solo dalla macchina docker, la connessione da remoto non è possibile. Nella mia domanda copro lo stesso problema per quanto riguarda la porta RMI ...

Non sembra esserci una soluzione pronta per questo problema. Tuttavia, è possibile fornire sia la porta JMX che il nome host esterno (o IP) all'avvio del contenitore come variabili di ambiente, come suggerito here.Questi potrebbero poi essere utilizzati nella configurazione JMX:

docker run -p 1099:1099 \ 
    -e "JMX_HOST=192.168.99.100" \ 
    -e "JMX_PORT=1099" \ 
    company/tomcat:8.0.30 

e

CATALINA_OPTS="... \ 
    -Dcom.sun.management.jmxremote=true \ 
    -Dcom.sun.management.jmxremote.port=$JMX_PORT \ 
    -Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT \ 
    -Dcom.sun.management.jmxremote.authenticate=false \ 
    -Dcom.sun.management.jmxremote.ssl=false \ 
    -Djava.rmi.server.hostname=$JMX_HOST" 
Non

molto bello, ma dovrebbe funzionare ...

+0

sì, questo approccio funziona e ho capito esattamente come te, ho appena dimenticato di scrivere una risposta :) Grazie. – stewenson

+1

BTW: Funzionava anche per me (Java 7, Tomcat 7), ma dovevo aggiungere '-Dcom.sun.management.jmxremote =' nel 'CATALINA_OPTS' per farlo funzionare. Solo avere le singole proprietà non era sufficiente. – nwinkler

+1

@nwinkler ovviamente hai ragione. Ho aggiornato la mia risposta per includere la proprietà di sistema mancante 'com.sun.management.jmxremote' – dpr

1

Se qualcuno ha problemi con esso. Ho iniziato il processo di Java nel contenitore finestra mobile con i seguenti parametri:

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=9876 
-Dcom.sun.management.jmxremote.rmi.port=9876 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Djava.rmi.server.hostname=<name of the docker container> 

La parte importante è quello di impostare il nome del contenitore finestra mobile. ESPORRE la porta nel contenitore 9876. Ho anche configurato una connessione ssh e inoltrato 9876 all'host locale.

Il seguente va al tuo config SSH:

LocalForward 127.0.0.1:9876 127.0.0.1:9876 

Anche io ho setup/etc/hosts sulla macchina locale

127.0.0.1 <name of the docker container> 

Ora collegare la console a "nome del contenitore di finestra mobile"