Sandbox nodes
Which compute nodes run sandboxes, and which run VMs, is decided by packages and traits. This page explains how sandbox packages carry traits, how the exact-key trait rule reserves a node, and what each of the three node layouts costs.
What runs on a sandbox node
A sandbox node is a compute node (CN) whose agent takes sandbox jobs. Each sandbox
is a microVM inside its own zone, run from a runtime bundle that the agent installs
on the CN. The bundle holds the virtual machine monitor, the guest kernel, and the
guest agent. The agent reports the bundle in its status as sandbox_runtime, and
placement takes the CN for sandboxes only when that report's state is ok.
A CN takes sandbox jobs only when sandboxes are enabled for it: by
sandbox.enabled_default, or by tritonadm cn sandbox set <CN> --enabled true. That
switch says whether a CN can run sandboxes. Traits say which work it is kept for.
Sandbox packages
A sandbox gets its size only from a package of kind sandbox in the tenant's silo.
Every silo gets three at startup and at creation:
| Package | vCPU | Memory | Disk |
|---|---|---|---|
sandbox-2g | 2 | 2 GiB | 8 GiB |
sandbox-4g | 2 | 4 GiB | 16 GiB |
sandbox-8g | 4 | 8 GiB | 32 GiB |
Each seeded package carries the trait sandbox=true. A family that exists in any
version is never seeded again, so an operator's edit or retirement stays.
sandbox.default_package names the package a create uses when it names none, and
the one the booted pool keeps. It defaults to sandbox-2g.
The two kinds do not mix. A VM create cannot use a sandbox package, and a sandbox cannot use a VM package. A sandbox create that gives sizes as numbers is refused, so every sandbox's size is something an operator chose. A sandbox package may have at most 16 vCPUs, at most 64 GiB of memory, and a disk of 4 to 256 GiB.
Traits reserve, labels select
A CN has two kinds of key-value data, and they do different jobs.
Traits reserve a CN. Placement uses the legacy Triton exact-key rule: a CN takes a request only when its trait keys are exactly the request's keys, and every value matches. A request with no traits goes only to a CN with no traits. So a CN with traits is kept for the packages that name them, and nothing else lands there.
Labels select a CN and never reserve it. The NoCloud build tag image-build=true
and the capacity view's cluster and rack are labels.
A request's traits come from its package version. An operator's instance create can
replace them with its own traits. A VM with no package traits, and every platform
zone (NAT gateways, SSH relays, load balancers, NAS gateways), takes
placement.default_vm_traits. A tenant can never set traits.
A list value lets one CN take more than one kind of package. A CN with
pool=[vm,sandbox] takes a package with pool=vm and a package with pool=sandbox,
because a requested string matches when the CN's list holds it.
Three layouts
Sandbox-only nodes
Give each sandbox CN sandbox=true. The seeded packages need no change. Sandboxes go
only to these CNs, and VMs go only to CNs with no traits.
This keeps sandbox churn, which is many short-lived zones and a large reservoir, away from long-running VMs. The cost is that sandbox capacity and VM capacity do not share spare room.
VM-only nodes
Leave the CN with no traits. It takes free-form VMs and packages with no traits, and no sandbox, because every seeded sandbox package has a trait.
Mixed nodes
Give the CN a list such as pool=[vm,sandbox], give every sandbox package
pool=sandbox and every VM package pool=vm, and set
placement.default_vm_traits to {"pool":"vm"}. Both kinds then share the CN's
room.
The cost is setup work and coupling: every package needs its trait, and a package
without one lands only on CNs with no traits. A CN with only pool=vm takes VMs and
no sandbox.
The platform-zone constraint
Platform zones place like VMs with no package traits. Keep at least one CN that
takes placement.default_vm_traits. If every CN carries traits that the default does
not match, a VPC gets no NAT gateway, and sandbox egress fails.
Classes are traits too
A package's cpu_class and disk_class add the keys cpu-class and disk-class to
the request when they are not generic. They follow the exact-key rule, so a CN for
an nvme package carries disk-class=nvme and takes only packages that name that
class. No package, setting, or operator create can set these two keys as traits.