Docker Networking Demystified: Part 1

Docker Networking Demystified: Part 1

Introduction

Docker has transformed the way developers build, ship, and run applications. Its networking capabilities are a key feature that allows containers to communicate with one another and the outside world. However, Docker networking can be complex and challenging to comprehend, particularly for those new to the technology. In this article, we will demystify Docker networking by exploring how containers communicate with each other and the concept of network namespaces. Read on to gain a better understanding of Docker networking.

Network Namespaces

In Linux, a network namespace is a technique used to isolate network resources, such as network interfaces, routing tables, and firewall rules, from the rest of the system. Each network namespace provides an independent network stack that can be used by processes running within that namespace. This allows multiple applications to run on the same host while using different network configurations.

Docker leverages network namespaces to provide container-level networking isolation. When a Docker container is started, it is assigned its own network namespace. This namespace provides a virtual network interface, IP address, routing table, and firewall rules for the container. The Docker daemon also creates a bridge network, which acts as a virtual switch connecting all the containers in the same network. Containers can communicate with each other through this bridge network or with the outside world through the host's network interface.

Docker also supports other network drivers, such as overlay networks, which allow containers to communicate across multiple hosts, and host networks, which allow containers to use the host's network interface directly. Each network driver uses a different network namespace to provide network isolation and different features for container networking.

Overall, network namespaces provide a powerful tool for isolating and managing network resources in Linux, and Docker leverages this technology to provide flexible and secure networking for containerized applications.

How it works

To recreate docker containers at the most basic level we can create two network namespaces and then create a virtual ethernet pair (veth pair) and plug the two ends into each of the network namespaces now this creates our simple container network in the most basic terms.

Below is the script that does the same. So let's understand it line by line.

set -o pipefail

This sets the Bash option "pipefail", which causes a pipeline (a series of commands separated by pipes) to fail if any command in the pipeline fails. This ensures that errors in the pipeline are detected and the script exits with a non-zero status.

string="$1"

This assigns the first command-line argument to the variable "string".

if [ "$string" = "up" ]; then

This checks if the value of "string" is equal to "up". If it is, the following commands will be executed.

ip netns add net1
ip netns add net2

These commands create two network namespaces called "net1" and "net2" using the "ip netns add" command.

ip link add veth1 netns net1 type veth peer name veth2 netns net2

This creates a pair of virtual network interfaces called "veth1" and "veth2", with "veth1" connected to "net1" and "veth2" connected to "net2", using the "ip link add" command.

ip netns exec net1 ip addr add 10.100.0.1/16 dev veth1
ip netns exec net2 ip addr add 10.100.0.2/16 dev veth2

These commands assign IP addresses to both virtual interfaces using the "ip addr add" command.

ip netns exec net1 ip link set lo up
ip netns exec net2 ip link set lo up

These commands bring up the loopback interface in both namespaces using the "ip link set" command.

ip netns exec net2 ip link set veth1 up
ip netns exec net2 ip link set veth2 up

These commands bring up the virtual network interfaces in "net2" using the "ip link set" command.

ip netns exec net1 ping -c 3 10.100.0.2

This command tests connectivity from "net1" to "net2" by pinging the IP address of "veth2" in "net2" using the "ping" command.

ip netns exec net2 ping -c 3 10.100.0.1

This command tests connectivity from "net2" to "net1" by pinging the IP address of "veth1" in "net1" using the "ping" command.

if [ "$1" == "down" ]; then

This checks if the value of the first command-line argument is equal to "down". If it is, the following commands will be executed.

ip netns delete net1
ip netns delete net2

These commands delete the network namespaces "net1" and "net2" using the "ip netns delete" command.

Let's run it

To run this bash script we can make an executable using chmod +x just run it with the bash -c parameter.

As we can see our script ran and we can ping namespaces from one another. We can also get inside these namespaces to see their details.

sudo ip netns exec net1 ip a

This command shows us the interfaces inside the net1 namespace and we can see that net1 has veth1 interface which is assigned the same IP as we did in the script.

Final Thoughts

We have just begun to scratch the surface of Linux and virtual networks. In the upcoming parts, we will see more about docker networks and what is the problem with the above method, and how Linux bridges solve the problem.

Until then keep learning, keep grinding, and keep growing....!!!

Did you find this article valuable?

Support Saurav Rana by becoming a sponsor. Any amount is appreciated!