Communicating between a windows and linux docker container on the same host - docker

This may seem trivial, but after some trial error I come to the SO community for a little help!
I create a network, call it docker-net.
I have a linux container, let's all it LC1, that has a published port of 6789 (so when created it had the parameter -p 6789:6789) and I make it join docker-net network (--network docker-net)
This works fine, through my host, I can communicate with it no problem.
I switch to the windows containers and check that LC1 is still running. It does! Amazing.
I create a container, let's call it WC1. It also publishes a port of 9000 that maps internally to 80 (-p 9000:80)
The application inside WC1 tries to connect to LC1 using the IP assigned from the network (docker inspect LC1) and I can't communicate.
There's probably a concept that I can't get my head around to.
I understand that the WC1 and LC1 have different gateways and subnets. Could that be the culprit?
Any help to get me to make that work is appreciated !
EDIT:
Here are the commands I ran for the scenario above:
docker network create docker-net
docker run -d -p 6789:6789 --name LC1 --network docker-net LC1
docker inspect LC1
The IP is 172.18.0.2
switch to the windows container
docker run -d -p 9000:80 --name WC1 WC1

In the docker network connect documentation it states that you can assign an IP to a container the same should work with docker run --network name --ip. Then use that IP to access the container.
Specify the IP address a container will use on a given network
You can specify the IP address you want to be assigned to the
container’s interface.
$ docker network connect --ip 10.10.36.122 multi-host-network
container2

I have found these:
a deleted question on serverfault about the same issue. See the cached-by-google version: Connect Windows container to Linux container running on same Docker host [closed]
an article: Run Linux and Windows Containers on Windows 10
and I think that the only way to make the 2 containers communicate is through the host and by exposing ports. For exampple LC1 will use -p [your app port]:8080 and WC1 -p [your app port]:9090.
By saying [your app port] I mean that it is up to you to decide what to use (a tcp/udp listening socket, a REST api...)
As docker evolves maybe there will be a better solution in the near future.

Related

Cannot connect interface to Docker container

I am trying to connect and run a device (LiDAR) through Docker container since it needs Ubuntu 16 while my computer is Ubunutu 20.
I got the device to ping inside the docker container, but it is not recognised when I try to use it.
What I did:
Made Dockerfile with requirements (Added EXPOSE to expose all ports)
Built docker image using:
docker build -t testLidar
I then made a container using
docker run -d -P --name test_Lidar (imagename)
Then
docker exec -t test_Lidar (device_ip) works
I am able to ping my LiDAR IP inside the container, but when I do ip a I cannot see the interfaces connected to my machine.
Been stuck on this for 3 days, any suggestions?
Note: I have done the exact same steps but on an Ubuntu 16 machine. The only change was the docker run command had --net host instead of -P tag and my device worked perfectly. I feel like this is the root of my problem.
Use --net host flag with docker run to attach the container to your host's networking stack and make it available in for other hosts in your network.
When you use --net host, you actually attach the container to your host's networking stack. By default, containers are attached to the default network of type bridge and can communicate with each other. You can then reach them only from your host using its ip addresses typically in subnet 172.17.0.0/16.
Using -P actually binds exposed ports from a container with randomly selected free ports on your host. It should be used for exposing network services (eg. web server with port 80), but not for ICMP ping.

Why is it possible to connect to the redis docker container without port forwarding?

When I run: docker run --rm -it redis, The container receives ip: 172.18.0.2. Then from the host I connect to the container with the following command: redis-cli -h 172.18.0.2, and it connects normally, everything works, the keys are added. Why does this happen without port forwarding? Default docker network - bridge
docker run --rm -it redis will not expose the port. Try stop the redis container. Then run redis-cli -h 172.18.0.2 to check if another redis exists.
It is only possible because you're on native Linux, and the way Docker networking is implemented, it happens to be possible to directly connect to the container-private IP addresses from outside Docker.
This doesn't work in a wide variety of common situations (on MacOS or Windows hosts; if Docker is actually running in a VM; if you're making the call from a different host) and the IP address you get can change if the container is recreated. As such it's not usually a best practice to look up the container-private IP address. Use docker run -p to publish a port, and connect to that published port and the host's IP address.
It's because the redis docker file exposes the right port for the api which is 6379.

How to ping Docker-Container inside host network?

