Stage 4 · Provision
Container Fundamentals
Linux Namespaces
Learn PID, mount, network, UTS, IPC, and user namespaces behind container isolation.
What Namespaces Do
Namespaces are a Linux kernel feature that partition system resources so that each process sees its own isolated view of the world. A process in a PID namespace only sees processes within that namespace. A process in a network namespace has its own IP address and routing table. This is the foundation of container isolation.
Docker creates a set of namespaces for each container. The container thinks it has its own filesystem, network, process tree, and hostname — but all of this is an illusion created by the kernel's namespace abstraction.
PID Namespace
The PID namespace gives a container its own process ID number space. PID 1 inside the container is the entrypoint process. From the host, that same process has a different PID — typically a large number. This isolation means a container cannot see or signal processes in other containers or on the host.
# Run a container and list its processes
docker run --rm alpine ps aux
# PID 1 inside the container is the entrypoint
# From the host, it appears as a different PID
docker run -d --name demo alpine sleep 3600
docker inspect demo --format '{{.State.Pid}}' # e.g., 123456
# On the host, that PID is visible in ps
ps aux | grep 123456Inside the container, sleep is PID 1. On the host, it has PID 123456. The container cannot see any host processes.
In Linux, PID 1 is the init process. It reaps orphaned zombies and forwards signals. If your container process is not designed to handle these duties, use tini or dumb-init as PID 1 and have your application as a child process.
Mount Namespace
The mount namespace gives each container its own filesystem tree. The container sees its own root filesystem (from the image layers), its own /tmp, /proc, and other mount points. Changes to mounts inside the container do not affect the host or other containers.
# Each container has its own root filesystem
docker run --rm alpine cat /etc/os-release
# Create a file inside a container
docker run --rm alpine sh -c "touch /hello && cat /hello"
# /hello does not exist in the next container
docker run --rm alpine ls /hello # No such file
# Bind mounts bypass mount namespace for specific paths
docker run --rm -v /tmp/test:/data alpine ls /dataMount namespaces ensure filesystem isolation. Bind mounts are a deliberate exception — they expose a host path into the container's mount namespace.
Network Namespace
Each container gets its own network namespace with a unique IP address, routing table, iptables rules, and port range. Two containers can both listen on port 8080 without conflicting. Docker connects container network namespaces via virtual Ethernet pairs and bridge networks.
# Each container gets its own IP
docker run --rm alpine ip addr show eth0
# Two containers can bind the same port
docker run -d --name a -p 8080:80 nginx
docker run -d --name b -p 8081:80 nginx
# From the host, both are accessible on different host ports
curl localhost:8080 # Container A
curl localhost:8081 # Container BNetwork namespaces give each container a full TCP/IP stack. Docker uses port publishing (-p) to map host ports to container ports through iptables NAT rules.
Other Namespaces
Linux provides several additional namespaces that Docker uses for isolation. UTS namespace gives each container its own hostname. IPC namespace isolates System V IPC and POSIX message queues. User namespace maps container users to different host users, providing privilege isolation.
| Namespace | Isolates | Container sees |
|---|---|---|
| PID | Process IDs | Own process tree, PID 1 |
| Mount | Filesystem mounts | Own root filesystem |
| Network | Network stack | Own IP, ports, routing |
| UTS | Hostname | Own hostname |
| IPC | Shared memory, semaphores | Own IPC resources |
| User | User/group IDs | Mapped root (UID 0) |
Inspecting Namespaces
You can inspect the namespaces of a running container by examining its process on the host. This is useful for debugging networking issues or understanding container isolation boundaries.
# Find the container's PID on the host
PID=$(docker inspect --format '{{.State.Pid}}' mycontainer)
# List the namespaces the process is in
ls -la /proc/$PID/ns/
# Compare with the host process
ls -la /proc/self/ns/
# Check network namespace
nsenter -t $PID -n ip addr showEach symlink in /proc/PID/ns/ points to a namespace inode. If two processes share the same namespace, their symlinks point to the same inode.
The nsenter command lets you enter a container's namespaces from the host. nsenter -t PID -n bash gives you a shell in the container's network namespace without running docker exec.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.