Network Namespaces (Virtual Network)
Luke Hebert
- 3 minutes read - 583 wordsNetwork namespaces are the building block behind every container network you have ever used. Once you understand how to create, link, and route them by hand, the abstractions in Docker and Kubernetes stop feeling like magic. The sections below walk through listing, adding, and deleting namespaces, inspecting interfaces and routes, creating point-to-point links, bridging for virtual switching, NAT and port forwarding, and how Docker and Kubernetes each layer on top of these primitives.
Much like container namespaces that isolate containers from the host operating system, Docker and Kubernetes containers also have network isolation by way of network namespaces. These namespaces provide isolation for the container from other containers connected to the same network on the host. Each namespace will also typically have its own network interface.
List Network Namespaces
ip netnsAdd a Namespace
ip netns add <name>Delete a Namespace
ip netns del <name>List Interfaces in a Namespace
On a host operating system you might use ip link or ip a to list the interfaces and their addresses. To do the same within a namespace, use the following command.
ip netns exec <namespace> ip link
ip -n <namespace> linkList ARP
ip netns exec <namespace> arpList Routes
ip netns exec <namespace> routeCreating Links Between Namespaces
ip link add veth-<namespace> type veth peer name veth-<peernamespace>
ip link set veth-<namespace> netns <namespace>
ip -n <namespace> addr add 192.168.15.1 dev veth-<namespace>ip link set veth-<peernamespace> netns <peernamespace>
ip -n <peernamespace> addr add 192.168.15.2 dev veth-<peernamespace>ip -n <namespace> link set veth-<namespace> up
ip -n <peernamespace> link set veth-<peernamespace> upVirtual Switching and Traffic Routing
To create an internal network on the host, you can use various solutions such as Open vSwitch or native Linux bridging. In the context of a virtual network, at a very simple level, you would connect all of the virtual interfaces to the bridge using “virtual cables.”
ip link add veth-<namespace> type veth peer name veth-<namespace>-br
ip link set veth-<namespace> netns <namespace>
ip link set veth-<namespace>-br master v-net-0
ip -n <namespace> addr add 192.168.15.2 dev veth-<namespace>
ip -n <namespace> link set veth-<namespace> upTo access the bridged network, you would need to assign an IP address to the bridge.
ip addr add 192.168.15.5/24 dev veth-net-0To access the outside world, each namespace would need a route through a gateway, for example, and you will need NAT.
ip netns exec <namespace> ip route add 192.168.1.0/24 via 192.168.15.5
iptables -t nat -A POSTROUTING -s 192.168.15.0/24 -j MASQUERADETo reach the internet from the namespace, you would add a default route through your host.
ip netns exec <namespace> ip route add default via 192.168.15.5To make the host accessible for incoming traffic, you can use port forwarding. The rule below forwards traffic arriving at the host on port 80 to the IP address assigned to the particular interface in that namespace.
iptables -t nat -A PREROUTING --dport 80 --to-destination 192.168.15.2 -j DNATDocker Bridge Network (CNM)
Docker uses a similar method for bridge networking. You can find the network namespace by inspecting the container. In the output, you will find a SandboxID. The namespace name is generally the first 12 characters of this ID. This is also visible in the SandboxKey.
Kubernetes (CNI)
Kubernetes uses a pluggable model that follows a standard approach. It essentially creates containers using the none network, then manually invokes the CNI plugin, which takes care of the rest of the configuration.