Skip to content

j143/basic-docker-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

basic-docker-engine

A minimal, educational Docker-like container runtime implementation from scratch, focused on demonstrating container internals, monitoring capabilities, and Kubernetes integration.

Project Scope

This is a teaching/runtime prototype designed for:

  • Understanding container isolation mechanisms
  • Demonstrating the Docker monitoring problem
  • Exploring Kubernetes custom resource integration
  • Learning container runtime internals

Not intended for production use. This is a reference implementation for education and research.

Core Features

Container Runtime

  • Container lifecycle management with state tracking (created, running, exited, failed)
  • Automatic cgroup v1/v2 detection and graceful degradation
  • Filesystem isolation with layered image support
  • Process and network namespace isolation (when available)
  • Container logs and metadata persistence

System Monitoring

  • Multi-level monitoring (process, container, host)
  • Gap analysis between isolation levels
  • Correlation tracking across monitoring layers
  • See MONITORING.md for details

Kubernetes Integration

  • ResourceCapsule CRD for enhanced resource modeling
  • Operator for CRD reconciliation
  • GitOps-compatible resource management
  • See KUBERNETES_INTEGRATION.md for details

Prerequisites

  • Linux system (tested on Ubuntu 20.04+)
  • Go 1.24+ for building
  • Root privileges for namespace operations
  • Optional: Kubernetes cluster for CRD features

Build steps

build go code

go build -o basic-docker .
./basic-docker info

Expected output:

Environment detected: inContainer=false, hasNamespacePrivileges=true, hasCgroupAccess=true, cgroupVersion=2
Lean Docker Engine - System Information
=======================================
Go version: go1.24.11
OS/Arch: linux/amd64
Running in container: false
Namespace privileges: true
Cgroup access: true
Cgroup version: v2
Cgroup base path: /sys/fs/cgroup
Memory controller: true
CPU controller: true
Available features:
  - Process isolation: true
  - Network isolation: true
  - Resource limits (memory): true
  - Resource limits (CPU): true
  - Filesystem isolation: true

create necessary folders

sudo mkdir -p /tmp/basic-docker/containers
sudo mkdir -p /tmp/basic-docker/images
sudo mkdir -p /sys/fs/cgroup/memory/basic-docker

Set proper permissions

sudo chmod -R 755 /tmp/basic-docker

Usage

Basic Container Operations

Run a container

# Run a simple command
sudo ./basic-docker run test-image /bin/echo "Hello from container"

# Run an interactive shell (requires image with /bin/sh)
sudo ./basic-docker run test-image /bin/sh

List containers

# Shows all containers with their states
sudo ./basic-docker ps

Example output:

CONTAINER ID         STATE     COMMAND        CREATED
container-1767175530 exited    /bin/echo      2025-12-31 10:05:30
container-1767175600 running   /bin/sleep     2025-12-31 10:06:00

Inspect a container

# Get detailed container information in JSON format
sudo ./basic-docker inspect <container-id>

Example output:

{
  "id": "container-1767175530",
  "state": "exited",
  "image": "test-image",
  "command": "/bin/echo",
  "args": ["Hello from container"],
  "created_at": "2025-12-31T10:05:30Z",
  "started_at": "2025-12-31T10:05:30Z",
  "finished_at": "2025-12-31T10:05:30Z",
  "exit_code": 0,
  "pid": 7505,
  "rootfs_path": "/tmp/basic-docker/containers/container-1767175530/rootfs"
}

View container logs

# Display stdout/stderr from a container
sudo ./basic-docker logs <container-id>

Remove a stopped container

# Clean up container directories and resources
sudo ./basic-docker rm <container-id>

Note: Cannot remove running containers. Stop them first.

System Information

# Display system capabilities and cgroup information
./basic-docker info

This command shows:

  • Cgroup version (v1 or v2) and availability
  • Memory and CPU controller support
  • Namespace privileges
  • Available isolation features

Architecture

