Local Docker and Sparse Loopback ext4 Runtime Driver
Source:
docs/enhancements/0007-docker-loopback-runtime/README.md· Status:implemented· Area:core· Milestone:—| Field | Value | | :--- | :--- | | CEP Number |0007| | Title | Local Docker and Sparse Loopbackext4Runtime Driver (pkg/runtime) | | Authors |@cubeplex-arch| | Status |implemented| | Target Version |v0.2.0| | Created |2026-11-10| | Last Updated |2026-11-10|
Summary
Section titled “Summary”This CEP introduces pkg/runtime with a unified Backend interface and two concrete implementations:
LocalProcessBackend(lightweight host-process fallback when Docker is unavailable or for fast unit tests, spawning a realpodddaemon process on a free localhost port per sandbox with persistentrootfs-upper/andworkspace/directories).DockerBackend(spawning real Docker containers with sparserootfs.ext4andworkspace.ext4images, injecting host/opt/cubepod/bin/{podd-init,podd}read-only at/opt/cubepod/bin, and exposingpodd’s:49983port to the Gateway).
Motivation
Section titled “Motivation”In v0.1.0, cubepod-gateway executed commands directly via os/exec in the Gateway process. To make v0.2.0 genuinely usable end-to-end, every sandbox must be backed by a real runtime (pkg/runtime.Backend) that manages persistent storage volumes (rootfs + workspace), runs the Rust podd daemon inside the sandbox, and returns the live podd endpoint URL (http://127.0.0.1:<port> or http://<container-ip>:49983) so the Gateway can proxy all data-plane operations to podd.
- Define
pkg/runtime/runtime.gowith theBackendinterface:EnsureRunning(ctx, SandboxSpec) (*InstanceInfo, error)Pause(ctx, sandboxID) errorResetRootFS(ctx, sandboxID) errorFork(ctx, sourceSandboxID, newSandboxID) (*InstanceInfo, error)Delete(ctx, sandboxID) errorInspect(ctx, sandboxID) (*InstanceInfo, error)
- Implement
pkg/runtime/local_podd.go(PoddProcessBackend):- Allocates persistent per-sandbox
rootfs/andworkspace/directories (plus sparserootfs.ext4andworkspace.ext4image files whenEnableSparseExt4is set). - Spawns the real compiled
bin/poddbinary on a dynamically allocated localhost port (127.0.0.1:<port>), waits forGET /healthto return200 OK, and tracks the daemon PID. - On
Pause, invokesPOST /v1/lifecycle/prepare-stop, terminates thepodddaemon process, and preserves bothrootfs/andworkspace/on disk. - On subsequent
EnsureRunning(Auto-Resume /connect), restartsbin/poddagainst the same persistent directories. - On
ResetRootFS, wipesrootfs/(and recreatesrootfs.ext4) while preservingworkspace/completely intact. - On
Fork, copies bothrootfs/andworkspace/(cp -a --reflink=auto) to the child sandbox ID and launches a newpoddinstance.
- Allocates persistent per-sandbox
- Implement
pkg/runtime/docker.go(DockerBackend):- Creates sparse
rootfs.ext4andworkspace.ext4files on the host, formats them withmkfs.ext4(viapodd-initor hostmkfs.ext4), and runsdocker run -dwith-v <podd-bin-dir>:/opt/cubepod/bin:roand entrypoint/opt/cubepod/bin/podd-init /opt/cubepod/bin/podd.
- Creates sparse
Non-Goals
Section titled “Non-Goals”- Replacing the Kubernetes CRD Operator (
pkg/controller).
Proposal
Section titled “Proposal”Risks and Mitigations
Section titled “Risks and Mitigations”| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
Orphaned podd child processes during test or gateway shutdown |
Medium | Medium | Implement Close() on PoddProcessBackend that cleanly kills all active podd child processes, and send SIGTERM/SIGKILL on Pause and Delete. |
Design Details
Section titled “Design Details”API Changes (pkg/runtime)
Section titled “API Changes (pkg/runtime)”package runtime
type SandboxSpec struct { SandboxID string TemplateID string VolumeKey string RootfsGeneration int64 Image string Env map[string]string}
type InstanceInfo struct { SandboxID string PoddURL string // e.g., "http://127.0.0.1:54321" WorkspaceDir string RootfsDir string PID int ContainerID string}Runtime Behavior (Production Kubernetes vs. Local Development)
Section titled “Runtime Behavior (Production Kubernetes vs. Local Development)”- Production Mode (
Kata + CSI Raw Block): Uses Pod IP:49983provisioned bycubepod-controller. - Local Development Mode (
Docker / PoddProcessBackend): UsesDockerBackendwhen Docker container mode is configured orPoddProcessBackendspawning the real Rustbin/poddbinary directly.
Test Plan
Section titled “Test Plan”- Unit & Integration Tests (
pkg/runtime/runtime_test.go):TestPoddProcessBackend_LifecycleAndPersistence: Launch a sandbox viaPoddProcessBackendusing the realbin/poddbinary (or auto-building it), verify/healthonPoddURL, write a file inworkspaceandrootfs, callPause(verifying thepoddprocess stops), callEnsureRunningagain (Auto-Resume), and verify both files survived!TestPoddProcessBackend_ResetRootFSPreservesWorkspace: CallResetRootFS, verifyrootfsmarker is wiped whileworkspacefile remains intact.TestPoddProcessBackend_CoWFork: CallFork(parent, child), verify child has an independent copy ofrootfsandworkspaceand its own livePoddURL.TestDockerBackend_CommandBuilder: VerifyDockerBackend.BuildRunArgsinjects-v <bin>:/opt/cubepod/bin:ro,--entrypoint /opt/cubepod/bin/podd-init, and sparse image mounts without bakingpoddinto the sandbox image.
Graduation Criteria
Section titled “Graduation Criteria”go test -v -race ./pkg/runtime/...passes all lifecycle, persistence, RootFS reset, and CoW fork tests.
Upgrade / Downgrade Strategy
Section titled “Upgrade / Downgrade Strategy”- New package
pkg/runtime; clean additive interface.
Production Readiness Review (PRR)
Section titled “Production Readiness Review (PRR)”- Observability: Health-checks
GET /healthwith exponential backoff up to 5s when startingpodd. - Security:
DockerBackendmounts/opt/cubepod/binread-only (:ro).
Alternatives Considered
Section titled “Alternatives Considered”- In-process mock execution in Gateway: Rejected for
v0.2.0because it bypassescrates/poddand cannot validate the real wire protocol between Gateway andpodd.