Docker Networking
Tags: docker, linux, microservices, networking
Published: 2021-09-30 16:14:56

Docker takes care of the networking aspects so that containers can communicate with other containers and also with the Docker Host.

Docker networking subsystem is pluggable, using drivers. 

There are several drivers available by default and provides core networking functionality.

* bridge 
* host
* overlay
* macvlan
* none

We can check what all the network drivers are supported by Docker Containers and also at what ip that driver is configured to connect to the other containers.

```shell
docker network ls
```

if you want to check particular network driver is running at what IP, we can inspect that network driver

```shell
docker inspect bridge
```

![network driver](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iiy8euep357wx8f2vvku.png)

We can check what all drivers what containers are running and what are not by simply inspecting that particular network driver.

```shell
docker inspect network host
```

![networkhost](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ldvzn1o0anca316gpl1v.png)
 

We can also create a docker container and can launch it to the available network drivers. Like here we have will launch a container on ***host*** driver.

```shell
docker container run -dt --name myhost --network host ubuntu
```
![creatingcontainerhostnetowrk](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1na9vsqxhwv4ziol884q.png)

### Bridge Network

A bridge network uses a software bridge that allows containers connected to the same bridge network to communicate while providing isolation from containers which are not connected to that bridge network.

C1,C2, C3 are the containers in the bridge network, can also communicate with eachother

![BridgeNetwork](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vfaczb5snzwo4w5oevw7.png)

If want to see the bridge in the docker container, you can simply inspect any docker container and there you will get the bridge details.
While creating a container if you don't mention the network, by default it is ***bridge*** network
We also can create User-defined Bridge Network which are superior to the default bridge.

Let me show you how two docker containers can connect with each other.

* Step 1:Created 2 docker containers ***bridge01*** and ***bridge02*** 

```shell
docker container run -dt --name bridge01 ubuntu
docker container run -dt --name bridge02 ubuntu
```

* Step 2: Enter into the ***bridge01*** container and installed the net-tools(ifconfig) and iputils-ping(ping) using below commands.

```shell
docker container exec -it bridge01 bash
apt-get update && apt-get install net-tools
apt-get install iputils-ping
```

* Step3: We will check the ip address for ***bridge02*** . So, to ping to this container.

```shell
docker inspect bridge02
```

![inspectdockercontainer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/doprmoy61430xn7tg2jd.png)
 
* Step 4: Here we ping the ***bridge02*** container from ***bridge01***

```shell
docker container exec -it bridge01 bash
ping 172.17.0.7
```

![pingcontainer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p1th2o5lsuli7fdfgo36.png)


###User-Defined Bridge Network

Differences between user-defined bridges and the default bridge
* User-defined bridges provide automatic DNS resolution between containers.
* User-defined bridges provide better isolation
* Containers can be attached and detached from user-defined networks on the fly.
* Each user-defined network creates a configurable bridge.
* Linked containers on the default bridge network share environment variables.

Reference: https://docs.docker.com/network/bridge/

Lets create a custom user-defined bridge.

```shell
docker network create --driver bridge mybridge
```

![customnetworkbridge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f7g2ceh17lnsm4qakoto.png)

If we don't define the driver, it will by default take the bridge driver.

```shell
docker network create mybridge-demo
```

![defaultbridgecustom](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i5mcg2bxzyictgdnfmpd.png)


To get the subnet and Gateway details of our custom network.

```shell
docker network inspect mybridge
```

![subnetgateway](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2nff5olwgd0ijy57bruv.png)
 
Now, we can see that new network containers will be created inside the ubuntu docker container.

![networkcontainer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wkedif9wxt3xr47y2xto.png)

#### Now, let me show you the best feature of the custom user-defined network. which is ( _User-defined bridges provide automatic DNS resolution between containers._ )

* Step1 : Creating 2 docker containers(***mybridge01*** and ***mybridge01***) on custom network (***mybridge***) that we have created.

![dockercontainersoncustomnetwork](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/efr6kgefhuf15md7lm1w.png)

```shell
docker container run -dt --name mybridge01 --network mybridge ubuntu
docker container run -dt --name mybridge02 --network mybridge ubuntu
apt-get update && apt-get install net-tools && apt-get install iputils-ping
```
* Step 2: Ping the mybridge02 by its name, And here we will be able to connect. This is what we call DNS resolution.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4p7sq2cp9m0gam6f5wr3.png)

