Skip to content

feat: opt-in gVisor (runsc) runtime for sandboxes#16

Open
tastyeffectco wants to merge 1 commit into
mainfrom
feat/gvisor-runtime
Open

feat: opt-in gVisor (runsc) runtime for sandboxes#16
tastyeffectco wants to merge 1 commit into
mainfrom
feat/gvisor-runtime

Conversation

@tastyeffectco

Copy link
Copy Markdown
Owner

Closes #3.

What

Opt-in gVisor runtime: set SANDBOXD_RUNTIME=runsc and every sandbox runs under gVisor for stronger per-sandbox kernel isolation. Default is unchanged (runc).

Changes

  • docker.RunSpec.Runtime--runtime on the sandbox docker run.
  • When runsc is enabled, sandboxd writes a resolv.conf (from SANDBOXD_DNS, default 1.1.1.1,8.8.8.8) and bind-mounts it into each sandbox at /etc/resolv.conf. gVisor's netstack can't reach Docker's embedded DNS (127.0.0.11) on a user-defined network, so without this the agent/DNS wouldn't resolve.
  • .env.example + docker-compose.yml knobs; docs/gvisor.md.

Operator requirement (documented)

runsc must be registered with runtimeArgs: ["--host-uds=create"] — sandboxd reaches runtimed over a Unix socket on the workspace bind-mount, and gVisor's gofer only exposes a sandbox-created socket to the host with that flag. Without it, tasks/exec/status fail. Full setup in docs/gvisor.md.

Verified end-to-end (ARM64, no KVM → software platform)

create → runtime=runsc → uname 4.19.0-gvisor
/etc/resolv.conf = 1.1.1.1,8.8.8.8 (bind-mount)
getent github.com → 20.233.83.145 ; curl github → 200

Build + full test suite + gofmt CI all green.

Trade-offs (measured)

Near-parity for serving / HTTP / in-sandbox HMR / CPU / bulk I/O; pnpm install ~1.7×; syscall-heavy microbenchmarks ~4×. Host-side file edits don't trigger HMR under gVisor's gofer (in-sandbox edits do). See docs/gvisor.md.

Opt-in and experimental; zero impact when SANDBOXD_RUNTIME is unset.

Adds SANDBOXD_RUNTIME=runsc to run every sandbox under gVisor for stronger per-sandbox kernel isolation. Opt-in; the default stays runc.

- docker.RunSpec.Runtime -> --runtime
- when runsc is on, write a resolv.conf (SANDBOXD_DNS, default 1.1.1.1,8.8.8.8) and bind-mount it into each sandbox, because gVisor's netstack can't reach Docker's embedded DNS (127.0.0.11) on a user-defined network
- docs/gvisor.md: setup (requires runsc registered with --host-uds=create so the runtimed control socket is reachable from the host), DNS handling, measured trade-offs

Verified end-to-end on ARM64: create -> runtime=runsc -> 4.19.0-gvisor -> DNS resolves -> internet reachable.

Closes #3.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tastyeffectco

Copy link
Copy Markdown
Owner Author

Perf note (gVisor vs runc, measured on this ARM64 host, no KVM)

Platform ops (median, n=3):

op runc gVisor delta
create ~511 ms ~640 ms +130 ms
spin from template ~257 ms ~519 ms +~130–260 ms

The gVisor cost is the sentry/gofer startup added to each docker run (~130 ms). Spin-up stays sub-second.

Runtime workload (from docs/gvisor.md): near-parity for serving, HTTP latency (+~1 ms/req), in-sandbox HMR, CPU (~1.2×), and bulk I/O; pnpm install ~1.7×; syscall/metadata-heavy microbenchmarks ~4×.

Net: a fraction of a second on spin-up and ~1.5–2× on install/build-heavy work — acceptable for an opt-in stronger-isolation tier, and far from the "10× unusable" worst case sometimes cited for gVisor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add gVisor runtime support

1 participant