Pre-requisite: Understanding of docker
Docker provides powerful networking to establish communication between containers and outside containers. Docker networking comes with a variety of drivers, that can be plugged into to provide different capabilities.
Following network drivers are provided by docker:
- bridge: isolated network for containers
- host: directly use the host networking with any isolation
- overlay: to facilitate communication between containers running on different docker daemons
- ipvlan: provides developer with control over IPv4 and IPv6 addressing
- macvlan: assigns MAC address to container so it appears as physical device on the network
- none: disable all networking
We will discuss only the bridge network here.
Bridge driver
As shown in the following diagram this is the network we are going to build here utilizing docker bridge capabilities.
docker0
is the default bridge and mynetwork
is a user defined network bridge.
Let’s first pull two lightweight docker images: nginx and busybox! Nginx is lightweight web server while busybox comes with pre-installed unix utilities that we would require here.
We would want to have connectivity between the containers as well connect to container from outside docker and vice versa.
By default docker uses the bridge driver, docker creates ethernet interfaces for the two containers and connects them through the default bridge docker0.
We can use the command docker inspect bridge
to find out ip address of these two running containers.
Connectivity in bridge network
We will verify connection from container to container, container to host and vice versa. For that purpose we would also need to have ping
utlity, busybox has it pre installed.
Let’s login to busybox shell using docker exec -it server_busybox sh
.
Container to container
Ping the IP address of nginx_server ping 172.17.0.3
.
Its successful! Busybox container is able to communicate to nginx server through the IP address of the nginx container.
Also, we will not be able to ping nginx server by its container name, default bridge do not have DNS resolution for the containers. Later in this article we will discover user defined bridge where this problem is tackled.
Container to host
From a container on bridge network, we can connect to servers on our host or internet. (as long as the server doesn’t restrict incoming connection)
To verify this lets ping google from busybox server ping google.com
, we can see that it works!
Host to container
Nginx webserver (server_nginx) is running on port 80, but can we access it from our host browser?
The answer is No!
This happens because docker doesn’t bind nginx port 80 to host. To be able to access nginx on host we have to map docker port 80 on which nginx server is running to a port on the host.
Docker allows port mapping using --publish <host port>:<container port>
we can just use -p
instead of --publish
.
To achieve that stop the current nginx server and re-run the container along with -p
flag.
Now go to a browser on host, and visit localhost:80. We should be able to see the below page.
Connection Successful!
User defined bridge
User-defined bridge networks are considered superior to the default bridge network.
Why to use a user defined bridge?
- User defined network comes with automatic DNS resolution between containers.
- We can create multiple user defined network with different configurations, a container can be assigned a network configuration that it require.
- User defined network also comes with better network isolation
- Each container can attach/detach to its user defined network on fly.
Its super easy to build a user defined network.
Running docker network create mynetwork
creates a user defined bridge network mynetwork
Lets run two more nginx and busybox containers server2_nginx
and server2_busybox
on mynetwork.
As 80 is already mapped to server_nginx
port on host machine, we can use port 81 this time.
Check the IP address of the containers using docker inspect my_network
We can login to server2_busybox using docker exec -it server2_busybox sh
and ping server2_nginx using its container name rather than IP address.
That works! As the DNS resolution is in place on a user defined bridge network.
Note, We cannot ping server_nginx(172.17.0.3) from server2_busybox, as they are on different bridge networks!!