Skip to content

Commit c30d7b8

Browse files
committed
Document runc as the evaluated AKS sandbox configuration
1 parent 05eac29 commit c30d7b8

2 files changed

Lines changed: 136 additions & 56 deletions

File tree

‎enterprise/k8s-install/aks.mdx‎

Lines changed: 127 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,30 @@ description: Prepare an Azure Kubernetes Service cluster to run OpenHands Enterp
44
icon: /enterprise/images/azure-logo.svg
55
---
66

7-
Prepare Azure Kubernetes Service (AKS) for OpenHands Enterprise, then follow the
8-
[Helm installation](/enterprise/k8s-install/installation) for application configuration.
9-
This page covers Azure permissions, node pools, persistent storage, and ingress.
7+
Running OpenHands Enterprise on Azure Kubernetes Service (AKS) follows the standard
8+
[Helm installation](/enterprise/k8s-install/installation), with provider-specific
9+
choices for node pools, storage, ingress and the sandbox runtime. This guide covers
10+
preparing the cluster with standard runc sandboxes. Once it is ready, follow the
11+
Helm guide to deploy using the runtime values below. Skip
12+
[Installing Sysbox](/enterprise/k8s-install/sysbox). Wherever the Helm guide installs
13+
or checks Sysbox, use the runc values and checks on this page instead.
14+
15+
<Warning>
16+
Sysbox is not yet supported for OpenHands Enterprise on AKS. This guide uses the
17+
node’s default runc runtime, evaluated with ordinary coding workflows (see Validation Scope). Docker builds
18+
and Docker Compose inside the sandbox are unavailable in this configuration.
19+
Other system-container workloads, such as systemd or nested containers, were not validated.
20+
Runc does not provide Sysbox’s additional system-container isolation; review the
21+
isolation requirements for your workloads before production adoption.
22+
</Warning>
1023

1124
## Cluster Requirements
1225

1326
| Requirement | Recommendation |
1427
| --- | --- |
1528
| Access | An Azure subscription and permissions to create the resource group, cluster, node pools and networking |
16-
| AKS version | A supported AKS version compatible with [Sysbox](/enterprise/k8s-install/sysbox); verify the actual Ubuntu image and containerd version |
17-
| Sandbox OS | Ubuntu nodes with a working Sysbox runtime |
29+
| AKS version | An AKS-supported version; verify the actual Ubuntu image and containerd version against your target Enterprise release |
30+
| Sandbox OS | Ubuntu nodes using the default containerd/runc runtime |
1831
| Storage class | Azure Disk CSI, such as `managed-csi`, with expansion enabled |
1932
| Capacity | Sufficient regional and VM-family vCPU quota for application nodes, sandbox nodes and upgrades |
2033

@@ -33,48 +46,94 @@ Use separate pools for application services and sandbox workloads:
3346

3447
- **General pool:** runs OpenHands services and cluster add-ons. Keep application
3548
workloads here through node affinity or selectors.
36-
- **Sysbox pool:** an Ubuntu user node pool for agent sandboxes. Configure
37-
`sysbox-install=yes` as a persistent node-pool label so new nodes receive the installer.
49+
- **Sandbox pool:** an Ubuntu user node pool for agent sandboxes. Set
50+
`workload=openhands-sandbox` as a persistent node-pool label so new nodes match
51+
the Runtime API selector. Do not install the Sysbox DaemonSet or add its installer label.
3852

3953
The evaluation used Azure CNI overlay with Calico, two platform nodes and a sandbox
4054
pool with autoscaler bounds of one to two nodes. Size the pools using the
4155
[Sizing Guide](/enterprise/sizing-guide) and
4256
[Resource Limits](/enterprise/k8s-install/resource-limits), including node overhead,
4357
image storage and warm sandbox capacity. Validate scale-down behavior for active sessions.
4458

45-
### Set Up the Sandbox Runtime
59+
AKS rejected a manual node-pool scale-down with `UnsatisfiablePDB` because of a
60+
sandbox PodDisruptionBudget with `maxUnavailable: 0`. Node-image and Kubernetes
61+
upgrades, which drain nodes, were not tested. Validate maintenance before relying
62+
on it; do not delete or patch PodDisruptionBudgets to force it.
4663

