问题
Actually I wanted a solution working for JEE containers, specifically for Glassfish, but after I tried many combinations of settings and did not succeed, I reduced the setup to the simplest possible case.
Here is my Hello World daemon started in a Docker container. I want to attach jconsole
or VisulaVM
to it. Everything is on the same 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"]
Building: docker build -t hello-world-daemon .
Running: docker run -it --rm --name hwd hello-world-daemon
Questions:
- what JVM parameters should be added to
CMD
command line? - what ports should be exposed and published?
- what network mode should Docker container be using?
I do not show my failed attempts here so that correct answers will not be biased. This should be a pretty common problem, yet I could not find a working solution.
Update. Worked solution
This Dockerfile works
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 combination with the docker run command
docker run -it --rm --name hwd -p 9010:9010 hello-world-daemon
VisualVM
connects via right click Local->Add JMX Connection, and then entering localhost:9010
, or through adding a remote host.
JConsole
connects via selecting a Remote process with localhost:9010
.
When defining the connection as remote, any interface listed by ifconfig
can be used. For instance, docker0
interface with address 172.17.0.1
works. The container's address 172.17.0.2
works too.
回答1:
At first you should run you application with these 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
Then you should expose port for docker:
EXPOSE 9010
Also specify port binding with docker run command:
docker run -p 9010:9010 -it --rm --name hwd hello-world-daemon
After that you can connect with Jconsole to local 9010 port and manage application run in Docker.
回答2:
I followed an other SO response to a similar question and it worked.
I started my Java process inside the container by adding those JVM params:
-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
and started the Docker container specifying -e HOST_HOSTNAME=$HOSTNAME -p <port>
to the docker run
command.
Then I've been able to access to this remote Java app from my local JVisualVm by adding a remote JMX connection ("File" > "Add a JMX Connection...") and specifying <dockerhostname>:<port>
in the "Connection" input, and checking "Do not require SSL connection".
回答3:
As answered by Anthony.
I had to use the -Djava.rmi.server.hostname
java option on my Windows machine.
Just be sure not to use the CMD in JSON format in your Dockerfile as this doesn't support shell expansion.
Dockerfile example:
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
来源:https://stackoverflow.com/questions/35108868/how-do-i-attach-visualvm-to-a-simple-java-process-running-in-a-docker-container