This content originally appeared on DEV Community and was authored by Ajinkya Singh
I’m Building My Own Container Runtime!
This is part of a complete series where I’m building Conti – a container runtime from scratch. Check it out on GitHub!
About This Series:
- I’m sharing everything I learn while building my own container runtime
- Most concepts come from videos, documentation, and LLM-assisted learning (for educational purposes)
- Focus: Understanding through practice – raw Linux commands and practical implementation
- Important: When building your own container, DON’T copy code from sources – it kills the fun! Write it yourself, break things, debug, and learn.
Why Build Your Own?
- Deep understanding of how containers really work
- Master low-level Linux concepts
- Learn by doing, not just reading
- It’s incredibly fun when things finally click!
The Secret Ingredient in Modern Cloud Computing
Have you ever wondered how Docker runs thousands of applications on a single server without them interfering with each other? The answer lies in a powerful Linux kernel feature called namespaces. Let’s dive into this fascinating technology that powers the modern cloud infrastructure.
The Theater Analogy: Understanding Isolation
Imagine a large theater complex called “The Grand Stage” with multiple rehearsal rooms. Here’s the situation:
The Challenge
You have different theater groups sharing the same building:
-
The Rock Band (rehearsing for a concert)
- Members: Mike, Sarah, Tom
- Need: Loud music and energetic space
-
The Drama Club (practicing Shakespeare)
- Members: Emma, Oliver, Sophia
- Need: Quiet, focused environment
-
The Kids’ Puppet Show
- Members: Lucy, Noah, Ava
- Need: Safe, controlled space with supervision
The Problem
Without separation, chaos ensues:
- The rock band’s music drowns out the drama club’s lines
- Kids might wander into the rock band’s rehearsal
- Everyone competes for the same props and equipment
- No privacy or focused practice time
The Solution: Private Rehearsal Rooms
Now imagine the theater manager creates separate rehearsal rooms:
┌─────────────────────────────────────────────┐
│ The Grand Stage Theater │
├─────────────┬───────────────┬───────────────┤
│ Room A │ Room B │ Room C │
│ │ │ │
│ 🎸 Rock │ 🎨 Drama │ 👶 Puppets │
│ Band │ Club │ Show │
│ │ │ │
│ Mike │ Emma │ Lucy │
│ Sarah │ Oliver │ Noah │
│ Tom │ Sophia │ Ava │
│ │ │ │
│ Can only │ Can only │ Can only │
│ see Mike, │ see Emma, │ see Lucy, │
│ Sarah, Tom │ Oliver, │ Noah, Ava │
│ │ Sophia │ │
└─────────────┴───────────────┴───────────────┘
This is exactly what kernel namespaces do for processes in Linux!
What Are Kernel Namespaces?
Kernel namespaces are a Linux kernel feature that creates virtual boundaries around applications and processes, isolating them from each other while running on the same physical system.
Two Meanings of “Namespace”
- The Kernel Feature: The Linux mechanism that enables isolation
- Namespace Instances: Individual isolated environments (like our theater rooms)
Why Namespaces Matter
- Security: Processes can’t interfere with each other
- Resource Control: Each group operates in its own bubble
- Containers: The foundation of Docker, Kubernetes, and modern DevOps
- Multi-tenancy: Run multiple applications safely on one server
Types of Linux Namespaces
Linux provides seven different types of namespaces, each isolating a specific system resource:
Namespace | What It Isolates | Real-World Example |
---|---|---|
PID | Process IDs | Rock band can’t see drama club’s activities |
Network | Network interfaces, IPs, routing | Each room has its own WiFi network |
Mount | Filesystem mount points | Each room has its own storage closet |
UTS | Hostname and domain name | Each room can have its own name tag |
IPC | Inter-process communication | Private message boards per room |
User | User and group IDs | Different permission systems per room |
Cgroup | Control group hierarchy | Different resource quotas per room |
Interactive Demo: PID Namespaces in Action
Let’s see namespaces in action with a hands-on example. We’ll create two isolated environments where processes can’t see each other.
Prerequisites
# Check if you're on Linux
uname -s
# Output should be: Linux
# Verify you have sudo access
sudo whoami
# Output should be: root
Step 1: Observe the Default Behavior
First, let’s see what happens WITHOUT namespaces:
# Create some test processes
echo '#!/bin/bash
while true; do
echo "🎸 Rock band jamming..."
sleep 2
done' > rockband.sh
echo '#!/bin/bash
while true; do
echo "🎨 Drama club rehearsing..."
sleep 2
done' > dramaclub.sh
# Make them executable
chmod +x rockband.sh dramaclub.sh
# Run them in the background
./rockband.sh &
./dramaclub.sh &
# List ALL processes (you'll see EVERYTHING)
ps aux | grep -E 'rockband|dramaclub'
Result: Both processes are visible to everyone on the system!
Step 2: Create Isolated Namespaces
Now, let’s create two separate “rehearsal rooms” using PID namespaces:
Terminal 1: Rock Band Namespace
# Create a new PID namespace
sudo unshare --pid --fork --mount-proc /bin/bash
# Now you're in an isolated namespace!
# Start the rock band process
./rockband.sh &
# List processes - you'll only see THIS namespace
ps aux
# Output:
# USER PID COMMAND
# root 1 /bin/bash
# root 2 ./rockband.sh
# root 3 ps aux
Terminal 2: Drama Club Namespace
# Create another PID namespace (in a new terminal)
sudo unshare --pid --fork --mount-proc /bin/bash
# Start the drama club process
./dramaclub.sh &
# List processes
ps aux
# Output:
# USER PID COMMAND
# root 1 /bin/bash
# root 2 ./dramaclub.sh
# root 3 ps aux
What Just Happened?
Notice something amazing:
- Each namespace thinks it’s PID 1 (the first process)
- Processes can’t see each other across namespaces
- Complete isolation despite running on the same machine
Understanding the unshare
Command
Let’s break down what each flag does:
sudo unshare --pid --fork --mount-proc /bin/bash
-
unshare
: Creates a new namespace (literally “un-shares” from the parent) -
--pid
: Create a PID (Process ID) namespace -
--fork
: Fork a new process in the namespace -
--mount-proc
: Mount a new/proc
filesystem (required for PID isolation) -
/bin/bash
: The command to run inside the namespace
Real-World Application: Docker Under the Hood
When you run docker run
, here’s what happens behind the scenes:
# What you type:
docker run -it ubuntu /bin/bash
# What Docker actually does (simplified):
sudo unshare \
--pid --net --mount --uts --ipc \
--fork --mount-proc \
chroot /var/lib/docker/overlay2/<container-id> \
/bin/bash
Docker combines:
- Namespaces (for isolation)
- Cgroups (for resource limits)
- Union Filesystems (for layering)
- Security (capabilities, SELinux, AppArmor)
Namespace Visibility Matrix
Here’s how different namespace types affect visibility:
From → To | Same Namespace | Different Namespace |
---|---|---|
Process List | ![]() |
![]() |
Network Ports | ![]() |
![]() |
Filesystem | ![]() |
![]() |
Hostname | ![]() |
![]() |
Best Practices and Tips
Do’s
-
Always use
--mount-proc
with PID namespaces - Combine multiple namespace types for complete isolation
- Test in VMs first – namespace operations can affect system behavior
- Use proper error handling in production scripts
- Document your namespace strategy for team understanding
Don’ts
- Don’t nest namespaces excessively – it complicates debugging
- Don’t forget cleanup – orphaned namespaces consume resources
- Don’t skip security – namespaces aren’t a security boundary alone
- Don’t use in production without understanding implications
Key Takeaways
Namespaces provide isolation – processes in different namespaces can’t see or interfere with each other
Seven namespace types – each isolates a different system resource
Foundation of containers – Docker, Kubernetes, and others rely heavily on namespaces
Not just for containers – useful for security, testing, and resource management
Combine with other technologies – cgroups for complete isolation
Conclusion
Kernel namespaces are the invisible heroes of modern computing. Every time you use Docker, Kubernetes, or any containerized application, you’re benefiting from this elegant isolation mechanism.
Now that you understand how they work, you can:
- Debug container issues more effectively
- Design better isolation strategies
- Understand cloud infrastructure at a deeper level
- Build your own containerization tools
This content originally appeared on DEV Community and was authored by Ajinkya Singh