* Step3: If we try to do the same with the previous containers that we created with the default bridge network(***bridge01*** and ***bridge02***). We will not able to ping with the name defined.

![mybridgeconnectping](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/70qohotjpnbera7mr4tj.png)
 
You can also define the custom options for your network, which will give us more feasibility to customize with our use-case.

Like in user-defined network we don't have defined any options yet.

![optionmybridge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9jrz1cuno99ue6s5erv.png)


But, we can define options like we have in default bridge network.

![optionbridge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3g9f65k2iyvacbrnzxm0.png)

###Host Network

This driver removes the network isolation between the docker host and the docker containers to use the host’s networking directly.
For instance, if you run a container that binds to port 80 and you use host networking, the container’s application will be available on port 80 on the host’s IP address.

So, now lets see how host network removes isolation between the docker host and the docker containers.

* Step1: We will create a ***myhostdemo1*** container having host network and will install necessary packages.

```shell
docker network ls
docker container run -dt --name myhostdemo1 --network host ubuntu
docker container exec  -it myhostdemo1 bash
apt-get update && apt-get install net-tools && apt-get install iputils-ping
```

![myhostdemo1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysjshqd3tyj0cb3btiu3.png)
 
* Step2: Now we will install and start nginx on the container ***bridge01***, that we had already created above with the bridge network.

```shell
docker container exec  -it bridge01 bash
netstat -ntlp
apt install nginx
/etc/init.d/nginx start
```

![bridgengix](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/muswk92vcikme0711csp.png)

* Step 3: If we exit the container and try to find that nginx host address. As, it is bridge network we will not able to see it.

![outsidebridge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0j2c3ph4bc86ks0qxot.png)
 
* Step4: If we do the same with myhostdemo01. Installing and starting the nginx server, We will see that host address is reflecting outside the container as-well.

![outsidehostdemo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b5zvow9n5ue1mr7hwfaq.png)
 
So, host network container can connect to all the docker containers internal container network drivers as-well external containers network drivers.

you can check it out by ***ifconfig*** in the host network container.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvsumb60y68144czb0hh.png)
 

### None Network

If you want to completely disable the networking stack on a container, you can use the none network.
This mode will not configure any IP for the container and doesn’t have any access to the external network as well as for other containers.
Eg. Virus affect testing

Demo:
Created one none network container and trying to ping _google.com_ but we are not able to ping.

![nonenetwork](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsfhmvgacgu85uzow7en.png)

### Publishing Exposed Ports of Container

We were discussing an approach to publishing container port to host.

```shell
docker container run -dt --name webserver -p 80:80 nginx
```

This is also referred to as a publish list as it publishes the only a list of the port specified.
There is also a second approach to publish all the exposed ports of the container.

```shell
docker container run -dt --name webserver -P nginx
```

This is also referred to as a publish all.
In this approach, all exposed ports are published to random ports of the host.

![example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/46g0bc1z80pkvklfd3px.png)
 
###Legacy Approach for Linking Containers

Before the Docker networks feature, you could use the Docker link feature to allow containers to
discover each other and securely transfer information about one container to another container.
The --link flag is a legacy feature of Docker. It may eventually be removed. Unless you absolutely need
to continue using it, we recommend that you use user-defined networks to facilitate communication
between two containers instead of using --link

* Step1: Created a container ***container01***

![step1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9k80ex71qzrwqt2gedbl.png)

* Step2: Create a new container linking to the above launched container.

```shell
docker container run -dt --link container01:container --name container02 busybox sh
```

![step2linking](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rxlu4wknl763rec5idc1.png)

* Step3: on login to ***container02*** and pinging ***container01***, we are able to ping

![step3ping](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zpvri38ukl4o4ysqrbhd.png)

* Step4: To check the link, you can cat the _/etc/hosts_ file

![step4link](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yu0apjhhh3dl4ao0ia2g.png)
 
 
References:
[Official Docker](https://docs.docker.com/get-docker/)
[Udemy Course](https://www.udemy.com/course/docker-certified-associate/)

Credit:
[Zeal Vora](https://in.linkedin.com/in/zealvora)

[Prev: Image Creation, Management, and Registry(Part 2)](https://dev.to/dporwal/image-creation-management-and-registry-part-2-514n)