flowchart TB
    subgraph "Basic Docker Engine"
        CLI[CLI Interface]
        ENV[Environment Detection]
        CMD[Command Handler]
        
        subgraph "Container Runtime"
            EXEC[Container Execution]
            FS[Filesystem Manager]
            NET[Network Manager]
            RES[Resource Controller]
        end
        
        subgraph "Image Management"
            IMG[Image Store]
            PULL[Image Puller]
        end
        
        subgraph "Isolation Components"
            FULL["Full Isolation\n(Linux Namespaces)"]
            LIMITED["Limited Isolation\n(chroot/unshare)"]
            FALLBACK["Minimal Isolation\n(runWithoutNamespaces)"]
        end
    end
    
    subgraph "Environment Detection"
        DETECT{Environment?}
        PRIV{Privileges?}
        CGROUP{CGroup Access?}
    end
    
    subgraph "Host System"
        LINUX[Linux Kernel]
        CONTAINERS[Container Environment]
    end
    
    %% Main flow
    CLI --> CMD
    CMD --> ENV
    ENV --> DETECT
    
    %% Environment detection flow
    DETECT -->|"Pure Linux"| PRIV
    DETECT -->|"Container"| LIMITED
    
    PRIV -->|"Root"| FULL
    PRIV -->|"Non-root"| LIMITED
    
    ENV --> CGROUP
    CGROUP -->|"Yes"| RES
    CGROUP -->|"No"| EXEC
    
    %% Execution paths
    FULL --> EXEC
    LIMITED --> EXEC
    FALLBACK --> EXEC
    
    %% Container runtime components
    EXEC --> FS
    EXEC -.-> NET
    EXEC -.-> RES
    
    %% Image management
    CMD -.-> IMG
    IMG -.-> PULL
    PULL -.-> FS
    
    %% Host system interactions
    FULL --> LINUX
    LIMITED --> CONTAINERS
    FALLBACK --> CONTAINERS
    
    %% Styling
    classDef primary fill:#d0e0ff,stroke:#3080ff,stroke-width:2px
    classDef secondary fill:#ffe0d0,stroke:#ff8030,stroke-width:2px
    classDef tertiary fill:#d0ffe0,stroke:#30ff80,stroke-width:2px
    classDef highlight fill:#ffff80,stroke:#808000,stroke-width:2px
    
    class CLI,CMD,ENV primary
    class EXEC,FS,NET,RES secondary
    class FULL,LIMITED,FALLBACK tertiary
    class DETECT,PRIV,CGROUP highlight
Loading

Container Lifecycle & State Management

Containers follow a well-defined state model:

created → running → exited
                  ↓
               failed

States

  • created: Container directory structure created, metadata initialized
  • running: Container process is executing
  • exited: Container completed successfully (exit code 0)
  • failed: Container terminated with error (non-zero exit code)

State Persistence

Container state is stored in /tmp/basic-docker/containers/<id>/state.json:

{
  "id": "container-123",
  "state": "exited",
  "image": "alpine",
  "command": "/bin/echo",
  "args": ["hello"],
  "created_at": "2025-12-31T10:00:00Z",
  "started_at": "2025-12-31T10:00:01Z",
  "finished_at": "2025-12-31T10:00:02Z",
  "exit_code": 0,
  "pid": 12345,
  "rootfs_path": "/tmp/basic-docker/containers/container-123/rootfs"
}

Cgroup Support & Resource Limits

The runtime automatically detects and adapts to the available cgroup version:

Cgroup v2 (Unified Hierarchy)

  • Detected via /sys/fs/cgroup/cgroup.controllers
  • Uses memory.max for memory limits
  • Controllers enabled via cgroup.subtree_control

Cgroup v1 (Legacy)

  • Detected via /sys/fs/cgroup/memory subsystem
  • Uses memory.limit_in_bytes for memory limits
  • Separate hierarchy per resource type

Graceful Degradation

When cgroup access is not available or permissions are insufficient:

  • Container still runs without resource limits
  • Warning logged but execution continues
  • info command shows cgroup availability status
  • No fatal errors from missing cgroup support

