VisualGC to a remote JVM running in docker - java

I understand from Oracle's documentation of VisualGC (and everything I found from SO on the subject, this question for instance) that a jstatd server is required when using VisualGC to connect to a remote JVM.
My JVM is running in a docker container, and the only process running in that container is the JVM, I hope to keep it this way as is the best practice for containers.
Is there any way I can use VisualGC (my client is the VisualGC plugin for VisualVM) with a JVM running in docker?

Here is how to do this easily.
Launch ejstatd in your remote host this way (executing from the ejstatd folder): mvn exec:java -Dexec.args="-pr 1099 -ph 1100 -pv 1101"
Open those 3 ports on your remote host and make them available to your local machine: 1099, 1100 and 1101
Identify the <lvmid> of your running Java application using jps from your local machine (replace <remotehost> with your remote host name): jps -m -l rmi://<remotehost>:1099
You can now use visualgc by launching it this way (replacing <lvmid> and <remotehost> with the correct values): visualgc <lvmid>#<remotehost>:1099
Disclaimer: I'm the author of the open source ejstatd tool

Just use jstatd in docker together with your application. I don't think it violates docker's best practices.

The VisualGC and friends connect over JMX, usually via port 1099. So if you set up your Docker container to passthrough TCP requests from port 1099 inside the docker container to an accessible port outside, then you should be able to connect to that remotely.

Related

Install Jenkins manually on docker image

I'm trying to install/run jenkins manually without pulling the Jenkins image from the docker-hub
for this exercise I have used the ubuntu image container and I did the following:
Install jdk-11 on the container
Set up the JAVA_HOME env variable
Install jenkins with apt-get
Run jenkins with the command service jenkins start
then status output is the following
root#42024442b87b:/# service jenkins status
Correct java version found
Jenkins Automation Server is running with the pid 89
Now I don't now how to access the jenkins server running in the container from my host.
thanks in advance
Docker containers are not reachable using the network from the host system by default. You need to expose a container's host, meaning that the port will be opened on the host machine and all traffic forwarded to the container.
Running docker with -p 8080:8080 forwards 8080. Take a look at the syntax here.
You can also specify which port on the host machine is supposed to be mapped to a container's port with something like -p 1234:8080.
You can also use the EXPOSE keyword in your Dockerfile.

Cannot connect from external PC to Java application running in Docker container - Linux

I have a Java server application running in Docker Container. The container runs in a Linux server (Ubuntu 18.04 LTS), with a static IP address. Another Java application, running in a PC, has to connect to the Java server application.
The server app listens for TCP connection requests and the PC App can open a TCP connection, knowing port and static IP address of Server App.
Let me say that the app server listens on port 5000 for TCP connection requests; then, when a TCP connection arrives from external, the TCP server releases a connection assigning a port in the range 5000-20000. So first question is if this range 5000-20000 to be exposed?
Before, the Java server application runned in a linux server, without container, and it worked.
Now, with the Server App inside the Docker container, the connection is refused; I guess that there is a problem of ports.
The Java application is configured by a dockerfile like that:
FROM openjdk:8-oraclelinux8
WORKDIR /mydir
# VOLUME . /
COPY ["./My_name_Java_app.jar", "./My_name_Java_app.properties", "./"]
EXPOSE 80
EXPOSE 8080
EXPOSE 5000-20000
ENTRYPOINT ["/bin/java", "-Djava.awt.headless=true", "-jar", "My_name_Java_app.jar"]
I have read that I have to publish the ports on Docker run command, but when I run the container by:
docker run -d --name my_container -p 5000-20000:5000-20000/tcp -p 80:80 -p 8080:8080 -v /root/my_app/volume:/mydir my_image
I get the following error (in Linux terminal - note that the final full stop is exactly whay I get):
linux docker: Error response from daemon xxxxxxxxx: driver failed programming external connectivity on endpoint Error starting userland proxy:.
So finally my target is that the PC app can connect to Server app using the port 5000 and opening a connection in the range of port (5001-20000).
I also exposed ports 80 and 8080 because the Server App must perform some http requests to a website, so I suppose that I have to expose the ports 80 and 8080; other question is if do I have also to expose and publish 80 and 8080 by -p option?
By the way, if I delete (see below) the -p option with 80 and 8080, I get always the same error.
docker run -d --name my_container -p 5000-20000:5000-20000/tcp -v /root/my_app/volume:/mydir my_image
Moreover, if I eliminate at all the -p option, the container starts without errors.
SOLVED:
AT the end of the story nothing was really wrong, simply I had to expose (inside the dockerfile) and publish with -p option (in docker run command) only the only port that I really need (that is the 5000), and not the big range of ports I considered at beginning.

