To fully master and understand Docker, The networking part is a must to learn, that’s why on this article i will explain for you the unique networking approach that docker follows and list for you the networking types you can use, how they works and finally we will go through some practical examples.
Once you launch a Docker container, Docker assigns it directly a network interface and an IP address with a default gateway and some other components of course like a routing table and DNS services. In the default state, all those addresses come from the same pool and all containers on the same host can communicate with one another. Of course this default behaviour is changeable and we can do that by defining the network to which the container should connect, either by creating a custom user-defined network or by using a network provider plugin which are pluggable using drivers. You can connect a Docker container to a particular network by using the –net switch when launching it.
The following command launches a container from the busybox image and joins it
to the host network. This container prints its IP address and then exits.
docker run --rm --net=host busybox ip addr
Docker offers five network types, each with a different capacity for communication with other network entities.
Docker networking types
With this type of networking, the container always shares the same IP address and the network namespace as that of the host. Also, services running inside this container have the same network capabilities as services running directly on the host.
The container runs in a private network internal to the host. Communication is open to other containers in the same network. Communication with services outside of the host goes through network address translation (NAT) before exiting the host. (This is the default mode of networking when the –net option isn’t specified).
Custom bridge network:
This is the same as Bridge Networking but uses a bridge explicitly created for this (and other)
containers. An example of how to use this would be a container that runs on an exclusive “database” bridge network.
Another container can have an interface on the default bridge and the database bridge, enabling it to communicate with both networks.
A container can share the address and network configuration of another container. This type enables process isolation between containers, where each container runs one service but where services can still communicate with one another on the localhost address.
This option disables all networking for the container.
The host mode of networking allows the Docker container to share the same IP address as that of the host and disables the network isolation otherwise provided by network namespaces. The container’s network stack is mapped directly to the host’s network stack. All interfaces and addresses on the host are visible within the container, and all communication possible to or from the host is possible to or from the container.
If you run the command ip addr on a host (or ifconfig -a if your host doesn’t have the ip command available), you will see information about the network interfaces.
If you run the same command from a container using host networking, you will see the same information:
In a standard Docker installation, the Docker daemon creates a bridge on the host with the name of docker0. When a container launches, Docker then creates a virtual ethernet device for it. This device appears within the container as eth0 and on the host with a name like vethxxx where xxx is a unique identifier for the interface. The vethxxx interface is added to the docker0 bridge, and this enables communication with other containers on the same host that also use the default bridge.
To demonstrate using the default bridge, run the following command on a host with Docker installed. Since we are not specifying the network – the container will connect to the default bridge when it launches.
Run the ip addr and ip route commands inside of the container. You will see the IP address of the container with the eth0 interface:
In another terminal connected to the host, run the ip addr command. You will see the corresponding interface created for the container. In the image below it is named veth1aac59@if26. Yours will be different.
Although Docker mapped the container IPs on the bridge, network services running inside of the container are not visible outside of the host. To make them visible, the Docker Engine must be told when launching a container to map ports from that container to ports on the host. This process is called publishing. For example, if you want to map port 80 of a container to port 8080 on the host, then you would have to publish the port as shown in the following command:
docker run --name nginx -p 8080:80 nginx
By default, the Docker container can send traffic to any destination. The Docker daemon creates a rule within Netfilter that modifies outbound packets and changes the source address to be the address of the host itself. The Netfilter configuration allows inbound traffic via the rules that Docker creates when initially publishing the container’s ports.
The output included below shows the Netfilter rules created by Docker when it publishes a container’s ports.
Custom Bridge Network
There is no requirement to use the default bridge on the host; it’s easy to create a new bridge network and attach containers to it. This provides better isolation and interoperability between containers, and custom bridge networks have better security and features than the default bridge.
- All containers in a custom bridge can communicate with the ports of other containers on that bridge. This means that you do not need to publish the ports explicitly. It also ensures that the communication between them is secure. Imagine an application in which a backend container and a database container need to communicate and where we also want to make sure that no external entity can talk to the database. We do this with a custom bridge network in which only the database container and the backend containers reside. You can explicitly expose the backend API to the rest of the world using port publishing.
- The same is true with environment variables – environment variables in a bridge network are shared by all containers on that bridge.
- Network configuration options such as MTU can differ between applications. By creating a bridge, you can configure the network to best suit the applications connected to it.
To create a custom bridge network and two containers that use it, run the following commands:
docker network create mynetwork docker run -it --rm --name=container-a --network=mynetwork busybox /bin/sh docker run -it --rm --name=container-b --network=mynetwork busybox /bin/sh
A specialized case of custom networking is when a container joins the network of another container. This is similar to how a Pod works in Kubernetes.
The following commands launch two containers that share the same network namespace and thus share the same IP address.
Services running on one container can talk to services running on the other via the localhost address.
docker run -it --rm --name=container-a busybox /bin/sh docker run -it --rm --name=container-b --network=container:container-a busybox /bin/sh
This mode is useful when the container does not need to communicate with other containers or with the outside world. It is not assigned an IP address, and it cannot publish any ports.
docker run --net=none --name busybox busybox ip a
I hope that everything i clear until now, we discussed all docker networking types, how they works, what is the need of every type and when you should use it and finally, how to create the network you need. On the next article we will talk about the communication between two containers or more.