Container Networking: Part I

Table of contents

My first encounter with container was when I had performed load testing on an application using JMeter. So rather installing JMeter on multiple Virtual Machines (VMs), I ended deploying them on multiple containers on a single VM.

I still remember, I was curious to understand how a container can manage to keep applications isolated. I was interested in understanding networking part specifically.

When I searched, lot of terms coined around. Like veth, bridges, Linux Namespaces, cgroups. I had lot of queries in my mind too.

  • How a network packet traverse from Host to container and vice-versa?

  • How container maintains separate network space for themselves?

  • Post installing docker, I see docker0 device in ip a command output. What is its use?

  • Post creating container, I see eth0@if5 device in container, whereas veth6e6a37e@if4 device on Host. Are they related to docker0 device?

  • And many more…

After a lot of readings (yes, it took me some time), I understood few of the stuff which I would like to share in this blog series.

I assume reader has basic understanding of Linux, Virtualization and Containerization on a high level.

Topics To Cover

I have broken down this blog post in following parts

  1. Part II: Virtual Ethernet

  2. Part III: Network Namespaces and Network Bridges

  3. Part IV: Container (docker, podman, etc) Networking

Setup

We are going to use Vagrant VM on the Ubuntu host with Oracle VirtualBox v7.0. The biggest advantage of using Vagrant VM is it provides a clean slate to play with. One can destroy, create, duplicate, share it very easily.

Here is the Vagrant File

cat <<EOF >> Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
 config.vm.box = "ubuntu/jammy64"
 config.vm.box_version = "20241002.0.0"

 config.vm.synced_folder "./shared-with-vm", "/shared-with-host"
 config.vm.hostname = "cnd" # Container Networking Demo

 config.vm.provider "virtualbox" do |vb|
    # Display the VirtualBox GUI when booting the machine
    # vb.gui = true

    # Customize the amount of memory on the VM:
    vb.memory = "2048"
    vb.cpus = 2
    vb.name = "Container Networking Demo"
  end
end
EOF

Create a directory shared-with-vm in the same location where Vagrantfile resides. This helps to share the data between host and VM

mkdir shared-with-vm

Start the VM and logged into it

vagrant up
vagrant ssh

Install few utilities

vagrant@cnd:~$ sudo apt update
vagrant@cnd:~$ sudo apt install -y net-tools vim curl git tree traceroute make dos2unix bind9-dnsutils tshark ethtool python3 python3-pip python3-scapy iputils-ping iproute2

# Note: you may need to restart few services. Do as it pops up
vagrant@cnd:~$ systemctl restart networkd-dispatcher.service unattended-upgrades.service

Last thing (optional, just to advertise my older blog post :-)), you can set the aliases. I do this way.

agrant@cnd:~$ wget https://raw.githubusercontent.com/simplyatul/bin/master/setaliases.sh
vagrant@cnd:~$ source setaliases.sh

All set, let us jump to Part II.