Mac host doesn't like Docker container port forwarding

I am experimenting with Docker for the first time, and am trying to get a Spring Boot web app to run inside a Docker container. I am building the app (which packages up into a self-contained jar) and then adding it to the Docker image (which is what I want).
You can find my SSCCE at this Bootup repo on GitHub, whose README has all the instructions to reproduce what I'm seeing. But basically:
I build the web app into a jar
Run docker build -t bootup . which succeeds
Run docker run -it -p 9200:9200 -d --name bootup bootup and then container seems to start up just fine, as is evidence by the docker ps output below
However, when I point a browser to http://localhost:9200, I get nothing
docker ps output:
CONTAINER ID IMAGE COMMAND CREATED
a8c4ee64a1bc bootup "/bin/sh -c 'java -ja" 2 days ago
STATUS PORTS NAMES
Up 12 seconds 0.0.0.0:9200->9200/tcp bootup
The web app is configured to run on port 9200, not the Java default of 8080. You can see this for yourself by running the app outside of docker (so, just locally on you host machine) by running ./gradlew clean build && java -jar build/libs/bootup.jar.
To my knowledge, there is no Firewall running on my host that would be blocking ports (I am on Mac 10.11.5 and verified that System Preferences >> Security & Privacy >> Firewall is turned off).
Can anyone spot where I'm going awry?
Updates:
I ran a curl, netstat and lsof on the host:
HOST:
curl http://localhost:9200
curl: (52) Empty reply from server
netstat -an | grep 9200
tcp6 0 0 ::1.9200 *.* LISTEN
tcp4 0 0 *.9200 *.* LISTEN
lsof -n -i4TCP:9200 | grep LISTEN
com.docke 2578 myuser 19u IPv4 <someHexNumber> 0t0 TCP *:wap-wsp (LISTEN)
And then docker exec'd into the container and ran another netstat:
CONTAINER:
netstat -an | grep 9200
bash: netstat: command not found
Update w/ photos:
Picture of my browser (Chrome) pointed to http://localhost:9200:
Picture of the source code at http://localhost:9200:
Picture of Chrome Developer Tools inspecting the page at http://localhost:9200:
Picture of the Network tab in Chrome Developer Tools:
What the heck is going on here?!?!? According to the source, the browser should be rendering my Well hello there, from Dockerland! message just fine. According to the actual browser page, it looks like there is a networking error. And according to Chrome Developer Tools, my app is returning all sorts of HTML/CSS/JS content that is not even remotely apart of my app (check out the source code, see for yourself)!!!
The Dockerfile doesn't expose 9200 to the daemon. Add
EXPOSE 9200
to the Dockerfile before ENTRYPOINT
Assuming you are using Docker Toolbox and not the beta ...
There is a 3 step process for exposing a port properly:
use EXPOSE 8080 where 8080 is just a port number in the Dockerfile
use -p 8080:8080 in your docker run command
Make sure that you setup port forwarding in Oracle Virtual Box so that the boot2docker machine is able to receive requests from port 8080.
This applies to both Windows and OSX where Docker Toolbox is being used. Linux doesn't use Oracle VirtualBox to run docker so those hosts do not need to do the third point
I ran your repo as-is on Docker 1.12 on OSX.
If you look carefully at your container startup:
2016-08-29 20:52:31.028 INFO 5 --- [ main] o.eclipse.jetty.server.ServerConnector : Started ServerConnector#47949d1a{HTTP/1.1}{0.0.0.0:8080}
2016-08-29 20:52:31.033 INFO 5 --- [ main] .s.b.c.e.j.JettyEmbeddedServletContainer : Jetty started on port(s) 8080 (http/1.1)
Although application.yml and Dockerfile both contain 9200, the application is starting on 8080
Going to add another answer here because I saw something related to the Github Repo that you posted:
So the repo is a spring boot repo with an application.yml file.
Your Dockerfile looks like this:
FROM openjdk:8
RUN mkdir /opt/bootup
ADD build/libs/bootup.jar /opt/bootup
WORKDIR /opt/bootup
EXPOSE 9200
ENTRYPOINT java -jar bootup.jar
Which is adding the built jar to the image. If my understanding is correct, the jar does not include application.yml because:
It is not part of the build (gradle would package the src/main only). It is sitting on the project root folder
It is not explicitly added to Docker
So therefore one can assume that your app is actually running on 8080 (the default) at the moment?
A couple of options that one could try:
Try exposing 8080 instead of 9200 (or expose both) and see if that makes a difference?
The entrypoint command can append the port --server.port=9200
The application.yml file should be added to the image (you might need to add an argument to reference it properly) [ADD application.yml /opt/bootup, after first ADD command]
Include the application.yml file in src/main/resources so that spring boot can pick it up automatically.
References
Spring Boot reference documentation on the order of loading for external configuration
Good News! (for MacOSx 10.15.7)
I found the same issue as you, and I was able to solve it by directly opening VirutalBox connection
Go here first:
changed to bridged then logged into the virtual machine within VirtualBox
And found the actual machine's adapter labeled:
eth0
after I noted the setting it was originally NAT so I changed to bridged and then
I was able to use its address vs. localhost.
After I used the public address I used:
curl -i [bridged_ip_address_here]:9200
it then worked flawlessly.
However I also noticed some firewalls and accessibility options that needed permission as well.
I pray this helps you.

