Skip to content

matintohidi/gocker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

9 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Gocker Logo

๐Ÿณ Gocker

A simple yet powerful container runtime written in Go, demonstrating Linux namespaces and container isolation.

Gocker is a lightweight container runtime that shows how Docker-like containers work under the hood. It uses Linux namespaces, chroot, and filesystem isolation to run processes in isolated environments.

โœจ Features

  • ๐Ÿ—๏ธ Image-based architecture - Pull and manage base images (Alpine Linux)
  • ๐Ÿ”’ Process isolation - PID namespace (every container sees itself as PID 1)
  • ๐Ÿ  Hostname isolation - UTS namespace (custom hostname per container)
  • ๐Ÿ“ Filesystem isolation - Mount namespace + chroot
  • ๐Ÿ†” Unique container IDs - Docker-style container identification
  • ๐Ÿš€ Simple CLI - Easy-to-use Docker-inspired commands
  • ๐Ÿ“ฆ Portable - All data stored in ~/.gocker (no hardcoded paths)
  • ๐ŸŽฏ OverlayFS support - Efficient layered filesystem (automatic detection)
  • ๐ŸŒ Network isolation - Network namespace for container networking

๐Ÿ—๏ธ Architecture

~/.gocker/
โ”œโ”€โ”€ images/
โ”‚   โ””โ”€โ”€ alpine/
โ”‚       โ””โ”€โ”€ rootfs/           # Base Alpine Linux filesystem (shared)
โ”œโ”€โ”€ containers/
โ”‚   โ”œโ”€โ”€ <container-id-1>/
โ”‚   โ”‚   โ””โ”€โ”€ rootfs/           # Container 1's isolated filesystem
โ”‚   โ”œโ”€โ”€ <container-id-2>/
โ”‚   โ”‚   โ””โ”€โ”€ ...
โ”‚   โ””โ”€โ”€ ...
โ””โ”€โ”€ metadata/

OverlayFS Mode (Recommended):

  • Base image is mounted as read-only lower layer
  • Container changes are written to the upper layer
  • Fast container creation (no copying needed)
  • Space-efficient (changes only stored once)

Fallback Mode:

  • Full filesystem copy for each container
  • Works on any Linux system
  • More disk space usage but simpler

๐Ÿš€ Quick Start

1. Build

go build -o gocker

2. Initialize

# Download Alpine base image and set up directory structure
./gocker init

This will:

  • Create ~/.gocker directory structure
  • Download Alpine Linux minirootfs (~3MB)
  • Extract it to ~/.gocker/images/alpine/rootfs

3. Run containers

# Run a shell
./gocker run alpine /bin/sh

# Run a command
./gocker run alpine /bin/ls -la /

# Check container hostname
./gocker run alpine /bin/hostname

# View processes (PID isolation)
./gocker run alpine /bin/ps aux

# Check OS version
./gocker run alpine /bin/cat /etc/os-release

๐Ÿ“š Commands

gocker init

Initialize gocker environment by creating directory structure and downloading the Alpine base image.

./gocker init

gocker run [image] [command] [args...]

Run a command in a new container.

./gocker run alpine /bin/sh
./gocker run alpine /bin/ls -la /
./gocker run alpine /bin/ps aux

# Disable OverlayFS (use filesystem copy instead)
./gocker run --no-overlay alpine /bin/sh

# Disable network namespace isolation
./gocker run --no-network alpine /bin/sh

Arguments:

  • image - Image name (currently only alpine is supported)
  • command - Command to execute inside the container
  • args... - Arguments for the command

Flags:

  • --no-overlay - Disable OverlayFS and use full filesystem copy
  • --no-network - Disable network namespace isolation

๐Ÿ”ง How It Works

1. Initialization (gocker init)

  • Creates ~/.gocker directory structure
  • Downloads Alpine Linux minirootfs from official CDN
  • Extracts it to ~/.gocker/images/alpine/rootfs

