
OpenShell on Kubernetes: A guide for platform engineers
What OpenShell is AI agents do more than call APIs. They run shells, install packages, read files, and open network connections. Often they act on text they pulled from the internet a minute earlier. So every...
以下正文同步自 CNCF Blog,版权归原站所有,已转换为易读排版。
What OpenShell is
AI agents do more than call APIs. They run shells, install packages, read files, and open network connections. Often they act on text they pulled from the internet a minute earlier. So every agent is untrusted code that holds real credentials. OpenShell, started by NVIDIA and now a CNCF Sandbox project, is a runtime for running agents like this safely. OpenShell runs each agent in a sandbox. A trusted supervisor outside the sandbox decides what the agent may reach. You declare four kinds of control in YAML:
- Filesystem: Landlock limits which paths the agent can read or write. In the demo, /usr, /etc, and a few other paths are read-only, and only /sandbox, /tmp, and /dev/null are writable.
- Process: before the agent starts, the sandbox runtime drops it to a non-root user with no capabilities and applies seccomp.
- Network: outbound traffic is denied by default. Rules can allow traffic per binary, host, port, and HTTP method.
- Credentials: the agent sees only a placeholder for each API key. The supervisor swaps in the real key, and only for endpoints the provider allows. For Kubernetes admins, a key point is that OpenShell does not bring its own scheduler. Its Kubernetes backend uses Agent Sandbox, the agents.x-k8s.io Sandbox resource from SIG Apps. Agents show up as Pods, Services, PVCs, Secrets, and NetworkPolicies, which you already know how to run. OpenShell adds what Kubernetes can’t see: which agent is calling, which binary made the request, and whether a given POST may leave the cluster. A NetworkPolicy can say “this Pod may reach api.github.com on 443.” It cannot say “curl may read issues but not create them.” OpenShell can, and it can change that rule on a running sandbox without a restart.
How a sandbox is created and run
On Kubernetes, the OpenShell gateway owns every sandbox, and Agent Sandbox turns each one into Pods. The nirmata/demo-openshell repo runs the whole flow on a two-node kind cluster with Kubernetes 1.35, Cilium 1.20, Agent Sandbox v1.0.5, OpenShell 0.1.3, and Kyverno 1.18.2. Its openshell-sandbox-lifecycle.md file describes each step in detail. Note 1: Currently, OpenShell sandboxes can only be created by calling the Gateway API and not via the Kubernetes API. There is an open issue (openshell/#1719) for a Kubernetes OpenShellSandbox CRD, and an operator. Note 2: a Supervisor Pod per agent provides strong isolation, but may not scale well in large environments. The roadmap includes flexible deployment options (see RFC 0018).
OpenShell on Kubernetes · control path and data path
The gateway creates the Kubernetes objects, and Agent Sandbox creates the agent Pod. The agent Pod has no outbound network access of its own. The supervisor opens the only connection to it, and every request the agent makes goes back over that connection for a policy check. Kyverno checks the Kubernetes objects at admission.
- Prepare the cluster. Install a CNI that enforces both ingress and egress NetworkPolicy. The demo replaces kindnet with Cilium. Then install the Agent Sandbox controller and CRDs, and then the OpenShell gateway Helm chart.
- Create a sandbox. openshell sandbox create –workspace demo –name policy-demo –from nicolaka/netshoot@sha256:… –no-auto-providers sends the request to the gateway over mTLS. Clients never talk to the Kubernetes API. A workspace, here demo, groups sandboxes, policy, and logs.
- The gateway checks and records the request. It authenticates the caller, resolves the image, policy, providers, and resources, and rejects unsafe settings. It then saves a sandbox record in the Provisioning phase. This record, not the Pod, is the source of truth.
- Network policies come first. The Kubernetes driver creates two NetworkPolicies in the namespace, or checks them if they already exist. One covers workload Pods: no outbound traffic at all, and inbound traffic only from supervisors on TCP 5500. The other covers supervisor Pods. Only then does the driver create the Sandbox resource, in a suspended state.
- Agent Sandbox creates the workload. The controller creates the workload Pod and a PVC for /sandbox. A scheduling gate holds the Pod back.
- OpenShell checks the admitted Pod. After admission, the driver reads the Pod back. It checks for a non-root UID and GID, no added capabilities, RuntimeDefault seccomp, no host namespaces, no ServiceAccount token, and the expected labels and volumes. If an admission webhook changed any of these, creation fails.
- The supervisor is created. The driver creates a supervisor Pod, a Service in front of the workload Pod’s port 5500, TLS and bootstrap Secrets for this sandbox, and a short-lived token for the supervisor. The workload never gets gateway credentials. Then the scheduling gates come off.
- The supervisor connects. The supervisor authenticates to the gateway with an identity tied to the namespace, the Sandbox UID, its own Pod UID, and the runtime generation. It receives the policy and connects to the workload through the Service. Inside the workload, the sandbox runtime applies the filesystem, process, socket, and DNS controls. The agent’s command does not start until these controls are confirmed.
- Run and update. Each outbound request from the agent goes to the supervisor, which checks the destination, port, calling binary, and HTTP request before it opens the upstream connection. Exec, SSH, logs, and file sync also go through the supervisor. openshell policy update loads a new policy version and waits for the sandbox to confirm it, without a restart. In the demo, curl starts out blocked. After the update it can be read from api.github.com, but a POST to /issues returns policy_denied. openshell logs policy-demo –source sandbox shows each allowed and denied request.
- Stop, start, and delete. Stopping suspends the Sandbox and removes the workload Pod, but keeps the PVC. Starting creates a new runtime generation and runs the Pod checks again. Deleting removes the Sandbox, and owner references clean up its Pods, Service, Secrets, and PVC. The two namespace NetworkPolicies stay. If creation fails partway, the driver rolls back. OpenShell checks only the Pod settings it needs to stay safe. Which images run, how big a sandbox can get, which credentials it gets, and who can change OpenShell’s RBAC are left to the platform team.
OpenShell vs. Agent Substrate
Agent Substrate is another CNCF project that provides sandboxed execution for agents. Both projects applied, and were accepted, to the CNCF Sandbox in September, 2026 (#522 and #523). Both run each agent in its own sandbox on Kubernetes, but they are built differently. OpenShell uses the SIG Apps Agent Sandbox project. Substrate has its own scheduler, controller, and sandbox runtime. Lin Sun’s CNCF post, Why sandboxing your agent is not enough, makes the case for Substrate: “Sandboxing your agents is necessary, but not sufficient.” Agent Sandbox is about running agents securely. Substrate is about running them securely and cheaply at scale, by suspending idle agents instead of giving each one a Pod. Agent Substrate is not meant to be used directly, but requires an orchestration layer like Agent Executor, Kagent, or possibly in the future OpenShell (more on that below). OpenShellAgent Substrate OriginNVIDIAGoogle CNCF SandboxVoted in Sep 26, 2026Voted in Sep 28, 2026 Main problemWhat may this agent do?How do we run thousands of mostly idle agents cheaply? Unit of workOne sandbox per agent: a Sandbox, a workload Pod, and a supervisor PodAn actor: an identity plus a snapshot. When active, it runs in its own sandbox inside a shared worker Pod. Workers are designed to hold many actors (–max-actors defaults to 1,000), but the autoscaling demo notes that each worker holds one actor today Kubernetes building blockAgent Sandbox. The gateway creates agents.x-k8s.io Sandbox resources, and the Agent Sandbox controller reconciles themIts own WorkerPool CRD (ate.dev), which atecontroller turns into a Deployment of worker Pods. It does not use Agent Sandbox RoutingThrough the gateway and the sandbox’s supervisorAn ate-target-actor header. The router resumes the actor if needed, and atunnel passes the request to its sandbox. Actors have no Pod IP CredentialsThe supervisor swaps a placeholder for the real key, only at endpoints the provider allowsThe egress gateway swaps an ate-secret:// placeholder header for the real credential. Actors and snapshots never hold the secret IdentitySupervisor identity tied to the namespace, Sandbox UID, Pod UID, and runtime generationA SPIFFE X.509 certificate per actor, valid for 1 hour, and mTLS between all components. OpenFGA access policies are in progress StateA /sandbox PVC that survives stop and startRAM and filesystem snapshots in object storage. Suspend and resume take under a second; the goal is 100 ms at p95 AutoscalingHPA for the gateway (more than one replica needs external PostgreSQL) and node autoscalers. Sandbox has no /scale subresource, so HPA, KEDA, and VPA cannot target a sandbox. Each new agent is a gateway API callWorkerPool has a /scale subresource, so HPA can scale workers on how full they are (the demo runs on kind only), plus node autoscalers. Requests wait when the pool is full Maturityv0.1.xPre-1.0. Three areas that will matter most to Kubernetes cluster admins::
- How detailed the policy is. OpenShell checks each request at a supervisor that serves one sandbox. It can let curl read GitHub issues and block curl from creating one. Substrate checks traffic at a shared egress gateway, per actor and per destination host. There is work underway to natively support OpenFGA policies and allow external policy.
- What Kubernetes can see. Each OpenShell sandbox is a set of Kubernetes objects, so RBAC, Kyverno, audit logs, and kubectl work on it. Substrate keeps actors, templates, and egress policies in its own API, backed by PostgreSQL, so the Kubernetes API server is not on the request path. Admission control sees Substrate’s worker pools, but not the agents or their egress policies.
- Isolation. Substrate requires a gVisor or Cloud Hypervisor sandbox for every actor; a plain container is not supported. That is what makes its snapshots possible. OpenShell runs a standard container with Landlock and seccomp, and you can require a stronger RuntimeClass for untrusted agents. Scaling follows from this. With OpenShell, your application decides how many sandboxes to run, and you size each one when you create it, as the demo does with Kyverno defaults and caps. With Substrate, HPA scales the worker pools, and the number of agents is separate from the number of Pods. For now, choose based on your workload. If you have many bursty, mostly idle agents, such as one assistant per user, and cost per agent matters most, look at Substrate. If your agents hold real credentials and reach production systems, and you need per-request control and policy on Kubernetes objects, look at OpenShell. Many large enterprises will likely need a mix eventually, and in the future, you may be able to use both. OpenShell’s RFC 0012, merged Sep 10, 2026, makes isolation a pluggable isolation backend, separate from the supervisor that enforces policy. The team has proposed building a Substrate backend (NVIDIA/OpenShell#3362). OpenShell would keep the policy, credential, and audit controls, and Substrate would add gVisor isolation and suspend and resume that keeps memory. One blocker is fixed. #3366, merged Sep 21, means the shared contract no longer requires Landlock or seccomp evidence, so a gVisor backend can supply its own. Two pieces are still open: a versioned transport for a backend that runs in a separate process, and a lifecycle operation that keeps memory. As of Oct 11 the issue is open. A contributor has +1’d it and asked whether the maintainers would accept it, but no maintainer has replied yet. If it is accepted, you would get OpenShell’s per-request policy with Substrate’s density. Until then, the difference for adm
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。