docker containers static IP to communicate two different hosts - docker

is it possible to change the ip of docker0 or provide a static IP to docker containers, because by default docker containers have the ip range of 172.17.0.2/16 but my network is 192.168.X.X/24 in this situation on the server container is running there all the containers is able to communicate within servers but from other server this failed to connect.

How do you set up your cluster? Do you use Swarm? If so, you need to use a k/v storage backend to enable communication between two containers hosted on different hosts. Is this what you aim to do, or do you want the host to communicate with the container on the other host?
Anyway, the solution is similar.
I re-writing a tuto for Docker Swarm to pull request it into their Swarm doc, you may want to take a look: https://www.auzias.net/en/docker-network-multihost/
Have a nice day!

problem can be fix by using --network=host
this will allow your container to use the host machine network. for direct accessing your container you can change the ssh port of the container and access your container with the specific port number.

I answered a similar question here
https://stackoverflow.com/a/35359185/4094678
The difference in your case would be to create a netowrk with subnet 192.168.X.X/24 and then assign desired ip addr to container with --ip

Here we can't able to change docker0 Ip address, but we have option to create multiple networks.
Solution 1:
can be by using start container with host network --network=host
Solution2:
we can also start the container by exposing the cluster required port and from another node we can communicate it.
-p hostport:serviceport
Or, Solution3:
We can deploy cluster over docker swarm.

Related

How docker containers expose services?

I'm deploying a stack of services through the command:
docker stack deploy -c <docker-compose.yml> <stack-name>
And I'm mapping ports of one of these services on docker compose with ports: 8000:8000.
The network driver being used is overlay.
I can access these services via localhost:8000, via Peers IP(?).
When I inspect the network created, I can see the local IPs of each container (for instance, 10.0.1.2). But Where is the external IP of container (the one like 172.0. ...) ?
I am running these docker container on a virtual machine ubuntu.
How can I access the services running on containers from other nodes running on other networks? Isn't possible to access via hostIP:port?
If so, how do I get the host IP? When I do docker-machine IP I get "host is not running".
[EDIT: I wasn't doing port mapping between the host and the VM in virtualbox. Now it works!]
Whats the best way to communicate between containers on the same swarm?
Thanks
Whats the best way to communicate between containers on the same swarm? Through name discovery?
In general if you communicate between containers you should use the container/service name.
And for your other problem you probably wan't a reverse proxy like nginx or traefik.

How to expose the docker container ip to the external network?

i want to expose the container ip to the external network where the host is running so that i can directly ping the docker container ip from an external machine.
If i ping the docker container ip from the external machine where the machine hosting the docker and the machine from which i am pinging are in the same network i need to get the response from these machines
Pinging the container's IP (i.e. the IP it shows when you look at docker inspect [CONTAINER]) from another machine does not work. However, the container is reachable via the public IP of its host.
In addition to Borja's answer, you can expose the ports of Docker containers by adding -p [HOST_PORT]:[CONTAINER_PORT] to your docker run command.
E.g. if you want to reach a web server in a Docker container from another machine, you can start it with docker run -d -p 80:80 httpd:alpine. The container's port 80 is then reachable via the host's port 80. Other machines on the same network will then also be able to reach the webserver in this container (depending on Firewall settings etc. of course...)
Since you tagged this as kubernetes:
You cannot directly send packets to individual Docker containers. You need to send them to somewhere else that’s able to route them. In the case of plain Docker, you need to use the docker run -p option to publish a port to the host, and then containers will be reachable via the published port via the host’s IP address or DNS name. In a Kubernetes context, you need to set up a Service that’s able to route traffic to the Pod (or Pods) that are running your container, and you ultimately reach containers via that Service.
The container-internal IP addresses are essentially useless in many contexts. (They cannot be reached from off-host at all; in some environments you can’t even reach them from outside of Docker on the same host.) There are other mechanisms you can use to reach containers (docker run -p from outside Docker, inter-container DNS from within Docker) and you never need to look up these IP addresses at all.
Your question places a heavy emphasis on ping(1). This is a very-low-level debugging tool that uses a network protocol called ICMP. If sending packets using ICMP is actually core to your workflow, you will have difficulty running it in Docker or Kubernetes. I suspect you aren’t actually. Don’t worry so much about being able to directly ping containers; use higher-level tools like curl(1) if you need to verify that a request is reaching its container.
It's pretty easy actually, assuming you have control over the routing tables of your external devices (either directly, or via your LAN's gateway/router). Assuming your containers are using a bridge network of 172.17.0.0/16, you add a static entry for the 172.17.0.0/16 network, with your Docker physical LAN IP as the gateway. You might need to also allow this forwarding in your Docker OS firewall configuration.
After that, you should be able to connect to your docker container using its bridge address (172.17.0.2 for example). Note however that it will likely not respond to pings, due to the container's firewall.
If you're content to access your container using only the bridge IP (and never again use your Docker host IP with the mapped-port), you can remove port mapping from the container entirely.
You need to create a new bridge docker network and attach the container to this network. You should be able to connect by this way.
docker network create -d bridge my-new-bridge-network
or
docker network create --driver=bridge --subnet=192.168.0.0/16 my-new-bridge-network
connect:
docker network connect my-new-bridge-network container1
or
docker network connect --ip 192.168.0.10/16 my-new-bridge-network container-name
If the problem persist, just reload docker daemon, restart the service. Is a known issue.