2. Container Creation (gocker run)

  1. Verify image exists - Check if the base image is available
  2. Generate container ID - Create a unique 12-character identifier
  3. Setup filesystem:
    • OverlayFS mode (default) - Mount overlay with base image as lower layer
    • Fallback mode - Copy base image to container-specific directory
  4. Create namespaces - Fork process with isolated namespaces:
    • PID namespace - Process isolation (container sees itself as PID 1)
    • UTS namespace - Hostname isolation
    • Mount namespace - Filesystem mount isolation
    • User namespace - User/UID mapping (allows unprivileged containers)
    • Network namespace - Network isolation (if enabled)
  5. Setup UID/GID mapping - Map container root (UID 0) to host user
  6. Setup environment:
    • chroot into container filesystem
    • Mount /proc filesystem
    • Set custom hostname
  7. Execute command - Run the requested command
  8. Cleanup - Unmount /proc and exit

3. Linux Namespaces Used

Namespace Purpose Example
PID Process ID isolation Container sees only its own processes (PID 1)
UTS Hostname isolation Container has its own hostname (gocker-container)
Mount Filesystem mount isolation Container has its own mount table
User User/UID isolation Maps container root (UID 0) to host user (unprivileged)
Network Network isolation Container has its own network stack (optional)

๐Ÿ” Technical Details

Directory Structure

// Paths in ~/.gocker/
type Paths struct {
    Root       string  // ~/.gocker
    Images     string  // ~/.gocker/images
    Containers string  // ~/.gocker/containers
    Metadata   string  // ~/.gocker/metadata
}

Container Lifecycle

User runs: gocker run alpine /bin/sh
    โ†“
1. Check if gocker initialized
    โ†“
2. Verify alpine image exists
    โ†“
3. Generate container ID (e.g., a8317726)
    โ†“
4. Copy image rootfs โ†’ container rootfs
   (~/.gocker/images/alpine/rootfs โ†’ ~/.gocker/containers/a8317726/rootfs)
    โ†“
5. Create parent process with namespaces (PID, UTS, Mount, User)
    โ†“
6. Setup UID/GID mapping (container UID 0 โ†’ host UID)
    โ†“
7. Fork child process (PID 1 in new namespace)
    โ†“
8. Child: chroot + mount /proc + set hostname + exec /bin/sh
    โ†“
9. User interacts with container
    โ†“
10. Exit โ†’ cleanup /proc โ†’ done

System Calls Used

  • syscall.Sethostname() - Set container hostname
  • syscall.Chroot() - Change root directory
  • syscall.Chdir() - Change working directory
  • syscall.Mount() - Mount /proc filesystem
  • syscall.Unmount() - Unmount /proc on exit
  • syscall.CLONE_NEWUSER - Create new user namespace (enables unprivileged containers)
  • syscall.CLONE_NEWPID - Create new PID namespace
  • syscall.CLONE_NEWUTS - Create new UTS namespace
  • syscall.CLONE_NEWNS - Create new mount namespace

๐Ÿ“ Project Structure

gocker/
โ”œโ”€โ”€ cmd/
โ”‚   โ”œโ”€โ”€ root.go          # Root cobra command
โ”‚   โ”œโ”€โ”€ init.go          # Initialize gocker
โ”‚   โ”œโ”€โ”€ run.go           # Run containers
โ”‚   โ””โ”€โ”€ child.go         # Internal child process handler
โ”œโ”€โ”€ internal/
โ”‚   โ”œโ”€โ”€ paths/
โ”‚   โ”‚   โ””โ”€โ”€ paths.go     # Path management
โ”‚   โ”œโ”€โ”€ image/
โ”‚   โ”‚   โ””โ”€โ”€ image.go     # Image download & management
โ”‚   โ”œโ”€โ”€ containerops/
โ”‚   โ”‚   โ””โ”€โ”€ container.go # Container creation & execution
โ”‚   โ””โ”€โ”€ container/
โ”‚       โ””โ”€โ”€ container.go # Legacy container operations
โ”œโ”€โ”€ main.go              # Entry point
โ”œโ”€โ”€ go.mod               # Dependencies
โ””โ”€โ”€ README.md            # This file

