How to visit another host inside docker? - networking

I have two servers on the same LAN. Their IP addresses are 10.0.0.1 (Server A) and 10.0.0.2 (Server B).
The MySQL server runs on Server B.
The docker container runs on Server A. It's IP address is 172.17.0.2, and the eth0 of the host is 172.17.0.1.
My question is, how to connect to Server B in the docker container inside Server A?
Thanks.

Something very easy to setup is the new Docker swarm mode (if you have Docker 1.12.2) https://docs.docker.com/engine/swarm/
With this all you have to do is connect your two servers by following the doc. You can then create an overlay network. Then to create your containers you will have to use the command docker service create instead of docker run.
You may also want to use some constraints to specify where the services should run.

Related

What is overlay network and how does DNS resolution work?

I cannot connect to external mongodb server from my docker swarm cluster.
As I understand this is because of cluster uses overlay network driver. Am I right?
If not, how does docker overlay driver works and how can I connect to external mongodb server from cluster?
Q. How does the docker overlay driver work?
I would recommend this good reference for understanding docker swarm network overlay, and more globally, Docker's architecture.
This states that:
Docker uses embedded DNS to provide service discovery for containers running on a single Docker Engine and tasks running in a Docker Swarm. Docker Engine has an internal DNS server that provides name resolution to all of the containers on the host in user-defined bridge, overlay, and MACVLAN networks.
Each Docker container ( or task in Swarm mode) has a DNS resolver that forwards DNS queries to Docker Engine, which acts as a DNS server.
So, in multi-host docker swarm mode, with this example setup :
In this example there is a service of two containers called myservice. A second service (client) exists on the same network. The client executes two curl operations for docker.com and myservice.
These are the resulting actions:
DNS queries are initiated by client for docker.com and myservice.
The container's built-in resolver intercepts the DNS queries on 127.0.0.11:53 and sends them to Docker Engine's DNS server.
myservice resolves to the Virtual IP (VIP) of that service which is internally load balanced to the individual task IP addresses. Container names resolve as well, albeit directly to their IP addresses.
docker.com does not exist as a service name in the mynet network and so the request is forwarded to the configured default DNS server.
Back to your question:
How can I connect to an external mongodb server form cluster?
For your external mongodb (let's say you have a DNS for that mongodb.mydomain.com), you are in the same situation as the client in above architecture, wanting to connect to docker.com, except that you certainly don't wan't to expose that mongodb.mydomain.com to the entire web, so you may have declared it in your internal cluster DNS server.
Then, how to tell docker engine to use this internal DNS server to resolve mongodb.mydomain.com?
You have to indicate in your docker service task that you want to use an internal DNS server, like so:
docker service create \
--name myservice \
--network my-overlay-network \
--dns=10.0.0.2 \
myservice:latest
The important thing here is --dns=10.0.0.2. This will tell the Docker engine to use the DNS server at 10.0.0.2:53 as default if it can not resolve the DNS name in the VIP.
Finally, when you say :
I cannot connect to external mongodb server from my docker swarm cluster. As I understand this is because of cluster uses overlay network driver. Am I right?
I would say no, as there is a built in method in docker engine to forward unknown DNS name coming from overlay network to the DNS server you want.
Hope this helps!

How to create docker containers with the same internal IP address?

I have an environment where I need to run some external software into Docker containers. This software is trying to connect to our product by specific IP address - let's say 192.168.255.2 - and this address is fixed and cannot be changed. Moreover, host IP address must be also set to specific IP - let's say 192.168.255.3.
Product supports 2 ethernet interfaces:
first of them has strict restrictions regarding IP addressing - let's call it "first"
second does not have such restrictions and provides similar functionalities - for this example let's assume that the IP address of this interface is set to 10.1.1.2/24 - let's call it "second"
I need to run simultaneously multiple docker containers, each container shall be connected to one product (1 to 1 relationship).
Things that are run inside containers must think that they're reaching connectivity to product by using "first" network interface (one which have static IP assignment and which cannot be changed).
All I want to do is to create containers with the same IP addresses to pretend that application inside container is using "first" ethernet interface of product and then at host level I want to redirect all traffic using IPTables to "second" interface.
Therefore I have one major problem: how to create multiple docker containers with the same IP address?
From the exact phrasing of your question, docker has the option to share the network stack of another container. Simply run:
docker run -d --name containera yourimage
docker run -d --net container:containera anotherimage
And you'll see that the second container has the same IP interfaces and can even see ports being used by the first container.
I'd recommend instead that you install both interfaces on your docker host and bind to the IP on the host that you need, then don't worry about the actual IP of the container. The result will be much simpler to manage. Here's how you bind to a single IP on the host with ports 8080 and 8888 that's mapped to two different container's port 80:
docker run -d -p 192.168.255.2:8080:80 --name nginx8080 nginx
docker run -d -p 192.168.255.2:8888:80 --name nginx8888 nginx

Unable to access web application in Docker container via container's ip and exposed port over http

I have a docker container running on a Centos host and has a host port: container port mapping. The docker container has an web application running.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a2f8ce62bb69 image1 "/bin/bash" 16 hours ago Up 16 hours 22/tcp, 0.0.0.0:7001->7001/tcp nostalgic_elion
I can access the application over http by host IP address and host port which is mapped. However if I replace the host IP with container IP, then I get an error saying "site cannot be reached" ERR_CONNECTION_TIMED_OUT.
Is it possible to access using the container IP and exposed port over http? Unfortunately I do not have much background on networking.
By default Docker containers can make connections to the outside world, but the outside world cannot connect to containers. (https://docs.docker.com/v1.7/articles/networking/)
The docs however, say it is possible to have outside world talk to containers with some extra run options. The docs say about using the run with options -P or ----publish-all=true|false. Refer the options in the same docker networking page.
If your only need is to share different ip address to teams. update your host file with the docker containers ip address - localhost
My /etc/hosts file:
container-ip localhost
container-ip localhost
container-ip localhost

how docker container can get IP where docker swarm runs

So my application server (instance with swarm installed) and many clients (docker containers on a different physical nodes) require that clients should connect to server by hostname and I don't know how container can get node IP where swarm runs to be able to connect.
I know that I can pass hosts rules to each docker container with hostname and IP of the node where swarm runs but I don't know how to get that IP because there is a lot of interfaces with different IPs.
So generally I'm looking for something like docker client can ask swarm what is your IP to be able to connect back.

How to send http request from Docker to localhost or Virtual Machine

Being new to Docker and VM's, I have run into a blocker. I have a node app that needs to send a POST request from a Docker container to a Virtual Machine or to my local machine.
I have read through the Docker documentation, but still don't understand what I need to do in order to accomplish this.
So how can I send an http request from my node app running in a Docker Container to my Vagrant Box?
By default, Docker creates a virtual interface (docker0) in your host machine with IP 172.17.42.1. Each of the container launched will have an IP of the network 172.17.42.1/16, and they will be able to connect to host machine connecting to IP 172.17.42.1.
If you want to connect a docker container with another service running in a virtual machine running with other provider (e.g.: virtualbox, vmware), the easiest way is forwarding the ports needed by the service to you host machine and then, from your docker container, connecting to IP 172.17.42.1. You should check your virtual machine provider documentation to see details about this. And if you are using libvirt/KVM (or with any other provider), you can use iptables to enable port forwarding.

Resources