47-
1. Follow [Installing Sysbox](/enterprise/k8s-install/sysbox) to install Sysbox on
48-
your Ubuntu sandbox pool.
49-
2. Before installing OpenHands, run a Sysbox test pod with an Azure Disk workspace
50-
using the [AKS installation skill and companion checks](https://github.com/OpenHands/OpenHands-Cloud/tree/832e57028298f3ad564e6ee7461ee1d9d2ee6d62/aks-install).
51-
Confirm the pod starts and can write and read a file.
52-
3. After installing OpenHands, start a conversation and ask it to run `pwd`.
53-
Confirm it returns the workspace directory.
64+
### Configure runc Sandboxes
5465

55-
<Warning>
56-
Some AKS node images need an additional Sysbox setup step. If the test pod fails
57-
with an error mentioning `sysbox-runc`, contact OpenHands support before continuing.
58-
The AKS installation skill includes the workaround used for the evaluation.
59-
</Warning>
66+
Override the Sysbox defaults in the Enterprise chart through Helm values:
6067

61-
Before enabling sandbox-pool autoscaling, confirm that each newly created node can
62-
start a sandbox. A setup correction applied to existing nodes must also be applied
63-
to replacement and new nodes. Validate this with your support team before relying
64-
on automatic scale-out or node upgrades.
68+
```yaml
69+
runtime-api:
70+
env:
71+
RUNTIME_CLASS: ""
72+
SET_HOST_USERS: "false"
73+
RUNTIME_NODE_SELECTOR: '{"workload":"openhands-sandbox"}'
74+
RUNTIME_TOLERATIONS: '[]'
75+
```
6576
66-
<Accordion title="Troubleshooting: Sysbox is installed but sandbox pods do not start">
67-
The failure was observed on AKS 1.35.8, Ubuntu 24.04.5 LTS and containerd 2.3.3-2
68-
with Sysbox installer v0.7.1-0. The installer registered the runtime under the old
69-
containerd plugin key, so its success message did not establish a working runtime.
70-
See [upstream issue 997](https://github.com/nestybox/sysbox/issues/997).
77+
An empty `RUNTIME_CLASS` omits `runtimeClassName` from new sandbox pods, using
78+
containerd’s default runtime. `SET_HOST_USERS: "false"` omits the `hostUsers` override;
79+
it does not request the Sysbox user-namespace configuration. Save these values in
80+
`values-aks-runc.yaml` and pass that file as the **last** `-f` argument on every
81+
install and upgrade, after your base values and feature overlays. For example:
7182

72-
The evaluation workaround corrected only the Sysbox registration and restarted
73-
containerd on each affected sandbox node. It requires a reviewed per-node operation
74-
and does not automatically cover nodes added by autoscaling, reimaging or upgrades.
75-
The [AKS install skill](https://github.com/OpenHands/OpenHands-Cloud/blob/832e57028298f3ad564e6ee7461ee1d9d2ee6d62/.agents/skills/aks-install.md)
76-
contains the diagnostic and correction procedure. Verify a real test pod afterward.
77-
</Accordion>
83+
```bash
84+
helm upgrade --install openhands <licensed-chart-source> --version 0.74.0 \
85+
--namespace openhands --create-namespace \
86+
-f values.yaml -f values-automation.yaml -f values-aks-runc.yaml --timeout 10m
87+
```
88+
89+
Include `values-automation.yaml` only when enabling automations. Follow the Helm
90+
guide for namespaces, Secrets and other prerequisites. Omitting these overrides
91+
can restore the chart’s Sysbox defaults and prevent new sandboxes from starting.
92+
If you add a sandbox-pool taint, configure a matching toleration instead of the empty list.
93+
94+
After deployment, create a conversation and verify that its pod is in the
95+
sandbox pool with no `runtimeClassName` or `hostUsers` override:
96+
97+
```bash
98+
kubectl get pod <sandbox-pod> -n <runtime-namespace> \
99+
-o jsonpath='{.spec.nodeName}{"\t"}{.spec.runtimeClassName}{"\t"}{.spec.hostUsers}{"\n"}'
100+
```
101+
102+
Expect a sandbox-pool node name followed by two empty fields. Use the configured
103+
runtime namespace (`openhands-runtimes` in the evaluation). The evaluated
104+
sandboxes ran without privileged mode, a host Docker socket or added capabilities.
105+
Confirm the agent executes commands and writes and rereads a workspace marker.
106+
Python, Node/npm, Git (public clone; authenticated pushes not tested), browser
107+
navigation/screenshots, HTTP previews and workspace
108+
persistence passed the runc evaluation. Docker-in-sandbox failed; an installed
109+
Docker CLI or Compose binary does not establish daemon functionality.
110+
See [Docker in the agent sandbox](/enterprise/docker-in-sandbox) for that feature’s requirements.
111+
112+
### Keep Startup Capacity Ready
113+
114+
Keep enough Ready sandbox nodes with the agent image cached to accommodate the
115+
expected concurrent sessions. Pool minimum counts alone do not establish available
116+
capacity: account for existing pods, memory requests, disk limits and node overhead.
117+
The tested defaults requested 500m CPU and 3 GiB memory per sandbox; a tested
118+
4-vCPU/16-GiB node accommodated three such sandboxes after Kubernetes reservations.
119+
Size production capacity using your own resources and workload measurements.
120+
121+
In the October 6 evaluation, six starts on ready/cached capacity all succeeded in
122+
38–51 seconds. A separate three-start burst forcing a zero-node pool to scale up
123+
failed around 120 seconds: the new node became Ready at 143 seconds and sandbox
124+
pods at approximately 234–247 seconds. The failed startup tasks did not recover
125+
automatically after their pods became healthy. Three fresh starts on that same node
126+
with its image cached then all succeeded in 53–55 seconds.
127+
128+
This locates the observed failure before sandbox execution, in cold provisioning
129+
and startup orchestration. It is not a runc-versus-Sysbox performance benchmark.
130+
Nodes that were already Ready with the image cached avoided this failure in testing.
131+
Pre-pulling images onto newly added nodes was not tested and would not remove the
132+
node-readiness delay. No startup deadline or recovery fix was validated. Do not
133+
rely on the autoscaler adding nodes, including scale-from-zero, to absorb interactive
134+
startups in the tested release. Validate scale-out, node replacement and maintenance
135+
for your target release. Pause orphaned sandboxes from failed startups through
136+
supported OpenHands APIs or the UI’s Stop Runtime action before retrying.
78137

79138
## Persistent Storage
80139

@@ -84,9 +143,12 @@ Inspect the Azure Disk CSI StorageClass:
84143
kubectl get storageclass managed-csi -o yaml
85144
```
86145

87-
The evaluated class uses `disk.csi.azure.com`, `WaitForFirstConsumer`,
88-
`ReadWriteOnce` and volume expansion. Configure stateful components and workspace
89-
storage explicitly; the GKE `standard-rwo` and AWS gp3 examples do not apply.
146+
The evaluated class uses `disk.csi.azure.com`, `WaitForFirstConsumer`, reclaim
147+
policy `Delete` and volume expansion. The evaluated Azure Disk PVCs use
148+
`ReadWriteOnce`. Configure stateful components and workspace
149+
storage explicitly, including persistence for any in-cluster object store; the GKE
150+
`standard-rwo` and AWS gp3 examples do not apply. Add `STORAGE_CLASS` to the same
151+
`runtime-api.env` map as the runc values above; do not create duplicate YAML keys.
90152

91153
```yaml
92154
runtime-api:
@@ -100,7 +162,9 @@ postgresql:
100162

101163
Account for node disk-attachment limits and availability-zone topology. Validate
102164
mounting, persisted content after reattachment, and expansion on a disposable PVC.
103-
The evaluation passed these checks, including expansion from 1 GiB to 2 GiB.
165+
The runc evaluation passed workspace read/write, stop/reopen persistence and
166+
cross-node disk reattachment. Expansion was not validated on the runc configuration;
167+
test it on a disposable PVC.
104168
See [Azure Disk CSI provisioning](https://learn.microsoft.com/en-us/azure/aks/create-volume-azure-disk).
105169

106170
## Object Storage
@@ -109,21 +173,23 @@ Conversation/session storage is separate from workspace PVCs. Helm chart 0.74.0
109173
supports S3-compatible and GCS filestore configuration; it does not expose an Azure
110174
Blob backend. Do not substitute Azure Blob credentials into the S3 settings.
111175

112-
The evaluation used the chart's optional RustFS store on Azure Disk CSI. For production,
113-
select a supported durable object store and validate backup, restore and availability.
114-
When enabling automations, also provision the separate automation package bucket.
176+
The tested configuration used the chart's optional RustFS store on Azure Disk CSI.
177+
Select an object store that meets your durability and availability requirements,
178+
and verify backup and restore for that configuration.
179+
When enabling automations, configure a separate automation package bucket. The
180+
automation service can create it at startup when bucket creation is enabled.
115181

116182
## Database
117183

118-
Use the [External PostgreSQL](/enterprise/external-postgres) guide for production
184+
Use the [External PostgreSQL](/enterprise/external-postgres) guide for managed
119185
database requirements and Helm values. If choosing Azure Database for PostgreSQL,
120186
verify compatibility, TLS and network access against those requirements before deployment.
121-
The AKS evaluation used bundled PostgreSQL; a managed Azure database was not validated.
187+
The tested configuration used bundled PostgreSQL.
122188

123189
## Ingress
124190

125191
Run an ingress controller on the general pool. Traefik was validated with an Azure
126-
public LoadBalancer:
192+
public LoadBalancer. In the Traefik Helm values (chart `41.6.0` was tested):
127193

128194
```yaml
129195
service:
@@ -138,20 +204,27 @@ Follow [DNS and TLS](/enterprise/k8s-install/dns-and-tls) for trusted certificat
138204
and hostname configuration. Use flat runtime hostnames with Traefik standard Ingress.
139205
If provisioning certificates manually, assign renewal and Secret-update ownership.
140206

141-
## Installation Skill
207+
## Validation Scope
142208

143-
For agent-assisted evaluation setup, the
144-
[AKS installation skill](https://github.com/OpenHands/OpenHands-Cloud/blob/832e57028298f3ad564e6ee7461ee1d9d2ee6d62/.agents/skills/aks-install.md)
145-
and [companion files](https://github.com/OpenHands/OpenHands-Cloud/tree/832e57028298f3ad564e6ee7461ee1d9d2ee6d62/aks-install)
146-
provide Azure commands, values templates and storage/automation checks.
147-
The skill is currently proposed in [PR #1339](https://github.com/OpenHands/OpenHands-Cloud/pull/1339).
209+
<Note>
210+
Validated October 6, 2026 with Helm chart `0.74.0`, OpenHands `1.67.0`, Runtime API
211+
`0.10.0` and agent-server `1.49.6-python` on AKS `1.35.8`, Ubuntu `24.04.5 LTS`
212+
and containerd `2.3.3-2`. The configuration used bundled PostgreSQL and RustFS.
213+
GitHub login, trusted HTTPS, ordinary coding/browser workflows, workspace persistence,
214+
cross-node disk movement and execution on an autoscaler-added node, after it
215+
became Ready, passed. Newly added nodes ran sandboxes without per-node runtime setup.
216+
217+
Cold autoscaling exceeded the startup deadline. An earlier resume-related HTTP 401
218+
and a PodDisruptionBudget issue blocking manual pool scale-down remain unresolved.
219+
Automations and PVC expansion were not validated on this runc configuration. Managed Azure PostgreSQL, Azure Blob, private
220+
endpoints, backup/restore, cross-zone recovery, tenant isolation and network
221+
isolation between sandboxes were not covered. No NetworkPolicy targeted the
222+
sandbox namespace in the evaluation. This is evaluation evidence, not production acceptance.
223+
</Note>
148224

149225
## Next Steps
150226

151227
<CardGroup cols={2}>
152-
<Card title="Installing Sysbox" icon="cube" href="/enterprise/k8s-install/sysbox">
153-
Configure and verify the sandbox runtime.
154-
</Card>
155228
<Card title="DNS and TLS" icon="lock" href="/enterprise/k8s-install/dns-and-tls">
156229
Configure hostnames and trusted certificates.
157230
</Card>

‎enterprise/k8s-install/sysbox.mdx‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,15 @@ description: Install the Sysbox runtime so agent sandboxes can run securely
44
icon: cube
55
---
66

7-
OpenHands runs each agent session in a sandbox that uses [Sysbox](https://github.com/nestybox/sysbox)
8-
for isolation. This guide covers installing Sysbox.
7+
OpenHands Enterprise can use [Sysbox](https://github.com/nestybox/sysbox)
8+
for sandbox isolation. This guide covers installing Sysbox.
9+
10+
<Warning>
11+
Sysbox is not yet supported for OpenHands Enterprise on **Azure Kubernetes Service
12+
(AKS)**. Do not use this procedure for OpenHands Enterprise on AKS. See the
13+
[Azure AKS guide](/enterprise/k8s-install/aks) for the evaluated runc configuration
14+
and its Docker-in-sandbox, isolation and startup limitations.
15+
</Warning>
916

1017
## Node Requirements
1118

0 commit comments

Comments
 (0)