User guide: container sandboxes (spec.sandbox.oci)
Run an OCI container image as a Machine, in its own lightweight VM on a FluxVM node, with a docker-like CLI. There is no Docker daemon, no Podman and no Colima: FluxVM mounts the image's root filesystem with its own init and runs the entrypoint. Experimental.
Where it runs
FluxVM provides the container track on macOS hosts
(Virtualization.framework; linux/amd64 images run under Rosetta). The
Linux hypervisors do not run container images, so on a mixed cluster pick
macOS nodes with a node selector. A node whose FluxVM cannot run the track
reports the error on the Machine. The host needs FluxVM's OCI boot
artifacts (oci-kernel, oci-initrd; built by FluxVM's
scripts/build-oci-boot.sh on Linux arm64, see FluxVM's
docs/oci-sandboxes.md); without them create fails with a message naming
the missing artifact.
The CLI
# Run to completion, print the exit code, remove the Machine
kaironctl container run --wait --rm alpine:3.22 sh -c 'echo hi; exit 3'
echo $? # 3
# A long-running service with a published port and a restart policy
kaironctl container run --name web -p 8080:10000 --restart always envoyproxy/envoy:v1.40.0
# x86-64 image under Rosetta, pinned to Mac nodes
kaironctl container run --platform linux/amd64 --node-selector kubernetes.io/os=darwin \
--wait alpine:3.22 uname -m
kaironctl container ps [-a]
kaironctl container inspect web
kaironctl container rm web
Flags go before the image, as with docker run; everything after the image
is the container's command. --wait waits for the process to exit and
returns its exit code; --rm implies --wait and deletes the Machine
afterwards; -d returns once the Machine exists.
The Machine
apiVersion: kairon.zyvor.dev/v1
kind: Machine
metadata: {name: web}
spec:
resources: {cpu: "1", memory: 512Mi} # optional; memory is at least 512Mi
sandbox:
oci:
image: envoyproxy/envoy:v1.40.0
ports: ["8080:10000"] # host ports 1024+, TCP only
restart: always
healthCheck: {command: [bash, -c, "echo > /dev/tcp/127.0.0.1/10000"], intervalSeconds: 5}
Fields: image (required), platform, command, entrypoint, env
(KEY=value), workdir, user, writableRoot, exitPolicy (keep or
poweroff), ports, restart (no, on-failure, always),
maxRestarts, healthCheck, offline, allowHosts (an egress allow-list),
profile (tiny, small, standard).
Rules checked at admission:
- It excludes
spec.image,spec.sandbox.templateNameandspec.volumes. portscannot combine withofflineorallowHosts, which have no network card to publish on.spec.sandbox.ociis immutable: delete and recreate the Machine to change the container.
status.container carries the process state, read from FluxVM's sandbox
logs endpoint on each reconcile: exitCode once it has exited, restarts,
health and initError.
Not included yet
- Secrets: FluxVM supports write-only
secret_env, but a Machine object is readable by anyone who can read Machines, so there is no field for it until Secret references are wired in. Do not put credentials inenv. - Logs:
kaironctl container logsis not provided; the console tail and exit code are on FluxVM'sGET /v1/sandboxes/{id}/logs, which Kairon reads only forstatus.container. - Volumes, exec and compose: named volumes,
container execand a Docker Engine API socket (forDOCKER_HOSTandpodman --url) are follow-ups. - Linux hosts: not supported by FluxVM's container track today.