This ensures the runtime works in various environments (containers, VMs, bare metal) without requiring cgroup permissions.

Image Build Logic

graph TD
    A[Start] --> B[Check if Base Layer Exists]
    B -->|Yes| C[Load Base Layer Metadata]
    B -->|No| D[Create Base Layer]
    D --> E[Initialize Base Layer with Minimal Rootfs]
    E --> F[Save Base Layer Metadata]
    C --> G[Create App Layer]
    G --> H[Add Container-Specific Files to App Layer]
    H --> I[Save App Layer Metadata]
    F --> G
    I --> J[Mount Layers to Create Rootfs]
    J --> K[Run Container with Rootfs]
    K --> L[End]
    
    %% Styling
    classDef startEnd fill:#d0e0ff,stroke:#3080ff,stroke-width:2px
    classDef process fill:#ffe0d0,stroke:#ff8030,stroke-width:2px
    classDef decision fill:#d0ffe0,stroke:#30ff80,stroke-width:2px
    
    class A,L startEnd
    class B decision
    class C,D,E,F,G,H,I,J,K process
Loading

The logic implemented for building images and running containers in the basic Docker engine. It starts by checking if the base layer exists, initializes it if necessary, and then creates an app layer for container-specific files. Finally, the layers are mounted to create the root filesystem, and the container is executed.

Code Structure

Diagram of Classes and Functions

graph TD
    subgraph Image Management
        Image["Image"]
        Registry["Registry Interface"]
        Manifest["Manifest"]
        Pull["Pull Function"]
        ListImages["ListImages Function"]
        ExtractLayer["extractLayer Function"]
    end

    subgraph Main Application
        Main["main Function"]
        ListContainers["listContainers Function"]
        Run["run Function"]
        PrintSystemInfo["printSystemInfo Function"]
        ExecCommand["execCommand Function"]
    end

    Main -->|Delegates| Pull
    Main -->|Delegates| ListImages
    Pull -->|Uses| Registry
    Pull -->|Uses| Manifest
    Pull -->|Calls| ExtractLayer
    ListImages -->|Reads| Image
    Run -->|Creates| Image
    ExecCommand -->|Interacts| Containers
Loading

This diagram provides an overview of the key classes and functions in the project, showing their relationships and responsibilities.

Basic docker prompts

Docker Monitoring System

The basic-docker engine now includes comprehensive monitoring capabilities that address the "Docker monitoring problem" by providing visibility across process, container, and host isolation levels.

Monitor Commands

# Monitor host-level metrics
./basic-docker monitor host

# Monitor specific process
./basic-docker monitor process <PID>

# Monitor specific container
./basic-docker monitor container <container-id>

# Monitor all levels (process, container, host)
./basic-docker monitor all

# Analyze monitoring gaps between isolation levels  
./basic-docker monitor gap

# Show correlation between monitoring levels
./basic-docker monitor correlation <container-id>

Example Output

./basic-docker monitor correlation container-1234

Shows the correlation table as described in the Docker monitoring problem:

Aspect Process Container Host
Spec Source Dockerfile Kickstart
On disk .TEXT /var/lib/docker /
In memory PID Container ID Hostname
In network Socket veth* eth*
Runtime context server core host data center
Isolation moderate private OS view full

See MONITORING.md for detailed documentation.

basic-docker info

/workspaces/basic-docker-engine (main) $ ./basic-docker info
Environment detected: inContainer=true, hasNamespacePrivileges=true, hasCgroupAccess=false
Lean Docker Engine - System Information
=======================================
Go version: go1.24.1
OS/Arch: linux/amd64
Running in container: true
Namespace privileges: true
Cgroup access: false
Available features:
  - Process isolation: true
  - Network isolation: true
  - Resource limits: false
  - Filesystem isolation: true

basic-docker run

