2016-01-31 23 views
25

Właściwie chciałem rozwiązania działającego na kontenery JEE, specjalnie dla Glassfish, ale po tym, jak spróbowałem wielu kombinacji ustawień i nie udało mi się, zmniejszyłem konfigurację do najprostszy możliwy przypadek.Jak dołączyć VisualVM do prostego procesu Java działającego w kontenerze Docker?

Oto mój demon Hello World uruchomiony w kontenerze Docker. Chcę do niego dołączyć jconsole lub VisulaVM. Wszystko jest na tej samej maszynie.

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

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

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

Pytania:

  • co JVM parametry powinny być dodawane do CMD z linii poleceń?
  • jakie porty powinny być wyeksponowane i opublikowane?
  • jaki tryb sieci powinien używać kontener Docker?

Nie pokazuję tutaj moich nieudanych prób, aby prawidłowe odpowiedzi nie były stronnicze. To powinien być dość powszechny problem, ale nie mogłem znaleźć działającego rozwiązania.

Aktualizacja. Pracował rozwiązanie

Ten Dockerfile działa

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 

w połączeniu z poleceniem run doker

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

VisualVM łączy poprzez prawy przycisk myszy szczeblu lokalnym> Dodaj JMX Connection, a następnie wprowadzając localhost:9010, lub poprzez dodanie zdalnego hosta.

JConsole łączy się poprzez wybór zdalnego procesu z localhost:9010.

Podczas definiowania połączenia jako zdalnego można użyć dowolnego interfejsu wymienionego pod numerem ifconfig. Na przykład działa interfejs docker0 z adresem 172.17.0.1. Adres kontenera 172.17.0.2 również działa.

Odpowiedz

23

Na początku należy uruchomić ci aplikacji z tych JVM params:

-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 

Następnie należy odsłonić port dokowanym:

EXPOSE 9010 

określić także wiązanie z polecenia uruchomienia doker port:

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

Po tym można połączyć się z Jconsole do lokalnego portu 9010 i zarządzać aplikacją w biegu w Docker.

+2

Nope .. VisualVM: 'Nie można połączyć się z localhost: 9010 przy użyciu usługi: JMX: RMI: /// JNDI/RMI: // localhost: 9010/jmxrmi'. Jconsole: 'Połączenie nie powiodło się: błąd podczas ustanawiania połączenia JRMP; Zagnieżdżony wyjątek to: java.net.SocketException: zerowanie połączenia ' – nolexa

+0

dlaczego dwa razy wystawiasz ten sam port? – nolexa

+0

Połącz się z localhostem, do interfejsu sieciowego. – eg04lt3r

4

Poszłam za an other SO response to a similar question i działała.

zacząłem proces Java wewnątrz pojemnika dodając te 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 

i zaczął pojemnik Docker określającą -e HOST_HOSTNAME=$HOSTNAME -p <port> dowodzić docker run.

Następnie mogłem uzyskać dostęp do tej zdalnej aplikacji Java z mojego lokalnego JVisualVm przez dodanie zdalnego połączenia JMX ("Plik"> "Dodaj połączenie JMX ...") i określenie <dockerhostname>:<port> w "Połączenie" wprowadzania i sprawdzania "Nie wymaga połączenia SSL".

0

Jak odpowiedział Anthony. Musiałem użyć opcji java -Djava.rmi.server.hostname na moim komputerze z systemem Windows.

Tylko pamiętaj, aby nie używać CMD w formacie JSON w pliku Docker, ponieważ nie obsługuje to rozszerzenia powłoki.

Dockerfile przykład:

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