sandbox-operator

The L3 half of agent sandboxes on Kubernetes: an aggregated apiserver that serves sandboxes.agents.x-k8s.io from live node inventory, the warm-pool driver that fills those nodes, and the e2b-compatible control and data planes in front of them. The Sandbox API itself is kubernetes-sigs/agent-sandbox, consumed as a Go module; this repository stores no copy of it and ships no controller of its own.

What is in the box

Component What it is
cmd/sandbox-apiserver Aggregated apiserver for sandboxes.agents.x-k8s.io/v1beta1: scatter-gather reads, node-local claim/release on create/delete, the pause/resume/fork/snapshot subresources, the optional e2b REST surface, and the in-process SandboxWarmPool driver
cmd/sandbox-envd-proxy The e2b data plane: one public entry point that carries files, commands and pty into a sandbox’s guest port
cmd/sandbox-e2b The e2b surface on a sandboxd mesh with no Kubernetes, with the envd data plane in the same process when asked; see mesh mode
nodeinventories.sandbox.cocoonstack.io The one CRD this repository owns: per-node summary of live sandboxes, warm capacity, promoted templates and the node’s sandboxd address
api/v1beta1 NodeInventory plus the lifecycle subresource payloads
pkg/scale, pkg/sandboxd, pkg/e2bcompat, pkg/e2bbuild, pkg/envdproxy The store, the sandboxd client, the e2b translation layer, its template build executor, the proxy
pkg/scale/kubeinventory, pkg/scale/meshinventory The two inventory sources the store reads: NodeInventory objects through an informer cache, or a sandboxd mesh polled over HTTP

The three paths

any Kubernetes client (kubectl / client-go / controller-runtime)
        |                                        e2b SDK (E2B_API_URL)
        v                                               |
kube-apiserver + agent-sandbox CRDs                     v
        |                                   sandbox-apiserver (aggregated)
        +-- upstream controller -> Pod           |            |
        |     routed by the pod-template         |            +-- e2b REST
        |     contract to a virtual node         |
        v                                        v
   vk-sandbox / vk-cocoon  ------------>  sandboxd node-local warm pools
                                                 ^
                                  sandbox-envd-proxy (files / commands / pty)

The Pod path and the L3 path both end at the same node-local warm pool; they differ in what Kubernetes stores. On the Pod path etcd holds one object per sandbox. On the L3 path it holds one NodeInventory per node and the pool’s intent, so object count is O(pools + nodes) however many sandboxes are live — which is why one SandboxWarmPool patch could take 20 nodes to 50 000 running microVMs while etcd saw ~2 writes/s.

The cost of that design is a list view assembled from inventory nodes republish on a ~30 s cadence: list and watch are eventually consistent. A lookup of one sandbox the inventory does not list yet — by name, by a list or watch pinned to one name in a namespace, or by claim id from the e2b surface and the envd proxy — asks the nodes directly.

Guides

Repository

Source and issue tracker: github.com/cocoonstack/sandbox-operator. Part of the cocoonstack MicroVM platform.