Skip to main content
Use k7 -h for built-in help. Below are the primary commands.

Talking to the K7 API

By default, every sandbox-management command (create, list, delete, pause, resume, fork, restore, exec, logs, snapshot *) talks to the K7 API over HTTPS. The CLI resolves the URL and key in this order:
  1. --api-url / --api-key flags (per command).
  2. K7_API_URL / K7_API_KEY environment variables.
  3. ~/.config/k7/config.toml — written by k7 config set api.url ... / k7 config set api.key ....
  4. On a cluster node only: /etc/k7/api_endpoint and the first entry of /etc/k7/api_keys.json.

--core (debugging / on-node CI only)

A hidden global flag --core skips the API and calls K7Core directly in-process. Useful when the API itself is misbehaving and you have kubeconfig access on the node. Most users should never need it.

config

Writes ~/.config/k7/config.toml with mode 0600. Same posture as ~/.kube/config and ~/.docker/config.json. For production use, put the API behind ingress + TLS + IP allowlist; the plaintext key file is suitable for demos and trusted networks today.

install

Install K7 components on host node(s).
  • -v: verbose output
  • —backend, -b: comma-separated backends: kata-firecracker-devmapper (kfd), kata-qemu-longhorn (kql), k7d. Default installs the two Kata backends; add k7d explicitly for the warm-fork microVM runtime.
  • —disk: block device for the kfd LVM thin-pool (auto-detected when omitted).
  • —k7d-version: k7d release version to download (k7d backend only).
  • —k7d-artifact: local k7d release tarball to install instead of downloading (k7d backend only).
  • -i, —inventory: Ansible inventory for multi-node installs (per-host k7_backends is authoritative — don’t combine with --backend).
  • —ha: multi-master HA with embedded etcd (inventory with 3+ servers).
  • —role / —join / —join-token: add a single node to an existing cluster.
  • —no-api: CLI-only install without the k7-api Deployment.
See Multi-node clusters for the inventory format and topology.

version

Check version of installed K7 .deb package

create

Create a sandbox from a YAML file or flags.

pause

Scale a sandbox to 0 replicas, optionally taking a crash-consistent VolumeSnapshot of its root PVC. Snapshots are kata-qemu-longhorn-only and use the longhorn VolumeSnapshotClass registered by the install playbook.
  • --snapshot (optional, takes optional value): when present, take a VolumeSnapshot of the sandbox’s root PVC (<sandbox>-root-lh) before scaling down. Bare flag → snapshot named <sandbox>-paused-<unix-ts>; with value → snapshot named as given.
  • Pause-time snapshots persist as VolumeSnapshot objects in the same namespace until you delete them.

resume

Scales the deployment back to 1. State persisted on the root PVC survives.

restore

Boot a brand-new sandbox from a standalone VolumeSnapshot. Unlike k7 fork, this does not require the original sandbox’s Deployment to still exist — it only needs the snapshot.
Image / backend / sidecar / limits / root-disk-size default to the source sandbox’s values via the k7.io/source-* annotations stamped on the snapshot at creation time (pause / named only — fork-temp snapshots are auto-deleted). Any flag above overrides the corresponding annotation. --no-keep-snapshot deletes the source snapshot after the new sandbox is Ready. Restore is kata-qemu-longhorn-only.

fork

Clone an existing sandbox to a new sandbox. With the kata-qemu-longhorn backend, the root disk PVC (<sandbox>-root-lh) is cloned via a crash-consistent VolumeSnapshot.
  • --snapshot (optional): friendly name for the temporary VolumeSnapshot. If omitted, an auto-named <source>-fork-<unix> snapshot is created and auto-deleted once the new sandbox’s PVC is bound.
  • Pass --snapshot=NAME to opt the snapshot out of GC (it becomes a named snapshot — persistent).
  • Storage scope: disk-only (no memory/CPU/network). One root PVC per sandbox; forks get their own cloned PVC.

snapshot

Manage VolumeSnapshot objects directly. See /api/endpoints/snapshots for the lifetime rules and the three kinds (pause, fork, named).
gc only ever touches kind=fork snapshots older than --keep-fork-for. Pause and named snapshots are never collected, even with --keep-fork-for=0s. A CronJob (k7-snapshot-gc in kube-system) runs the same logic every 10 minutes as a backstop, in case the inline cleanup after k7 fork ever misses a snapshot.

YAML configuration reference