I'm working with Docker containers for a while now but can't figure out how to ping docker containers which are part of my host network.
So until now I created my containers specifing the name and networks flags like described in many tutorials like: https://www.digitalocean.com/community/questions/how-to-ping-docker-container-from-another-container-by-name
Where I am able to create a network and afterwards run my containers in these networks for example like:
docker run -d --name web1 -n testnetwork
docker run -d --name web2 -n testnetwork
That would enable me to ping my containers from each other with:
docker exec -it web1 bash # enter container
ping web2 #ping second container
Now I have to use a given application which only runs in the "host" network for now. To access this container from my other containers they have to be in the same network (== "host").
But It seems like I cant ping my containers from each other anymore. I'm also unable to ping my containers from my host machine using their name.
Did I overlooked something?
Any help would be appreciated!
Best regards
If you set --network host, you basically disable Docker's entire networking stack. Among other things, that disables normal inter-container communications: if you're using host networking you can't call another container by its name. Host networking is very rarely necessary (and doesn't work well on some host platforms); the first thing I'd look at is whether you can switch back to standard (bridged) networking.
If you do run a container with --network host, it's indistinguishable from other processes running on that host. That means you can't directly send ICMP packets to it, any more than you can ping(1) your ssh daemon or Web browser. You need to connect to the container using the host's IP address or DNS name, even from other containers on the same host. From inside of a Docker container, how do I connect to the localhost of the machine? discusses several ways to do this.
(I don't think you can customize the behavior of Docker or Linux when a container receives an ICMP ECHO packet; ping(1) a container doesn't seem that useful.)

Docker - connecting to an open port in a container

I'm new to docker and maybe this is something I don't fully understand yet, but what I'm trying to do is connect to an open port in a running docker container. I've pulled and run the rabbitmq container from hub (https://hub.docker.com/_/rabbitmq/). The rabbitmq container should uses port 5672 for clients to connect to.
After running the container (as instructed in the hub page):
$ docker run -d --hostname my-rabbit --name some-rabbit rabbitmq:3
Now what I want to do is telnet into the open post (it is possible on a regular rabbitmq installation and should be on a container as well).
I've (at least I think I did) gotten the container IP address using the following command:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
And the result I got was 172.17.0.2. When I try to access using telnet 172.17.0.2 5672 it's unsuccessful.
The address 172.17.0.2 seems strange to me because if I run ipconfig on my machine I don't see any interface using 172.17.0.x address. I do see Ethernet adapter vEthernet (DockerNAT) using the following ip: 10.0.75.1. Is this how it is supposed to be?
If I do port binding (adding -p 5672:5672) then I can telnet into this port using telnet localhost 5672 and immidiatly connect.
What am I missing here?
As you pointed out, you need port binding in order to achieve the result you need because you are running the application over the default bridge network (on Windows i guess).
From the official docker doc
Containers connected to the same user-defined bridge network automatically expose all ports to each other, and no ports to the outside world. [...]
If you run the same application stack on the default bridge network, you need to open both the web port and the database port, using the -p or --publish flag for each. This means the Docker host needs to block access to the database port by other means.
Later in the rabbitmq hub there is a reference to a Management Plugin which is run by executing the command
docker run -d --hostname my-rabbit --name some-rabbit -p 8080:15672 rabbitmq:3-management
Which exposes the port 8080 used for management which I think is what you may need.
You should also notice that they talk about clusters and nodes there, maybe they meant the container to be run as a service in a swarm (hence using the overlay network and not the bridge one).
Hope I could help somehow :)

How to access a Process running on docker on a host from a remote host

How to access or connect to a process running on docker on host A from a remote host B
consider a Host A with ip 192.168.0.3 which is running a application on docker on port 3999 .
If i want to access that application from remote machine with IP 192.168.0.4 in same subnet.
To be precise i am running Kafka producer on the server and i am trying to receive using Kafka-console-Consumer.
Use --net=host to run your container and it'll use the host's network stack, then you can connect to the application running inside container like it's running on host directly.
Port mapping, use option -p to map the port inside your container to a port of your host. e.g. docker run -d -p <container port>:<host port> <image>, then you can connect to <host>:<host port> to connect your application inside container
Docker's built-in multi-host network. In early releases the network driver is isolated from docker's core, you have to use 3rd party tools like flannel or weave for multi-host connection, but from release 1.9, it has been merged into docker. You can follow it's guide to set it up.
Hope this is helpful :-)
First you need to bind docker container's port to the Host A:
docker run -d -p 3999:3999 kafka-producer
Then you need to access Host A from Host B using IP:Port
192.168.0.3:3999

Resources