π 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!
Understanding Mount Namespaces
We've already covered what namespaces are. Now let's dive deep into mount namespaces - one of the most critical components for container filesystem isolation.
Mount namespaces control which files and directories are visible to processes. They allow each containerized application to have its own view of the filesystem, preventing interference between applications.
The Isolation Problem
Without mount namespaces, all applications share the same filesystem view:
WITHOUT ISOLATION
βββββββββββββββββ
π /
βββ π bin/
βββ π etc/
βββ π var/
βββ π sensitive-data/
βββ webapp-secrets/ β App A can see this
βββ database-config/ β App B can see this
βββ api-keys/ β Everyone can see this
β οΈ Security Risk: All apps see all files
With Mount Namespace Isolation
ββββββββββββββββββββββββ ββββββββββββββββββββββββ
β WebApp Namespace β β Database Namespace β
β β β β
β π / β β π / β
β βββ bin/ β β βββ bin/ β
β βββ lib/ β β βββ lib/ β
β βββ data/ β β βββ data/ β
β βββ webapp/ β β βββ db/ β
β β β β
β β
Isolated view β β β
Isolated view β
ββββββββββββββββββββββββ ββββββββββββββββββββββββ
Understanding Mount Points
Before we go further, let's understand what "mounting" means.
What is Mounting?
Mounting is the process of making a filesystem accessible at a specific point in the directory tree. Think of your Linux system as a tree that can have different "branches" (filesystems) plugged in at various points.
Storage Device to Unified View
STORAGE DEVICE
ββββββββββββββ
ββββββββββ ββββββββββ ββββββββββ
β Part 1 β β Part 2 β β Part 3 β
β (sda1) β β (sda2) β β (sda3) β
β ext4 β β swap β β btrfs β
ββββββββββ ββββββββββ ββββββββββ
β β β
[root] [swap] [home]
Kernel Magic β¨
β
UNIFIED FILE SYSTEM
ββββββββββββββββββ
π / (from sda1)
βββ π bin/
βββ π etc/
βββ π home/ (mounted from sda3)
βββ π var/
βββ π usr/
The kernel stitches together multiple physical storage devices into one seamless directory tree.
Types of Mounts
1. Device Mount
Mounting a physical device or partition:
# Mount a USB drive
mount /dev/sdb1 /mnt/usb
# Mount a disk partition
mount /dev/sda3 /home
2. Bind Mount
Mounting an existing directory to another location - making the same content appear in two places:
# Make /source/project appear at /workspace/active
mount --bind /source/project /workspace/active
Bind Mount Visual:
BEFORE BIND MOUNT:
ββββββββββββββββββ
/project/ /workspace/
βββ src/ βββ temp/
βββ docs/ βββ logs/
βββ README
AFTER: mount --bind /project /workspace/active
ββββββββββββββββββββββββββββββββββββββββββββ
/project/ /workspace/
βββ src/ βββ temp/
βββ docs/ βββ logs/
βββ README βββ active/ β Now shows
βββ src/ project
βββ docs/ content
βββ README
Creating Mount Namespaces
Basic Mount Namespace
# Create new mount namespace
sudo unshare --mount /bin/bash
# Now you're in an isolated mount namespace
# Any mounts you create are invisible outside
mkdir /tmp/isolated
mount --bind /home/user/data /tmp/isolated
# Exit the namespace
exit
# Check from parent - /tmp/isolated won't show the mount
ls /tmp/isolated # Empty or doesn't exist
Why This Matters for Containers
When a container starts, it needs its own filesystem view:
- Container shouldn't see host mounts
- Host shouldn't be affected by container mounts
- Each container has its own
/tmp
,/var
, etc.
Managing Namespaces with nsenter
Now that we understand mount namespaces, how do we interact with processes running inside them? Enter nsenter
.
What is nsenter?
nsenter
(namespace enter) allows you to enter the namespaces of an existing process. It's essential for debugging containers and understanding what's happening inside isolated environments.
Command Structure
nsenter --target <PID> [OPTIONS] <command>
# Common options:
--pid # Enter PID namespace
--mount # Enter mount namespace
--uts # Enter UTS namespace
--net # Enter network namespace
--all # Enter all namespaces
Practical nsenter Examples
Example 1: Viewing Container Processes
# Find the container's main process
ps aux | grep myapp
# Output: 4500 root /usr/bin/myapp
# Enter its PID namespace and list processes
sudo nsenter --target 4500 --pid ps aux
# You'll see only processes inside that namespace
# PID 1 will be the container's init process
Example 2: Inspecting Container Filesystem
# Enter mount namespace to see what's mounted
sudo nsenter --target 4500 --mount df -h
# Or get a shell inside
sudo nsenter --target 4500 --mount /bin/bash
ls / # You see the container's root filesystem
Example 3: Full Container Debug Session
# Enter ALL namespaces of process 4500
sudo nsenter --target 4500 --all /bin/bash
# Now you're fully inside the container
hostname # Container's hostname
ps aux # Container's processes
ip addr # Container's network interfaces
mount # Container's mounts
cat /etc/hosts # Container's host file
# Exit to return to host
exit
Example 4: Resource Monitoring
# Monitor CPU/memory from inside container
sudo nsenter --target 4500 --pid top
# Check disk usage
sudo nsenter --target 4500 --mount du -sh /var/log
# Network connections
sudo nsenter --target 4500 --net netstat -tuln
Complete Isolation Example
Let's create a container-like environment using multiple namespaces:
# Create PID, Mount, and UTS namespaces
sudo unshare --pid --mount --uts --fork /bin/bash
# At this point you're in isolated namespaces
# Set custom hostname (UTS namespace in action)
hostname my-container
hostname # Shows: my-container
# Create isolated mount point
mkdir -p /tmp/container-root/{bin,lib,usr,var,tmp}
# Bind mount necessary directories
mount --bind /bin /tmp/container-root/bin
mount --bind /lib /tmp/container-root/lib
# Change root to our isolated filesystem
chroot /tmp/container-root
# Now you have:
# β
Isolated PID namespace
# β
Isolated mount namespace
# β
Custom hostname
# β
Restricted filesystem view
Entering This Container from Outside
# In another terminal, find the container process
ps aux | grep "my-container"
# Let's say PID is 6000
# Enter all its namespaces
sudo nsenter --target 6000 --all /bin/bash
# You're now inside the container
# Same view as if you were inside originally
Key Concepts Recap
Mount Points
- Mount Point: Directory where a filesystem is attached
- Bind Mount: Making existing directory appear elsewhere
- Root Filesystem: Primary filesystem containing system files
Mount Namespaces
- Provide filesystem isolation
- Allow processes to have different views of directory tree
- Essential for container security
nsenter
- Enters namespaces of running processes
- Critical for debugging containers
- Can enter specific or all namespaces
- Must target a running process PID
Quick Reference Commands
# CREATE MOUNT NAMESPACES
unshare --mount /bin/bash # New mount namespace
unshare --mount --pid --fork /bin/bash # Mount + PID namespaces
# MOUNT OPERATIONS
mount /dev/sdb1 /mnt/usb # Device mount
mount --bind /source /target # Bind mount
umount /mnt/usb # Unmount
# NSENTER - ENTER NAMESPACES
nsenter --target <PID> --mount /bin/bash # Enter mount namespace
nsenter --target <PID> --pid ps aux # Run command in PID namespace
nsenter --target <PID> --all /bin/bash # Enter all namespaces
# VIEW NAMESPACE INFO
lsns # List all namespaces
ls -l /proc/<PID>/ns/ # View process namespaces
readlink /proc/<PID>/ns/mnt # Get mount namespace ID
findmnt # Show mount tree
Why This Matters for Conti
When building your container runtime, mount namespaces and nsenter
are crucial:
- Isolation: Each container needs its own filesystem view
- Security: Prevent containers from accessing host files
- Debugging: Use nsenter to troubleshoot running containers
- Resource Management: Monitor container filesystem usage
- Root Filesystem: Create minimal root filesystems for containers
Building Conti? Star the repo on GitHub and share your progress!
Top comments (0)