Connect to docker host from container - java

I have a container running a Java web service with jetty. I would like to connect to the Docker host process, ie tcp://dockerhost:2376, to build and publish images to the local registry on demand.
I can connect to the host from the container but for some annoying reason, I can't seem to connect to the docker host process... Could this be down to some internal firewall rules? The strange thing is I can connect to other docker services, ie on other machines, but NOT the one running the container.
EDIT - just to be clear
my docker daemon runs on 192.168.22.150, port 2376
I can do curl -X GET http://192.168.22.150:2376 from any machine (VM) on that net and I get the usual message
I can do curl -X GET http://192.168.22.150 from my docker container and that works fine (I have a process listening on 80)
I can do curl -X GET http://192.168.22.XXX:2376 on another machine running a docker daemon from my container
If I do curl -X GET http://192.168.22.150:2376 from my container, it hangs
Feels like it's a firewall issue?

I was down to a firewall issue... the IP address of the container wasn't allowed through for the 2376 port, I added it and it worked. Sorry for the trouble and thanks for the help.

Related

How connect to db when running Dockerfile?

I have a spring boot app that connects fine to my PostgreSQL server running locally in Desktop Docker.
Than I wrote a simple Dockerfile to run my app in container. Container starts but can't connect to my db server with error message:
Connection to localhost:5432 refused.
Why and how to fix this?
To access localhost from inside a docker container you can use the IP of your computer. Localhost or 127.0.0.0 donsen't work.
Use docker compose to connect the two docker containers.
https://docs.docker.com/compose/
On this page you can see an example on how to connect to containers using docker compose:
https://dev.to/mozartted/docker-networking--how-to-connect-multiple-containers-7fl
If they are on seperate Docker networks, use:
docker.host.internal
This connects to the Docker host machine. So if your PostgreSQL instance is exposed on 5432, docker.host.internal will route to that instance through the host from other containers.
Alternatively, set them up in the same network using docker compose or by creating a network and attaching both containers to them. They can then communicate with container name.
https://docs.docker.com/engine/reference/commandline/network_create/

Docker container shows no ports, can find IP but need both to connect to Java application

So I'm fairly new to Docker, only been using it for a day or two and recently pulled this https://hub.docker.com/r/ncbi/blast
Which is an image that has a set of commands to get information from a database. I have the Desktop version of Docker for windows and manage to get the image to pop up just fine. It shows up in my images,
I run the image via the desktop app. Give it the name "Test", see it's running using the "docker ps". I get it's IP just fine but see there are no ports.
I've heard that it might be connected to my local host which is why no ports show up but still where would I go to find my host port then and or just change the port? A java program/application I'm making is supposed to connect to this using IP and Port but I can't find the port. Any help would be appreciated, thank you again.
You have to include -p flag in your docker run command to expose ports for your application.
-d options runs docker container in the background.
For e.g. In Docker Run Command
docker run -p 8080:8080 -d ncbi/blast:latest

Cannot connect jmx to java app running in docker on remote host

Assuming I have a server in my local network with ip 192.168.100.10.
There is docker container running in it with java application.
Now i want to connect to this java application with VisualVM from my computer which has ip address 192.168.100.20. I thought I had everything configured properly but it still does not work.
I have passed these JVM options:
-Dcom.sun.management.jmxremote"
-Dcom.sun.management.jmxremote.port=9010"
-Dcom.sun.management.jmxremote.authenticate=false"
-Dcom.sun.management.jmxremote.ssl=false"
-Dcom.sun.management.jmxremote.local.only=false"
-Dcom.sun.management.jmxremote.rmi.port=9010"
-Djava.rmi.server.hostname=192.168.100.10"
Then I have exposed port 9010 in Dockerfile:
EXPOSE 9010
Then added this port to docker-compose:
ports:
- "9010:9010"
I am trying to connect to remote host with JConsole or VisualVM from my local machine. In "Remote Process" input in JConsole I put "192.168.100.10:9010" but connection fails with error:
"The connection to 192.168.100.10:9010 did not succeed. Would you like to try again?"
What am I doing wrong?
The solution above is sufficient and working. I've been using env variable to set port number which was not working properly.

Attaching VisualVM or JConsole to Java in Docker on GCE

