docker_namespaces_explained
Understanding Docker and Linux Namespaces
This guide explores how Docker utilizes Linux namespaces to provide container isolation. We'll use various command-line tools to inspect and interact with these namespaces.
1. Starting a Test Container
First, let's start a simple Nginx container in detached mode.
sudo docker run -d --name mynginx nginx
# Using '--name mynginx' for easier reference later
sudo docker ps
# Note the Container ID or name ('mynginx') from the output.The question to consider: Can you curl inside this Nginx container from the host at this point without using docker exec or port publishing? (Typically, no, not directly to its container IP without knowing it or specific routing).
2. Inspecting Container Namespaces from the Host
2.1 Get the Container's Process ID (PID)
To inspect a container's namespaces from the host, we first need the PID of the main process running inside the container.
# Replace 'mynginx' with your container's name or ID if different
PID=$(sudo docker inspect --format '{{.State.Pid}}' mynginx)
# Example with a specific ID:
# PID=$(sudo docker inspect --format '{{.State.Pid}}' a8f058d6936c)
echo "The PID of the container's main process on the host is: $PID"
# You can see this process listed in the host's process list
ps aux | grep "$PID"2.2 List Namespaces for the Container's Process
The lsns command can list the namespaces associated with a given PID.
2.3 Find Processes Sharing a Namespace
You can also use pgrep to find all processes (PIDs) that share the same specific namespace as the container's main process. For example, to find all PIDs in the same PID namespace:
3. Entering a Container's Namespaces with nsenter
nsenterThe nsenter command allows you to run commands within one or more of a process's namespaces. This is a powerful way to "enter" a container's environment from the host without using docker exec.
Enter all key namespaces of the container: The following command attempts to enter the mount, UTS (hostname), IPC, network, and PID namespaces of the container.
Once inside the namespace (you'll see a new shell prompt): You are now operating within the container's context. For an Ubuntu/Debian-based container like Nginx, you can try:
Comparison with docker exec:docker exec is the standard Docker way to run commands inside a running container. nsenter is a lower-level Linux tool that achieves a similar result by directly manipulating namespaces.
4. Manipulating Network Namespaces
Let's demonstrate how to create a virtual network interface and move one end into the container's network namespace.
Create a
vethpair on the host: Aveth(virtual Ethernet) pair consists of two connected virtual interfaces.Check the interfaces on the host:
Move one end of the
vethpair into the container's network namespace:The
veth-guestinterface will disappear from the host's interface list and now exist inside the container's network namespace.veth-hostremains on the host.Configure the interface inside the container's namespace using
nsenter: Enter the container's network namespace (and others for full context):Now, from the new shell prompt (inside the namespace):
(Note:
ifconfigis older;ip addr/ip linkfromiproute2are preferred. Addediproute2to the suggested install.)Verify with
docker exec: You can also see the new interface usingdocker exec.
5. Advanced Exercise: Inter-Container Communication via Custom Network (Optional)
This section is for users comfortable with Linux networking. The goal is to enable communication between two containers using manually configured veth pairs and potentially a bridge.
Create a second container.
Create another
vethpair, assign one end to the second container, and give it an IP address (e.g.,10.10.10.11/24) on the same conceptual subnet as the first container'sveth-guest.On the host, configure the host-side ends of the
vethpairs (e.g.,veth-hostfrom the first pair, and the equivalent from the second). You might:Bring up these host interfaces (e.g.,
sudo ip link set veth-host up).Create a Linux bridge on the host (e.g.,
sudo ip link add name mybridge type bridge; sudo ip link set mybridge up).Add the host-side
vethinterfaces to this bridge (e.g.,sudo ip link set veth-host master mybridge).
Ensure IP forwarding is enabled on the host if traffic needs to be routed beyond the bridge:
Configure
iptablesornftablesif necessary, for example, to allow forwarding between the interfaces or to NAT traffic if containers need to reach outside. The original example snippet:(Corrected "mifgt" to "might". Changed
<br>to list items. Clarified iptables rule example.)
This exercise demonstrates the underlying networking primitives that Docker's own networking commands (docker network create, etc.) abstract away.
Last updated