/workspaces/basic-docker-engine (main) $ ./basic-docker run /bin/echo "Hello from container"
Environment detected: inContainer=true, hasNamespacePrivileges=true, hasCgroupAccess=false
Starting container container-1743307284
unshare: unshare failed: Operation not permitted
Error: exit status 1
Container container-1743307284 exited

@j143 ➜ /workspaces/basic-docker-engine (main) $ sudo ./basic-docker run /bin/echo "Hello from container"
Environment detected: inContainer=true, hasNamespacePrivileges=true, hasCgroupAccess=true
Starting container container-1743307290
Hello from container
Container container-1743307290 exited

basic-docker ps

@j143 ➜ /workspaces/basic-docker-engine (main) $ sudo ./basic-docker ps
Environment detected: inContainer=true, hasNamespacePrivileges=true, hasCgroupAccess=true
CONTAINER ID    STATUS  COMMAND
container-1743307284    N/A     N/A
container-1743307290    N/A     N/A

basic-docker run /bin/sh

@j143 ➜ /workspaces/basic-docker-engine (main) $ sudo ./basic-docker run /bin/echo "Hello from container"
Environment detected: inContainer=true, hasNamespacePrivileges=true, hasCgroupAccess=true
Starting container container-1743307567
Hello from container
Container container-1743307567 exited

basic-docker run /bin/busybox

@j143 ➜ /workspaces/basic-docker-engine (main) $ sudo ./basic-docker run /bin/busybox echo "Hello from BusyBox"
Environment detected: inContainer=true, hasNamespacePrivileges=true, hasCgroupAccess=false
Starting container container-1744512443
Hello from BusyBox
Container container-1744512443 exited

Verify the prompt functionality

@j143 ➜ /workspaces/basic-docker-engine (main) $ chmod +x verify.sh 
@j143 ➜ /workspaces/basic-docker-engine (main) $ ./verify.sh 
==== System Information ====
Environment detected: inContainer=true, hasNamespacePrivileges=true, hasCgroupAccess=false
Lean Docker Engine - System Information
=======================================
Go version: go1.24.1
OS/Arch: linux/amd64
Running in container: true
Namespace privileges: true
Cgroup access: false
Available features:
  - Process isolation: true
  - Network isolation: true
  - Resource limits: false
  - Filesystem isolation: true
===========================


==== Running Simple Command ====
Environment detected: inContainer=true, hasNamespacePrivileges=true, hasCgroupAccess=true
Starting container container-1743307590
Hello from container
Container container-1743307590 exited


==== Listing Containers ====
Environment detected: inContainer=true, hasNamespacePrivileges=true, hasCgroupAccess=true
CONTAINER ID    STATUS  COMMAND
container-1743307284    N/A     N/A
container-1743307290    N/A     N/A
container-1743307567    N/A     N/A
container-1743307590    N/A     N/A


==== Testing with busybox ====
Environment detected: inContainer=true, hasNamespacePrivileges=true, hasCgroupAccess=true
Starting container container-1743307590
Error: failed to create symlink for sh: symlink busybox /tmp/basic-docker/containers/container-1743307590/rootfs/bin/sh: file exists


==== Skipping isolation tests (needs root) ====


==== All tests completed ====

Test Strategy

Current Testing Status

graph TD
    A[Unit Tests] --> B[Integration Tests]
    B --> C[End-to-End Tests]
    C --> D[Verification Script]

    %% Styling
    classDef process fill:#ffe0d0,stroke:#ff8030,stroke-width:2px

    class A,B,C,D process
Loading
  • Unit Tests: Present in main_test.go and image_test.go.
    • Includes tests for AddResourceCapsule, CapsuleManager, and Docker integration.
    • Benchmarks for capsule and volume access.
  • Integration Tests: Covered partially in verify.sh.
    • Verifies container creation, image listing, and network functionality.
  • End-to-End Tests: Basic functionality tested via verify.sh.
    • Simulates real-world usage scenarios.
  • Verification Script: verify.sh runs additional checks and validations.
    • Includes system information, container commands, and BusyBox tests.

About

Basic docker engine implementation from scratch

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •