A minimal educational container runtime in C that demonstrates core Linux container technologies: namespaces and cgroups. This project is designed for learning how containers work at the system call level.
This project implements a basic container runtime that shows how tools like Docker and Podman work under the hood. It demonstrates:
- Linux Namespaces: Process isolation (PID, Mount, Network, UTS, IPC)
- Control Groups (cgroups): Resource limitation (CPU, Memory)
- Proper syscall usage:
clone(),mount(),pivot_root(),sethostname() - Educational documentation: Inline comments explaining kernel features
Namespaces provide process isolation by giving each container its own view of system resources:
-
PID Namespace (
CLONE_NEWPID)- Container processes see isolated process tree
- Container's init process has PID 1
- Prevents seeing or signaling host processes
-
Mount Namespace (
CLONE_NEWNS)- Isolated filesystem mount table
- Container can have different filesystem view
- Changes don't affect host mounts
-
Network Namespace (
CLONE_NEWNET)- Separate network stack (interfaces, routing, firewall)
- Container has isolated network configuration
- Can create virtual network devices
-
UTS Namespace (
CLONE_NEWUTS)- Isolated hostname and domain name
- Container can have unique hostname
- Useful for service identification
-
IPC Namespace (
CLONE_NEWIPC)- Isolated inter-process communication
- Separate message queues, semaphores, shared memory
- Prevents IPC interference
Cgroups limit and monitor resource usage:
- Memory Controller: Limit memory usage (prevents OOM on host)
- CPU Controller: Control CPU time allocation (shares/weight)
- cgroups v2: Uses unified hierarchy at
/sys/fs/cgroup
clone() // Create process with new namespaces
mount() // Mount filesystems in container
chroot() // Change root directory
sethostname() // Set container hostname
open/write() // Configure cgroups- Linux kernel 3.8+ (for namespace support)
- GCC compiler
- Make
- Root/sudo access (for namespace operations)
makeThis creates the mini-container executable.
make cleansudo ./mini-container [options] [command] [args...]-h, --help Show help message
-n, --hostname NAME Set container hostname
-r, --root PATH Set root filesystem path
-m, --memory BYTES Set memory limit (bytes)
-c, --cpu SHARES Set CPU shares
--no-pid Disable PID namespace
--no-net Disable network namespace
--no-mount Disable mount namespace
--no-uts Disable UTS namespace
--no-ipc Disable IPC namespace
1. Simple container with shell:
sudo ./mini-container /bin/sh2. Container with custom hostname:
sudo ./mini-container -n mycontainer /bin/bash3. Container with memory limit (10MB):
sudo ./mini-container -m 10485760 /bin/sh4. Container with resource limits:
sudo ./mini-container -n web-container -m 52428800 -c 512 /bin/bash5. Container without network namespace:
sudo ./mini-container --no-net /bin/sh6. Run a command in container:
sudo ./mini-container /bin/echo "Hello from container!"When you run the container:
- Namespace Creation:
clone()creates child process with namespace flags - Cgroup Setup: Process added to cgroup, limits applied
- Filesystem Isolation: Mount namespace provides isolated mount table
- Hostname Setting: UTS namespace allows custom hostname
- Command Execution:
execvp()runs specified command - Cleanup: Cgroups removed after container exits
=== C Mini Container Runtime ===
Educational demonstration of Linux namespaces and cgroups
[NAMESPACE] Enabling PID namespace
[NAMESPACE] Enabling network namespace
[NAMESPACE] Enabling mount namespace
[NAMESPACE] Enabling UTS namespace
[NAMESPACE] Enabling IPC namespace
[CLONE] Creating container process with flags: 0x6f020000
[HOST] Container process created with PID: 12345
[CGROUP] Process 12345 added to cgroup: mini_container
[CGROUP] Memory limit set to 10485760 bytes
[HOST] Waiting for container to exit...
=== Inside Container ===
[NAMESPACE] Container process started (PID: 1)
[UTS] Hostname set to: mycontainer
[MOUNT] Set root mount point to private
[MOUNT] Mounted /proc filesystem
--- Container Environment ---
Hostname: mycontainer
Process ID (in container): 1
Parent PID (in container): 0
----------------------------
[EXEC] Executing: /bin/sh
# (You are now in the container)
Inside container, check PID namespace:
ps aux # Should show only container processes
echo $$ # Should be PID 1 (if PID namespace enabled)Check hostname (UTS namespace):
hostname # Shows container hostnameCheck network namespace:
ip addr # Shows isolated network interfacesCheck cgroup membership:
cat /proc/self/cgroupCheck memory limit (from host):
cat /sys/fs/cgroup/mini_container/memory.maxThis is an educational tool, not production-ready:
- Missing user namespaces (runs as root)
- No seccomp filtering
- No capability dropping
- No SELinux/AppArmor profiles
- Minimal error handling for edge cases
For production use, consider Docker, Podman, or containerd.
.
├── container.h # Header with structures and declarations
├── container.c # Main container logic and namespace handling
├── cgroups.c # Cgroup setup and resource limiting
├── Makefile # Build configuration
└── README.md # This file
To extend the container runtime:
- User Namespace: Add
CLONE_NEWUSERflag - Rootfs Management: Implement proper pivot_root
- Network Setup: Create veth pairs, configure networking
- Image Support: Add OCI image handling
- Seccomp Filters: Add syscall filtering
MIT License - see LICENSE file for details
This is an educational project. Contributions that improve clarity, add documentation, or fix bugs are welcome!
Created to demonstrate Linux container fundamentals through clean, documented C code.