Offload is a CLI-first distributed task runner for small k3s clusters. It bootstraps nodes over SSH, accepts task submissions from a local CLI, materializes them as Kubernetes workloads, tracks status in Redis, and stores artifacts in MinIO.
offload: CLI for bootstrap, onboarding, submission, status, logs, and artifact fetchoffload-controller: in-cluster Redis consumer that creates Kubernetes workloadsoffload-runner: helper container that executes commands or uploads task artifacts
command: run a shell command inside the runner imageimage: run a prebuilt container image with an optional command overridebuild: upload a local Docker context, build it in-cluster, then run it
Execution modes:
job: single one-shot workloadstatefulset: replicated workload for sharded or distributed execution
Task manifests are supported in YAML or JSON:
offload run --file ./examples/task-manifest.yamloffload submit ./examples/task-manifest.yaml --watch --fetch ./out/task
Admin bootstrap:
scripts/bootstrap/admin/install.sh
offload admin init --name demo --server ubuntu@100.x.x.10 --ssh-key ~/.ssh/id_ed25519_offload_nopass --worker ubuntu@100.x.x.11
offload admin invite create --name demo --out ./demo-user.invite.yaml --expires 168hUser connect and submit:
scripts/bootstrap/user/install.sh
offload user connect --bundle ./demo-user.invite.yaml
offload submit ./examples/task-manifest.yaml --watch --fetch ./out/first-taskAfter offload user connect, Offload remembers the current cluster so --name can usually be omitted.
offload run [--name <cluster>] --mode job|statefulset --cmd "<shell command>" --image <ref> --context <dir> --dockerfile Dockerfile --env KEY=VAL --cpu 500m --memory 512Mi --replicas 1 --max-retries 2offload run [--name <cluster>] --file ./task.yamloffload submit <path> [--name <cluster>] [--mode job|statefulset] [--replicas N] [--dockerfile Dockerfile] [--cmd "..."] [--watch] [--fetch ./out]offload status [--name <cluster>] <task-id> [--watch]offload logs [--name <cluster>] <task-id> --phase run|build [-f]offload fetch [--name <cluster>] <task-id> --out ./artifactsoffload cluster current|list|use <name>offload admin init --name <cluster> --server <user@host> --ssh-key <path> [--worker <user@host> ...] [--require-tailscale]offload admin add-node --name <cluster> --worker <user@host> --ssh-key <path> [--server <user@host>]offload admin invite create --name <cluster> [--out ./offload-invite-<cluster>.yaml] [--expires 168h] [--allow-logs]offload admin invite revoke --name <cluster> --bundle-id <id>offload user connect --bundle <invite.yaml> [--name <cluster>]offload doctor admin --name <cluster>offload doctor user --name <cluster>offload doctor node --target <user@host> --ssh-key <path>
~/.offload/clusters/<name>.yaml: cluster endpoints and credentials~/.offload/kubeconfigs/<name>.yaml: admin kubeconfig~/.offload/invites/<name>.yaml: local admin invite index~/.offload/current-cluster: default cluster used when--nameis omitted
Bootstrap manifests live under deploy/k8s. During bootstrap, Offload generates cluster-specific Redis and MinIO credentials and tracks SSH trust in an Offload-managed known_hosts file instead of disabling host verification.
- Quickstart:
docs/quickstart-by-role.md - Manifest example:
examples/task-manifest.yaml