Jconsole Remote Executable Jar File

All,
I have a remote server that I recently enabled VNC for using vnc4server and Chicken for mac as the client.
The purpose for doing so was to enable running Java's Jconsole to monitor an executable jar file that is running my server logic.
However, after logging into my server using VNC, I keep getting an error when I try to use Jconsole on vnc.
It states connection failed do you want to try again. Now I am logged in as the same user that started the process.
Is there something I am missing when using jconsole in VNC? Also can I monitor my executable jar file remotely using Jconsole on my local machine?
These are the options I am including to run the jar file: java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9005 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.remote.ssl=false -Djava.rmi.server.hostname=ipaddress -jar path
Thanks
These JVM options fixed things. Fix found here: You need to pass to the VM: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false
https://forums.oracle.com/thread/1177644
This does not seem like an VNC issue- either the ports are not open, they are being blocked b a firewall, or there is some kind of permission/authentication issue with the app itself related to monitoring it.
In order to eliminate VNC as the cause (and use localhost in a local connection on jconsole), do "ssh -X REMOTHOST -n jconsole" and see. This will also eliminate the overhead of running the full X server and VNC.
Also on linux you can find out what process holds a port open by doing:
netstat -ap | grep PORT_NUMBER on the remote host you want to run on.
Colin

JVM remote profiling with JVisualVM

I am trying to profile my jvm applications on a remote host.
I am using Jvisualvm
I setup jstatd as recomended in this (link removed, leads to phishing website).
I am able to "telnet remotehost 1099" successfully. All the tcp/ip ports are firewall open on the remote.
I added my remote host in jvisualvm. Also, made sure the jstatd port is the 1099 with a refresh of 3 secs.
I started my application with
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8011
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
But, my jvm applications dont show up in my jvisualvm. Is there anything else I need to configure or check ?
jvisualvm 1.3.5
local: Mac OSX Oracle jdk 1.6.37
remote: centos 6 oracle jdk 1.6.24
1) You should start your application with JMX enabled
Example for remote connection
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9990
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
2) You should have JMX classes to be able to do something with them. I suppose you are aware of this
You need to start jstatd on the remote machine. For this purpose create a jstatd.all.policy file in the home directory of your remote machine and add the following lines:
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
Then on the command line of your remote machine you will type
jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname={Your IP address} '
Once jstatd service start on the remote machine you basically add the remote connection IP address connection on the jvisualVM UI using add remote host.
The Oracle documents for JvisualVM can be referred at https://docs.oracle.com/javase/8/docs/technotes/guides/visualvm/applications_remote.html but it is really confusing to understand jstatd steps.

Categories