Easiest way to connect Docker container to local host

I am wondering if is it possible to connect to an app on local host from Docker container.
I run two Docker container which are connected to each other via link option. But how can I connect one of the containers to the local host?
Yes, use docker run --network=container:<container-id>
--network='container:': reuse another container's network stack
This let you run a container sharing the same network interface (then localhost) from another container.
Alternatively, you can use the host mode to give your containers the same network ips that the host has (including localhost). docker run --network=host:
--network= 'host': use the Docker host network stack
Docs: https://docs.docker.com/engine/reference/run/#name-name
I think it is possible.
Try communicate with the host's<ip:port>
ip: useip addror something similar to get the one of eth0,not the one of docker0
port:the one you assigned to the app
To make the process easier,perhaps turn selinux and firewall down when you try.

Communication between docker containers in different networks

If I know a Docker container IP address, I can easily communicate with it from another container, but as long as they are in same network.
My question is, how can I communicate with containers from another network and why can't I access local IP which is on the same machine? I am interested in network explanation why I can access 172.19.0.1 from 172.19.0.2 but I can't access 172.20.0.1 from 172.19.0.2.
What are possible workarounds to making Docker container from one network to communicate with docker container from another network?
You can publish a port and then access that port over localhost (or 0.0.0.0 for troubleshooting).
Other than that you could use an alternative to docker network like linking or other things. But I wouldn't suggest that. If you want two containers to communicate with eachother and not the public just create a new network for those two containers.
You can specify that this network is external and they can join it even from different compose files.

Cross container communication with Docker

An application server is running as one Docker container and database running in another container. IP address of the database server is obtained as:
sudo docker inspect -f '{{ .NetworkSettings.IPAddress }}' db
Setting up JDBC resource in the application server to point to the database gives "java.net.ConnectException".
Linking containers is not an option since that only works on the same host.
How do I ensure that IP address of the database container is visible to the application server container?
If you want private networking between docker containers on remote hosts you can use weave to setup an overlay network between docker containers. If you don't need a private network just expose the ports using the -p switch and configure the addresses of the host machine as the destination IP in the required docker container.
One simple way to solve this would be using Weave. It allows you to create many application-specific networks that can span multiple hosts as well as datacenters. It also has a very neat DNS-based service discovery mechanism.
I should disclaim, I am one of Weave engineering team.
Linking containers is not an option since that only works on the same host.
So are you saying your application is a container running on docker server 1 and your db is a container on docker server 2? If so, you treat it like ordinary remote hosts. Your DB port needs to be exposed on docker server 2 and that IP:port needs to be configured into your application server, typically via environment variables.
The per host docker subnetwork is a Private Network. It's perhaps possible to have this address be routable, but it would be much pain. And it's further complicated because container IP's are not static.
What you need to do is publish the ports/services up to the host (via PORT in dockerfile and -p in your docker run) Then you just do host->host. You can resolve hosts by IP, Environment Variables, or good old DNS.
Few things were missing that were not allowing the cross-container communication:
WildFly was not bound to 0.0.0.0 and thus was only accepting requests on eht0. This was fixed using "-b 0.0.0.0".
Firewall was not allowing the containers to communication. This was removed using "systemctl stop firewall; systemctl disable firewall"
Virtual Box image required a Host-only adapter
After this, the containers are able to communicate. Complete details are available at:
http://blog.arungupta.me/2014/12/wildfly-javaee7-mysql-link-two-docker-container-techtip65/

Resources