All fields map to the server-side SandboxConfig:
  • name (string, required): unique sandbox name.
  • image (string, required): container image, e.g. alpine:latest.
  • namespace (string, default default): Kubernetes namespace.
  • env_file (string, optional): (absolute) path to an env file on the host node.
  • egress_whitelist (array of CIDR strings, optional): allowed egress IPs, e.g. "1.1.1.1/32" for single hosts or "10.0.0.0/8" for ranges.
  • limits (object, optional): resource limits:
    • cpu (string): cores or millicores, e.g. "1" or "500m".
    • memory (string): e.g. "1Gi", "512Mi".
    • ephemeral-storage (string): e.g. "2Gi".
  • before_script (string, optional): shell script run once after container starts.
    • Runs via kubectl exec before egress netpol is applied; readiness waits for completion.
  • pod_non_root (boolean, optional): run Pod as non-root (UID/GID/FSGroup 65532).
  • container_non_root (boolean, optional): run container as non-root (UID 65532), no privilege escalation.
  • cap_add (string[], optional): add back Linux capabilities (default policy drops ALL).
  • cap_drop (string[], optional): override drop policy. If omitted, ALL is dropped by default.
Example k7.yaml:
Do not whitelist public DNS resolvers (e.g., 1.1.1.1, 8.8.8.8). Doing so re-enables DNS exfiltration (UDP/TCP 53 and DoH over 443). Prefer whitelisting only your own egress proxy IP and enforce DNS/DoH policies at the proxy.If using package managers that require root (e.g., apk add, apt-get install) in before_script make sure you didn’t add security policies that prevent it such as running the pod or container as non-root. Check Security & Networking section in the API reference for more.

list

Lists sandboxes with status, readiness, restarts, age, and image.

delete

Deletes one sandbox.

delete-all

Deletes all sandboxes in a namespace (with confirmation).

shell

Opens an interactive shell in the sandbox pod.

logs

Shows container logs (before script and main container).

top

Top-like view of CPU and memory usage.

nodes storage

Per-node storage-pool utilization, collected from the k7-agent DaemonSet on every node:
  • kata_thinpool — the kfd LVM thin-pool (lvs size, data%, metadata%).
  • k7d_disks — the k7d XFS disk pool at /var/lib/k7d/disks (df size / used / avail).
A node whose agent is unreachable shows a loud error entry — nodes are never silently omitted. Also available as GET /api/v1/nodes/storage (API reference) and Client.nodes_storage() in the SDK.

api

The K7 API is deployed automatically by k7 install and runs as a Kubernetes Deployment (k7-api in kube-system). K3s keeps it running and reschedules it on failure — there is no separate “start” step. The k7 api sub-app provides read-only diagnostics and a feature toggle:
To install without the API (CLI-only deployment, e.g. for local-only test rigs), pass --no-api to k7 install. Re-run k7 install later (without --no-api) to add it; the playbook is idempotent.
The previous top-level commands k7 start-api / k7 stop-api / k7 api-status / k7 get-api-endpoint are deprecated; they still work for one release and print a one-line warning pointing at the new home.

API keys

Keys are stored at /etc/k7/api_keys.json. Use with X-API-Key or Authorization: Bearer.

Flag reference (create)

  • -n, —namespace: Kubernetes namespace (default default).
  • -f, —file: YAML config file (defaults to k7.yaml when using k7 create).
  • —name: Sandbox name (when not using YAML).
  • —image: Container image (when not using YAML).
  • —cpu: CPU limit (e.g., 1, 500m).
  • —memory: Memory limit (e.g., 1Gi, 512Mi).
  • —storage: Ephemeral storage limit (e.g., 2Gi).
  • —env-file: Path to env file on the host node injected as a Secret.
  • —egress CIDR: Repeatable; whitelist CIDR blocks for egress (omit to keep open; use none for full block).
  • —before-script: Shell script to run once after container start; runs with open egress before lockdown.
  • —entrypoint: Repeatable; override image ENTRYPOINT (ordered).
  • —cmd: Repeatable; override image CMD (ordered).
  • —pod-non-root / —no-pod-non-root: Pod-level non-root defaults.
  • —container-non-root / —no-container-non-root: Container runs as UID 65532, no privilege escalation.
  • —cap-add CAP: Repeatable; add back Linux capabilities (default drop ALL).
  • —cap-drop CAP: Repeatable; override default drop policy.
Package installs like apk add require root inside the container. Either leave container_non_root disabled for setup or prebuild an image. See Security & networking: /api/security.
For kata-qemu-longhorn, the persistence wrapper requires /bin/sh, tar, and mount in the image. Use a Debian/Ubuntu-like base (or ensure those tools are installed).
For kata-qemu-longhorn, the main container runs privileged to allow bind mounts for persistence.
For kata-qemu-longhorn, the wrapper preserves the image ENTRYPOINT+CMD by default. Use --entrypoint and/or --cmd to override.