docker build, docker run, or docker compose inside the sandbox. k7 create --docker gives every backend the same contract:
docker,docker compose, anddocker buildxonPATH(pinned Docker 27.5.1, Compose 2.32.4, Buildx 0.20.0) — your image does not need the Docker CLI.- A pinned
dockerdwithoverlay2on a block graph disk (default 20Gi,--docker-disk 40Gito change). Never vfs, never a graph on virtio-fs or emptyDir. DOCKER_HOSTpre-set in the sandbox container; the socket is shared as a directory mount.- Everything runs inside the sandbox VM — the isolation boundary is the VM, not the container.
--sidecar docker (and sidecar: docker) is a deprecated alias of --docker. It still resolves, but the old dind sidecar with a tmpfs / subPath graph is gone: the alias now provisions the same block-backed overlay2 engine described here.How it runs on each backend
The user-visible contract is identical; what differs is wheredockerd lives and what happens to the graph disk across pause, fork, and restore.
On kql the two VolumeSnapshots (root + docker graph) are crash-consistent per volume, not atomic across both. k7 syncs the vehicle before snapshotting, but an inner container mid-write can still land on either side of the cut.
k7d / k7d-fc: dockerd as a guest service
The k7d guest agent (PID 1) starts a pinneddockerd from a read-only, host-enforced payload image and puts its graph on a dedicated scratch disk. Inner containers share the guest kernel and network namespace with the sandbox container, and the sandbox paths /home, /root, /tmp, /opt, and /workspace are exported into the engine so docker run -v "$PWD:/src" from your working directory works as expected.
Because dockerd is not a Kubernetes sidecar, k7 fork clones it like any other in-VM process: a warm fork of a --docker sandbox comes up with Storage Driver: overlay2 and the source’s images and containers already present. This is the only backend where the Docker engine itself is forkable.
Requires k7d 0.6.0+ (the release tarball ships the guest docker payload; k7 install --backend k7d installs it to /usr/local/share/k7d/docker). An older k7d fails create loudly: this k7d has no docker service; upgrade.
Inside the guest, docker.sock is guest root — the sandbox securityContext no longer bounds what runs in the VM. For mutually distrusting tenants, use k7d-fc: identical guest side, plus a per-VM jailer around the VMM. See the k7d security notes on --docker.
kfd / kql: the docker-vehicle
On the Kata backends k7 injects one privilegeddocker-vehicle container (docker:27.5.1-dind, digest-pinned) into the pod. It formats and mounts the block device /dev/k7docker, then runs dockerd --storage-driver=overlay2 on a directory socket at /run/k7/docker/docker.sock. An init step copies the pinned CLI and plugins into the sandbox container. Within one Kata VM the vehicle and the sandbox are a single trust domain; the isolation boundary is the VM.
The sandbox waits for the vehicle’s readiness probe (docker info reporting overlay2) before before_script runs.
Measured
Medians of 3 on one Hetzner AX41 node (Ryzen 5 3600, 64 GiB, NVMe), 3Gi / 4 CPU guests,DOCKER_BUILDKIT=0. Full tables and ranges: PERFORMANCE.md.
The
run io row is the point of the block graph: the old dind sidecar on a tmpfs / subPath graph fell back to vfs and took ~37 s on the same workload.
Network considerations
Inner containers share the sandbox’s network namespace. Traffic spawned bydockerd (image pulls, containers dialing out) flows through the VM’s network stack and is subject to the sandbox’s egress policy. k7 create without an egress flag is block-all, so pulls will hang; whitelist the registry:
*.docker.com matches production.cloudflare.docker.com (and any other CDN host under that suffix) but not docker.com itself — add the apex separately. See Networking.
Reference
- Pins and helpers:
src/k7/core/docker.py - Kata vehicle script:
src/k7/assets/k7-docker-vehicle.sh - Backend comparison: Backends
