feat(sandbox-adapter): Kubernetes provider built on Agent Sandbox
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 12/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Necesita aclaración
- Estado de actividad
- Activo
- Stack tecnológico
- typescript
- Área
- cloud, devops, infrastructure
Línea de trabajo
The proposed provider would live in packages/sandbox-adapter/src/kubernetes.ts, with docker.test.ts as the model for tests. Read the Docker provider first to see how it runs commands and file operations. Do not start coding yet: the issue asks maintainers to choose between pods/exec, sandboxd and Sandbox Agent, and that decision is still open. Done means the runtime is chosen and the provider's create, connect, suspend and destroy paths are agreed.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
We'd like to contribute a SandboxProvider for Kubernetes, built on Kubernetes Agent Sandbox (SandboxClaim / SandboxTemplate / SandboxWarmPool), at packages/sandbox-adapter/src/kubernetes.ts.
The main thing we need from you is which runtime to implement: how the provider runs commands and file operations inside the sandbox pod. There are three candidates:
pods/exec: the Kubernetes exec API, as the Docker provider usesdocker exec. Nothing extra in the image.sandboxd: Agent Sandbox's own in-pod runtime daemon.- Sandbox Agent: the
sandbox-agentserver running in the pod.
We recommend pods/exec, so that, like the other providers, the sandbox image needs nothing installed. We'll build whichever you prefer. The claim lifecycle (create, connect, suspend, destroy) is the same for all three. Because this provider depends on cluster-side setup, we'd like to agree on the design before writing the tests and docs.
Motivation
- Teams that run their own Kubernetes clusters (for data residency, cost, or GPU access) have no
sandbox-adapterprovider today. Docker covers local development only. - Agent Sandbox is the Kubernetes SIG Apps project for exactly this workload. It reached v1.0 and gives claims, warm pools, per-sandbox Services, managed NetworkPolicies, and suspend/resume. It works with any runtime class, so gVisor (GKE Sandbox) or Kata provide the isolation.
- We're building toward running
piDurable()sessions this way, with the Rivet engine and the sandboxes in the same cluster.
Proposed API
import { agentSandboxProvider } from "@rivet-dev/sandbox-adapter/kubernetes";
export const agent = piDurable({
// ...
sandbox: agentSandboxProvider({
namespace: "sandbox",
warmPool: "coding-agent", // SandboxWarmPool to claim from
cwd: "/workspace",
container: "agent", // container to exec into; defaults to the first
readyTimeoutMs: 300_000, // a cold claim includes node scale-up
suspend: "pod", // "pod" | "none"
claim: { labels, podLabels, volumeClaimTemplates, shutdownAfterSeconds },
kubeConfig, // default: in-cluster ServiceAccount, else ~/.kube/config
}),
});
SandboxProvider |
Implementation |
|---|---|
create |
Create a SandboxClaim whose name is derived from the actor id (DNS-1123 safe). A retried create adopts the existing claim instead of failing. Returns the claim name. |
connect |
Read the claim. Return undefined if it's gone or terminating. If its Sandbox is suspended, set spec.operatingMode: Running. Wait for Ready, then return a Sandbox for the claim's pod. |
suspend |
Set the Sandbox's spec.operatingMode: Suspended. The pod is removed; the Sandbox and its PVCs are kept. |
destroy |
Delete the claim. Agent Sandbox removes the Sandbox, pod, Service and PVCs. |
The runtime options
Option 1 (recommended): pods/exec
The Sandbox operations run through the Kubernetes exec API (@kubernetes/client-node's Exec), the same way the Docker provider uses docker exec:
execruns/bin/sh -c, with the working directory, environment and command passed as positional arguments rather than interpolated into the script. It streams stdout and stderr toonDataand reads the exit code from the exec status channel.- Each command starts in its own process group and records its PID in the sandbox. Abort and timeout kill that group explicitly with a second exec. The provider doesn't rely on a closed exec stream killing the process: with non-TTY exec, Kubernetes can leave it running after the client disconnects. On
connect, the provider kills any group left over from a previous actor generation, so a resumed run never shares the workspace with an orphaned command. readFilestreamscat.writeFilepipes content through stdin.mkdir,stat,readdirandexistsusemkdir -p,testand a POSIX-sh directory listing, as the Docker provider does.
The only image requirement is /bin/sh with cat and mkdir. Exec goes through the API server, so every command is authenticated, authorized and audit-logged by Kubernetes. It also works on gVisor and Kata pods, where port-forwarding does not.
Options 2 and 3: sandboxd or Sandbox Agent
Both connect directly to the pod through the per-sandbox Service (status.serviceFQDN), so the API server is off the data path. They require a daemon in the sandbox image.
Comparison
1. pods/exec (recommended) |
2. sandboxd |
3. Sandbox Agent | |
|---|---|---|---|
| Image requirement | /bin/sh |
sandboxd as the container's process |
sandbox-agent server as the container's process |
| Data path | API server → kubelet | Direct to the pod (REST :8080, gRPC :9090) |
Direct to the pod (HTTP :2468) |
| Access control | Kubernetes RBAC (pods/exec), audited |
NetworkPolicy only; no authentication in its in-cluster modes | NetworkPolicy plus a bearer token |
| Command when the connection drops | Keeps running; the provider kills it explicitly | SIGKILLed with its process group (per its user guide) | Keeps running; output is re-read by sequence, so a long command survives a network blip |
| Client in TypeScript | @kubernetes/client-node |
gRPC + REST (Agent Sandbox's TypeScript client isn't published yet) | HTTP + JSON; exec uses runRemoteProcess |
sandboxdis Agent Sandbox's standard runtime (KEP-539.2). It suits clusters that want the direct path and already lock sandbox ingress down with NetworkPolicy.- Sandbox Agent suits teams already using it in their sandboxes. It's also the most tolerant of long commands over unreliable connections.
Whichever you choose, we'd keep the runtime behind an internal interface, so another one could be added later behind a runtime option without changing the provider's API.
What we've verified
Tested on GKE 1.36 with a GKE Sandbox (gVisor) node pool and Agent Sandbox v1.0.7:
- Exec works on gVisor sandbox pods through the Kubernetes API (
kubectl exec), including running commands and reading files. - Suspend and resume. Patching the Sandbox to
Suspendedremoved the pod in about 4 seconds, and the claim reportedReady=False (SandboxSuspended). The claim controller didn't revert the patch. Resuming took about 9 seconds with a node already available. With a PVC from the template'svolumeClaimTemplates, the workspace survived. With anemptyDirit was wiped, sosuspendneeds a persistent workspace volume. - Cleanup. Deleting the claim removed the Sandbox, pod, Service and PVC.
- Cold start. A claim from an empty warm pool, including a node scale-up from zero, was ready in about 2 minutes.
- Sandbox Agent runtime (0.5.3): processes survive the client disconnecting. Client A started a 40-second process, followed its logs to sequence 6, and disconnected. Client B, from another pod, found it still
running15 seconds later.logs?since=6returned 7, 8, 9…, all 40 entries were contiguous, andexitCodewas reported.
Still to verify before the PR:
- Exec from an in-cluster ServiceAccount with namespace-scoped RBAC.
- Whether a dropped exec connection kills the process under runc and gVisor, which determines how much the explicit kill matters.
- Binary-safe
writeFileand largereadFileround-trips.
Cluster requirements (would go in the docs)
- Agent Sandbox v1.0+ with the extensions (
SandboxClaim,SandboxTemplate,SandboxWarmPool). - A
SandboxTemplateandSandboxWarmPool. Forsuspend, the template also needs avolumeClaimTemplatesentry mounted at the workspace. - RBAC for the actor's ServiceAccount in the sandbox namespace:
sandboxclaims: create, get, list, watch, patch, delete;sandboxes: get, watch, patch;- with
pods/exec:podsget andpods/execcreate.
- With
sandboxdor Sandbox Agent:service: trueon the template, the daemon in the sandbox image, and a NetworkPolicy (through the template'snetworkPolicy) that admits the actor's namespace on the daemon's ports.
We'd include example YAML for all of the above. The runtime class (gVisor, Kata or the default) is left to the user.
Tests
- Unit tests against a fake Kubernetes API, plus a fake exec stream or a fake runtime server depending on the chosen runtime, like
docker.test.ts. - An integration test against a kind cluster with Agent Sandbox installed and the default runtime class. Happy to wire it into CI, or keep it opt-in, whichever you prefer.
Questions for maintainers
- Which runtime should we implement:
pods/exec,sandboxd, or Sandbox Agent? We recommendpods/exec, but this is your call, and it's the one answer we need before starting. - Should the export be
./kubernetesor./agent-sandbox? - Is
@kubernetes/client-nodeacceptable as an optional peer dependency? suspendon a template without a workspace PVC: should it refuse, warn, or silently delete the pod?- Should the kind integration test run in CI?
If the direction looks right, we'll open the PR with the provider, tests, a section in docs/content/docs/sandboxes.mdx, and an example under examples/docs/sandboxes/.
- Lenguaje dominante
- TypeScript
- Estrellas
- 1.6k
- Forks
- 135
- Merge medio
- 12 h 27 min
- PR fusionados (30 d)
- 52
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de rivet-dev/agents
-
Add Upstash Box sandbox providerAbiertoenhancement
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
rivet-dev/agents#371 · 2 comentarios · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 68/100
rivet-dev/agents#370 · 2 comentarios · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
skills add rivet-dev/skills -s sandbox-agent fails: the skill was removed from rivet-dev/skillsAbierto
Dificultad 3/5 1-2 días Aptitud para principiantes 68/100
rivet-dev/agents#319 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
High-level SDK cannot authenticate current ACP adapters with dynamic auth methodsPosiblemente ocupada @gauravch-code la tomó hace 16 días. Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
rivet-dev/agents#313 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
Los mantenedores suelen responder en 1 día
Todos los issues de rivet-dev/agents
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 67/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 79/100
Los mantenedores suelen responder en 1 día
-
Invalid-link error for static location apps shows HTML-escaped sample URL (`/`)Posiblemente ocupada @cgmuniz la tomó hoy. Abierto🐛 bug
Dificultad 1/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 2 días
-
apps/stage-web bug env/os-linux pending triage scope/audio-output
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día