En fait, je voulais une solution fonctionnant pour les conteneurs JEE, en particulier pour Glassfish, mais après avoir essayé de nombreuses combinaisons de paramètres et sans succès, j'ai réduit la configuration au cas le plus simple possible.
Voici mon démon Hello World démarré dans un conteneur Docker. Je veux y attacher jconsole
ou VisulaVM
. Tout est sur la même machine.
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"]
Bâtiment: docker build -t hello-world-daemon .
Fonctionnement: docker run -it --rm --name hwd hello-world-daemon
Des questions:
CMD
?Je ne montre pas mes tentatives infructueuses ici afin que les bonnes réponses ne soient pas biaisées. Cela devrait être un problème assez courant, mais je n'ai pas pu trouver de solution de travail.
Mise à jour. Solution travaillée
Ce Dockerfile fonctionne
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
en combinaison avec la commande docker run
docker run -it --rm --name hwd -p 9010:9010 hello-world-daemon
VisualVM
se connecte via un clic droit Local-> Ajouter une connexion JMX , puis en saisissant localhost:9010
, ou en ajoutant un hôte distant.
JConsole
se connecte en sélectionnant un processus distant avec localhost:9010
.
Lorsque vous définissez la connexion comme distante, n'importe quelle interface répertoriée par ifconfig
peut être utilisée. Par exemple, docker0
interface avec l'adresse 172.17.0.1
travaux. L'adresse du conteneur 172.17.0.2
fonctionne aussi.
Au début, vous devez exécuter votre application avec ces paramètres 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
Ensuite, vous devez exposer le port pour docker:
EXPOSE 9010
Spécifiez également la liaison de port avec la commande docker run:
docker run -p 9010:9010 -it --rm --name hwd hello-world-daemon
Après cela, vous pouvez vous connecter avec Jconsole au port 9010 local et gérer l'exécution des applications dans Docker.
J'ai suivi ne autre réponse SO à une question similaire et cela a fonctionné.
J'ai commencé mon processus Java à l'intérieur du conteneur en ajoutant ces paramètres 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
et a démarré le conteneur Docker en spécifiant -e Host_HOSTNAME=$HOSTNAME -p <port>
au docker run
commande.
Ensuite, j'ai pu accéder à cette application Java Java de mon JVisualVm local en ajoutant une connexion JMX distante ("Fichier"> "Ajouter une connexion JMX ...")) et en spécifiant <dockerhostname>:<port>
dans l'entrée "Connexion" et en cochant "Ne nécessite pas de connexion SSL".
Comme répondu par Anthony . J'ai dû utiliser le -Djava.rmi.server.hostname
Java sur ma machine Windows.
Assurez-vous simplement de ne pas utiliser le CMD au format JSON dans votre Dockerfile car cela ne prend pas en charge l'expansion de Shell.
Exemple de Dockerfile:
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