Linux Network Namespace Tutorial: Connecting Two Network Namespaces Using a veth Pair

 Linux Network Namespace Tutorial: Connecting Two Network Namespaces Using a veth Pair

Network Namespaces are one of the core technologies behind Docker, Kubernetes, and container networking. They allow multiple isolated network stacks to coexist on the same Linux system.

In this tutorial, we'll create two network namespaces, connect them using a Virtual Ethernet (veth) pair, assign IP addresses, and verify communication using ping.


What are Network Namespaces?

A Network Namespace provides an isolated networking environment containing its own:

  • Network interfaces

  • Routing table

  • ARP table

  • Firewall rules

  • IP addresses

  • Loopback interface

Think of it as having multiple independent Linux networking environments running on the same kernel.


Lab Environment

Host Network

Host IPs

172.16.1.252/16  --> ens192
192.168.2.252/24 --> ens224

Namespaces to create

testns
prodns

We'll connect them using a veth pair.


Step 1: Create Network Namespaces

Create two isolated namespaces.

ip netns add testns
ip netns add prodns

Verify the namespace.

ip netns exec testns ip link

Output

1: lo: <LOOPBACK> mtu 65536 state DOWN

Notice only the loopback interface exists.


Step 2: View Existing Routes

Check the host routing table.

ip r

Output

default via 192.168.2.1 dev ens224

172.16.0.0/16 dev ens192

192.168.2.0/24 dev ens224

This confirms our host networking before creating namespaces.


Step 3: Create a Virtual Ethernet Pair

Create two virtual interfaces.

ip link add vnix-prodns type veth peer name vnic-testns

Verify.

ip link

Output

vnic-testns
vnix-prodns

A veth pair behaves like a virtual Ethernet cable.

+---------------------------+
|      veth Pair            |
|                           |
| vnix-prodns <-------> vnic-testns |
+---------------------------+

Whatever enters one end exits the other.


Step 4: Move Interfaces into Namespaces

Move each interface into its namespace.

ip link set vnix-prodns netns prodns
ip link set vnic-testns netns testns

Verify.

ip netns exec testns ip link
lo
vnic-testns
ip netns exec prodns ip link
lo
vnix-prodns

Mistake Encountered

Initially the following command was used.

ip link set vnic-prodns netns prodns

Error

Cannot find device "vnic-prodns"

Reason:

The interface was actually named

vnix-prodns

instead of

vnic-prodns

Linux interface names are case-sensitive and spelling-sensitive.


Step 5: Assign IP Addresses

Assign IPs inside each namespace.

Production namespace

ip -n prodns addr add 192.168.2.102/24 dev vnix-prodns

Testing namespace

ip -n testns addr add 192.168.2.103/24 dev vnic-testns

Common Error

Initially the command was executed without specifying the interface.

ip -n prodns addr add 192.168.2.102/24

Linux responded

Not enough information:
"dev" argument is required.

Always specify the device.

Correct command

ip -n prodns addr add 192.168.2.102/24 dev vnix-prodns

Step 6: Bring Interfaces UP

Enable both interfaces.

ip -n testns link set vnic-testns up
ip -n prodns link set vnix-prodns up

Without this step, communication will fail.


Verify Host Interfaces

Notice that after moving the interfaces into namespaces, the host no longer displays them.

ip a

Only

ens192
ens224
lo

remain on the host.

This confirms the interfaces now belong exclusively to the namespaces.


Step 7: Test Connectivity

Ping from prodns to testns

ip netns exec prodns ping 192.168.2.103

Output

64 bytes from 192.168.2.103

64 bytes from 192.168.2.103

64 bytes from 192.168.2.103

Success!


Ping in the opposite direction.

ip netns exec testns ping 192.168.2.102 -c2

Output

64 bytes from 192.168.2.102

64 bytes from 192.168.2.102

Both namespaces can successfully communicate.


Network Topology

                  Linux Host
             +-------------------+
             |                   |
             |                   |
             +-------------------+
                    |
        -------------------------
        |                       |
   Namespace               Namespace
    testns                  prodns
        |                       |
        |                       |
   vnic-testns            vnix-prodns
   192.168.2.103          192.168.2.102
        \_______________________/
              Virtual Ethernet
                 (veth pair)

Complete Commands

# Create namespaces
ip netns add testns
ip netns add prodns

# Create veth pair
ip link add vnix-prodns type veth peer name vnic-testns

# Move interfaces
ip link set vnix-prodns netns prodns
ip link set vnic-testns netns testns

# Configure IP addresses
ip -n prodns addr add 192.168.2.102/24 dev vnix-prodns
ip -n testns addr add 192.168.2.103/24 dev vnic-testns

# Bring interfaces up
ip -n prodns link set vnix-prodns up
ip -n testns link set vnic-testns up

# Test connectivity
ip netns exec prodns ping 192.168.2.103
ip netns exec testns ping 192.168.2.102

Key Takeaways

  • A Network Namespace creates an isolated network environment.

  • A veth pair acts like a virtual Ethernet cable between namespaces.

  • Interfaces must be moved into namespaces using ip link set <interface> netns <namespace>.

  • IP addresses must always be assigned to a specific device (dev option).

  • Interfaces must be brought UP before communication can occur.

  • Once moved, interfaces disappear from the host's network namespace.

  • Connectivity can be verified using ping between namespace IP addresses.


Conclusion

Linux Network Namespaces are a foundational feature for modern container platforms such as Docker, Podman, and Kubernetes. By connecting two namespaces with a veth pair, you've recreated the basic networking model used by containers. Understanding these building blocks makes it much easier to troubleshoot container networking, Kubernetes CNI plugins, and Linux virtual networking in production environments.

No comments:

Post a Comment