I am trying to get some CPU sampling working on a remote Java-in-Docker process.
I've already looked at the related questions here, and tried everything, to no avail, so I'm posting my setup here.
I have a Java process (openjdk-8) running in a Docker container on a Google Compute Engine (GCE) instance. The GCE instance and container are both running Debian-9. I want to attach VisualVM or JConsole to my Java process.
I am able to run my docker container locally and connect with both visualvm and jconsole using localhost:9010.
I start the container in the VM startup script with:
docker run -d -p 9010:9010 <my container>
The Dockerfile also has:
EXPOSE 9010
The Java process, started by the Dockerfile CMD, has the following relevant args:
"-Dcom.sun.management.jmxremote", \
"-Dcom.sun.management.jmxremote.port=9010", \
"-Dcom.sun.management.jmxremote.rmi.port=9010", \
"-Dcom.sun.management.jmxremote.local.only=false", \
"-Dcom.sun.management.jmxremote.authenticate=false", \
"-Dcom.sun.management.jmxremote.ssl=false", \
I have opened up port 9010 in my gcloud firewall using:
gcloud compute firewall-rules create jmx-port --allow=tcp:9010,udp:9010
I have verified with netcat that the port is open and I can make a TCP connection to it.
I have other ports open from the same Docker container, with clients connecting successfully to those ports. They were exposed and mapped to the host ports the same way (-p port:port) and opened in the firewall the same way.
I am passing the external IP address of the GCE instance. For instance, if I do:
gcloud compute instances list
and it tells me:
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
my-server-b23j us-central1-d n1-standard-1 10.240.0.2 108.357.213.99 RUNNING
Then I will use the argument:
108.357.213.99:9010
as the remote jmx connection host:port pair.
VisualVM and JConsole both tell me they can't connect to the remote JMX service. In both cases, I decline the secure connection, and then they say:
Cannot connect to 108.357.213.99:9010 using
service:jmx:rmi:////jndi/rmi://108.357.213.99:9010/jmxrmi
In desperation, I added a firewall rule that enables TCP/UDP connections on all ports 0-65535, but it did not make a difference -- they still could not connect.
I've read that JMX-RMI opens up anonymous ports, and that you can (at least partly?) disable this behavior by specifying both:
"-Dcom.sun.management.jmxremote.port=9010", \
"-Dcom.sun.management.jmxremote.rmi.port=9010", \
However, it doesn't do the trick in my case.
I've read here that you need to specify the rmi server hostname:
-Djava.rmi.server.hostname='192.168.99.100'
but my server IP is ephemeral -- it is assigned by Google Compute Engine when I create the instance, and so I can't hardwire it into the Dockerfile with the rest of the Java args.
Am I going to have to get a static IP address to make this work?
One possible solution would be to ssh into your GCE box and port-forward port 9010. This can be done from the local console with:
gcloud compute ssh name-of-your-gce-engine -- -L 9010:localhost:9010
Then in jconsole or jvisualvm you connect to localhost:9010. Using localhost here means that jconsole/jvisualvm will connect to your local machine, this connect is tunneled by ssh into your GCE engine and there to the host and port defined in the -L argument, which is localhost:9010, but from the GCE-engine's view. Meaning that you will end up at your application.
You still have to set the rmi server name before starting your program, but you must use
-Djava.rmi.server.hostname='localhost'
so that RMI will tell jconsole/jvisualvm to use localhost and this will then resolve to your local tunneled endpoint. And of course you still need these:
"-Dcom.sun.management.jmxremote", \
"-Dcom.sun.management.jmxremote.port=9010", \
"-Dcom.sun.management.jmxremote.rmi.port=9010", \
"-Dcom.sun.management.jmxremote.local.only=false", \
"-Dcom.sun.management.jmxremote.authenticate=false", \
"-Dcom.sun.management.jmxremote.ssl=false", \

Unable to connect to remote JMX using VisualVM but OK with JConsole

I'm attempting to connect to a remote JMX service using VisualVM 1.3.8 with JRE 1.8.0. Making exactly the same connection with JConsole works perfectly, however the attempt to use the same parameters with VVM just hangs at the 'Adding services' stage. I've looked in the VVM log but there is literally nothing logged.
I also read here at the VVM remote JMX doc:
Note: To retrieve and display information on applications running on the remote host, the jstatd utility needs to be running on the remote host.
That puzzles me since I can make the remote JMX connection using JConsole and as far as I can tell, jstatd is not running on the remote.
Does anyone know if jstatd a requirement only for VVM as a remote JMX client? As the JMX connection can be made with JConsole between the same client and server endpoints, then there's no problem with network/firewall etc.
Other than that I'm really puzzled where else to look for clues?
I had the same trouble when I switched from Java 7 to 8, while using SOCKS where I was updating proxy settings through VisualVM -> Tools -> Plugins -> Settings -> Proxy Settings. However, I have been successful with the following:
Run your JVM with the following options:
-Dcom.sun.management.jmxremote.port=<JMX_PORT>
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
Note that you could obviously do something more secure, both w.r.t SSL and authentication.
Setup a SOCKS proxy from your localhost to the remote server:
ssh -D<SOCKS_PORT> -vvv -N <REMOTE_HOST>
Run either of these commands on your localhost:
jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=<SOCKS_PORT> service:jmx:rmi:///jndi/rmi://<REMOTE_HOST:JMX_PORT>/jmxrmi
jvisualvm -J-DsocksProxyHost=localhost -J-DsocksProxyPort=<SOCKS_PORT> --openjmx <REMOTE_HOST>

Categories