๐ŸŽฏ Design Decisions

Why copy-on-create instead of OverlayFS?

For educational purposes and simplicity:

  • โœ… Easy to understand - Direct filesystem copy is conceptually simple
  • โœ… No kernel dependencies - Works on any Linux system
  • โœ… Complete isolation - Each container has its own filesystem
  • โš ๏ธ Trade-off - Uses more disk space and slower to create

Future improvement: Implement OverlayFS for Docker-like layered filesystem.

Why ~/.gocker directory?

  • โœ… Portable - No hardcoded paths
  • โœ… User-specific - Each user has their own containers
  • โœ… No root filesystem pollution - Clean separation
  • โœ… Easy cleanup - Just remove ~/.gocker

๐Ÿงช Examples

Example 1: Interactive Shell

$ ./gocker run alpine /bin/sh
Container bf116791 created successfully
๐Ÿณ Container ID: bf116791
Running command in container: [/bin/sh]
Starting container (PID: 1)
/ # hostname
gocker-container
/ # ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 /proc/self/exe child --rootfs ...
    8 root      0:00 /bin/sh
   14 root      0:00 ps aux
/ # exit
โœ… Container bf116791 finished

Example 2: List Files

$ ./gocker run alpine /bin/ls -la /
Container d8ac5809 created successfully
๐Ÿณ Container ID: d8ac5809
Running command in container: [/bin/ls -la /]
Starting container (PID: 1)
total 72
drwxr-xr-x   19 1000     1000          4096 Jan  2 15:22 .
drwxr-xr-x   19 1000     1000          4096 Jan  2 15:22 ..
drwxr-xr-x    2 1000     1000          4096 Jan  2 15:22 bin
drwxr-xr-x    2 1000     1000          4096 Jan  2 15:22 dev
...
โœ… Container d8ac5809 finished

Example 3: Check OS Version

$ ./gocker run alpine /bin/cat /etc/os-release
Container 94e0358a created successfully
๐Ÿณ Container ID: 94e0358a
Running command in container: [/bin/cat /etc/os-release]
Starting container (PID: 1)
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.19.0
PRETTY_NAME="Alpine Linux v3.19"
โœ… Container 94e0358a finished

๐Ÿ› ๏ธ Requirements

  • OS: Linux (kernel 3.8+)
  • Go: 1.21 or higher

๐Ÿšง Limitations

  • Only Alpine Linux is supported as base image
  • No network namespace isolation (yet)
  • No cgroups resource limiting (yet)
  • No container persistence/restart
  • No overlay filesystem (uses full copy)

๐Ÿ”ฎ Future Improvements

  • OverlayFS support for efficient storage
  • Network namespace isolation
  • Cgroups for resource limiting (CPU, memory)
  • Container lifecycle management (start/stop/rm)
  • Support for custom images
  • Volume mounting
  • Environment variable passing

๐Ÿ“– Learning Resources

This project demonstrates:

  • Linux namespaces (PID, UTS, Mount, User, Network)
  • User/UID mapping for unprivileged containers
  • Process isolation techniques
  • chroot jails
  • OverlayFS and layered filesystems
  • Network namespace isolation
  • Copy-on-Write filesystems
  • Filesystem management
  • Go system programming
  • CLI design with Cobra and flags

๐Ÿค Contributing

This is an educational project. Feel free to:

  • Add new features
  • Improve documentation
  • Fix bugs
  • Add tests

๐Ÿ“ License

MIT License - See LICENSE file for details

๐Ÿ™ Acknowledgments

  • Inspired by Docker and container runtimes
  • Uses Alpine Linux minirootfs
  • Built with Cobra CLI framework

Made with โค๏ธ for learning how containers work

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages