delonix cluster
Kubernetes de ponta a ponta: bootstrap kubeadm idempotente sobre SSH, ou provisionamento completo de VMs.
End-to-end Kubernetes: idempotent kubeadm bootstrap over SSH, or full VM provisioning.
Dois caminhos para um cluster real (não emulado):
cluster apply faz bootstrap kubeadm em hosts já vivos e alcançáveis por SSH —
idempotente sem ficheiro de estado (cada passo tem um check e um apply;
nunca dessincroniza de um .tfstate porque não há nenhum). cluster kubeadm vai mais longe:
provisiona as VMs a partir da imagem VM dourada, espera pelo SSH e corre o MESMO bootstrap — um
comando, do zero a um cluster com o delonix-cri como runtime (sem containerd).
Two paths to a real (not emulated) cluster: cluster apply
bootstraps kubeadm on hosts that are already alive and reachable over SSH —
idempotent with no state file (every step has a check and an
apply; it can never drift from a .tfstate because there isn't one).
cluster kubeadm goes further: it provisions the VMs from the golden VM image, waits
for SSH, and runs the SAME bootstrap — one command, from zero to a cluster running
delonix-cri as its runtime (no containerd).
📄 Implementação real em Rust: cmd/cluster.rs
Usage: delonix cluster <COMMAND>
Commands:
backup Back up etcd's keyspace to a local file (VM-provisioned clusters only)
create Create a local Kubernetes cluster **without a manifest and without Docker**
destroy Remove a cluster entirely — nodes, kubeconfig, `~/.kube/config` entry
kubeadm Provision VMs (golden VM image) + `kubeadm` bootstrap
restore Restore etcd's keyspace from a snapshot taken with `cluster backup`
start Start every node of a stopped kind-mode cluster back up
stop Stop every node of a kind-mode cluster at once — no rebuild, no state lost
upgrade Upgrade a `mode: ssh` cluster to a newer Kubernetes version, kubeadm-style
init Initialize a project with the cluster manifests (kind/vm/ssh)
drain Cordon a node and evict its pods
health Is the control-plane answering, and is every node `Ready`?
kubeconfig Print a cluster's kubeconfig from the local cache (no live SSH)
load Load local images into a kind-mode cluster's nodes, **without a registry**
ls List this host's clusters — kind-mode AND VM-based
uncordon Mark a drained node schedulable again
apply Apply the `kind: KubernetesCluster` document(s) of a manifest
kube Generate a Kubernetes manifest from a container/pod already running locally
prune Reclaim the state of clusters that have no nodes left
network Inspect and prepare the pod-network profiles
help Print this message or the help of the given subcommand(s)
Options:
-h, --help
Print help (see a summary with '-h')
COMMAND MAP:
Lifecycle stop · start · destroy · create · kubeadm · upgrade · backup · restore
Create init
Interact ls · load · kubeconfig · health · drain · uncordon
Declarative kube · apply
Maintenance prune
Clusters network
EXAMPLES:
# a local Kubernetes cluster with no manifest and no Docker
delonix cluster create --name dev
# what is up, node by node
delonix get clusters
# from zero to VMs plus kubeadm — above one control-plane the load balancer
# comes with it
delonix cluster kubeadm --name lab --network k8s --control-plane 3 --cni none
# hand the kubeconfig to a teammate, or reload it in a fresh shell
delonix cluster kubeconfig dev
SEE ALSO:
delonix cluster kube generate · delonix stack apply · delonix vm create ·
delonix vm image pull
delonix › clustercluster kube
Generate a Kubernetes manifest from a container/pod already running locally.
kube generate — the "ran it locally, now give me the YAML for k8s" path (equivalent to podman generate kube).
Usage: delonix cluster kube <COMMAND>
Commands:
generate Generates a `kind: Pod` from a container (or from every member of a pod) and prints it to stdout
help Print this message or the help of the given subcommand(s)
Options:
-h, --help
Print help (see a summary with '-h')
COMMAND MAP:
Declarative generate
EXAMPLES:
# the Kubernetes YAML for something you already have running locally
delonix cluster kube generate web
SEE ALSO:
delonix container describe · delonix describe · delonix stack apply
delonix › cluster › kubeExemplosExamples
delonix cluster kube generatecluster load
Load local images into a kind-mode cluster's nodes, without a registry.
The equivalent of kind load docker-image: packs each image from the local store and imports it into every running node's containerd.
Usage: delonix cluster load [OPTIONS] <IMAGES>...
Arguments:
<IMAGES>...
Images to load (`repo:tag`, as they appear in `delonix image ls`)
Options:
--name <NAME>
Cluster name. Omit when there is only one — with several, this says which
-h, --help
Print help (see a summary with '-h')
EXAMPLES:
# the image you just built, into every node, with no registry in between
delonix cluster load myapp:dev
# several in one go
delonix cluster load myapp:dev sidecar:dev
# say which cluster, when more than one is up
delonix cluster load myapp:dev --name dev
SEE ALSO:
delonix cluster create · delonix image ls · delonix build · delonix get
delonix › cluster › loadExemplosExamples
delonix build -t app:dev .
delonix cluster load app:dev --name labcluster create
Create a local Kubernetes cluster without a manifest and without Docker.
Native kind mode: starts the kindest/node nodes in the Delonix engine itself and bootstraps them with kubeadm. No flags = 1 control-plane ready to use.
Usage: delonix cluster create [OPTIONS]
Options:
--name <NAME>
Cluster name (prefix of the nodes and the kubeconfig). Omit = invents one (Angolan king + place), so two `create`s in a row do not collide
--api-port <API_PORT>
Host port for the apiserver. Omit = delonix picks a free one (tries 6443; if taken by another cluster, uses a high one)
--workers <WORKERS>
Worker nodes to join (0 = control-plane only, untainted — schedules everything)
[default: 0]
--control-planes <CONTROL_PLANES>
Cluster control-planes (default 1). More than 1 requires a stable endpoint in front of them (LB) — see the error if you ask for >1
[default: 1]
--image <IMAGE>
Node image (default: `kindest/node` pinned by digest)
--pod-subnet <POD_SUBNET>
[default: 10.244.0.0/16]
--service-subnet <SERVICE_SUBNET>
[default: 10.96.0.0/12]
--cni <CNI>
`default` (kindnet, from the image itself) or `none` (node stays NotReady until you apply yours — plain kubeadm behavior)
[default: default]
[possible values: default, none]
--config <CONFIG>
A real `kind` config file (`kind.x-k8s.io/v1alpha4`), the one `kind create cluster --config` reads. delonix honours the fields it can (`nodes[].role`, `name`, `networking.{podSubnet,serviceSubnet, apiServerPort,disableDefaultCNI}`) and REFUSES the rest by name (DX-1707) instead of ignoring them. The config is the source of truth: a value it sets wins over the matching flag's default
-h, --help
Print help (see a summary with '-h')
EXAMPLES:
# a single node: control-plane untainted, so it schedules everything
delonix cluster create --name dev
# one control-plane and two workers
delonix cluster create --name dev --workers 2
# your own CNI instead of kindnet — the node stays NotReady until you apply
# it
delonix cluster create --name dev --cni none
# pin the apiserver to the host port your kubeconfig already expects
delonix cluster create --name dev --api-port 6443
SEE ALSO:
delonix get · delonix cluster load · delonix delete · delonix cluster
kubeadm
delonix › cluster › createExemplosExamples
delonix cluster create --name labdelonix cluster create --name lab --workers 2cluster kubeconfig
Print a cluster's kubeconfig from the local cache (no live SSH).
The same file create/apply/kubeadm already wrote and merged into ~/.kube/config at creation time. Redirect or pipe it as needed.
Usage: delonix cluster kubeconfig [NAME]
Arguments:
[NAME]
Cluster name. Omit when there is only one cached
Options:
-h, --help
Print help (see a summary with '-h')
EXAMPLES:
# the one cluster you have — no name needed
delonix cluster kubeconfig
# a specific one, redirected to a file
delonix cluster kubeconfig lab > lab.yaml
# straight into KUBECONFIG for one shell
export KUBECONFIG=<(delonix cluster kubeconfig lab)
SEE ALSO:
delonix cluster create · delonix cluster kubeadm · delonix cluster apply ·
delonix get
delonix › cluster › kubeconfigLê da CACHE local (<root>/clusters/<nome>-kubeconfig.yaml)
— sem SSH ao vivo. Funciona para os dois tipos de cluster (modo kind e
kubeadm/SSH), que escrevem no mesmo caminho. Não faz merge em
~/.kube/config: isso já acontece automaticamente na criação.
ExemplosExamples
delonix cluster kubeconfigdelonix cluster kubeconfig lab > lab.yamlcluster init
Initialize a project with the cluster manifests (kind/vm/ssh).
Files ALREADY FILLED IN (images included), ready to use without editing anything.
Usage: delonix cluster init [OPTIONS] [DIR]
Arguments:
[DIR]
Project directory (default: the current one)
[default: .]
Options:
--name <NAME>
Project name (default: the directory name)
--image <IMAGE>
Image to use. Omit = fills in with the default image
--force
Overwrite existing files
-h, --help
Print help (see a summary with '-h')
EXAMPLES:
# a project with the cluster manifests already filled in
delonix cluster init
# into a directory of its own, named, with the image you intend to run
delonix cluster init ./lab --name lab --image nginx:alpine
# regenerate over a scaffold you already edited
delonix cluster init --force
SEE ALSO:
delonix cluster apply · delonix cluster create · delonix stack init
delonix › cluster › initExemplosExamples
delonix cluster init ./meu-clustercluster apply
Apply the kind: KubernetesCluster document(s) of a manifest
Usage: delonix cluster apply [OPTIONS]
Options:
-f, --file <FILE>
--cri-bin <CRI_BIN>
`delonix-cri` binary to install on the nodes. Omit = the one next to `delonix`, else the release asset of this version
-h, --help
Print help (see a summary with '-h')
EXAMPLES:
# bootstrap the hosts a manifest declares — idempotent, and with no state
# file to drift
delonix cluster apply -f cloud.yaml
# the manifest in this directory
delonix cluster apply
SEE ALSO:
delonix cluster kubeadm · delonix stack apply · delonix stack validate ·
delonix get
delonix › cluster › applyTodas as entradas do manifesto que chegam a comandos remotos
(controlPlaneEndpoint, subnets, versão) passam por validação estrita antes de qualquer
interpolação — a injecção de comandos via manifesto foi um dos CRÍTICOS encontrados e fechados na
auditoria ofensiva do projecto, com testes a replicar o exploit.
Every manifest field that reaches remote commands
(controlPlaneEndpoint, subnets, version) goes through strict validation before any
interpolation — command injection via the manifest was one of the CRITICAL findings closed in the
project's offensive audit, with tests replicating the exploit.
ExemplosExamples
delonix cluster apply -f cloud.yamlcluster kubeadm
Provision VMs (golden VM image) + kubeadm bootstrap.
From zero to a working cluster, without writing a manifest by hand.
Usage: delonix cluster kubeadm [OPTIONS]
Options:
--name <NAME>
Cluster name (used for `<name>-cp1`/`<name>-w1` VM names and the kubeconfig context). Omit for an auto-generated Angolan name (`<king>-<place>-NN`) — same pattern as auto-named containers and `cluster create` (kind mode)
--control-plane <CONTROL_PLANE>
[default: 1]
--workers <WORKERS>
[default: 2]
--vm-image <VM_IMAGE>
Tag of the golden VM image (`delonix vm image ls`). Omit = uses the only local image that exists
--network <NETWORK>
Network the nodes attach to. Omit and the cluster gets its OWN, created here and named `<cluster>-<hash>` — and removed again by `cluster destroy`. Name one that already exists (`delonix network create`) to attach to it instead; that one is never removed, because you created it
--ssh-key <SSH_KEY>
Private SSH key to use. Omit = generates a new ed25519 pair in `<root>/clusters/<name>/id_ed25519`
--vcpus <VCPUS>
[default: 2]
--memory <MEMORY>
[default: 2G]
--k8s-version <K8S_VERSION>
--pod-subnet <POD_SUBNET>
[default: 10.244.0.0/16]
--service-subnet <SERVICE_SUBNET>
[default: 10.96.0.0/12]
--cni <CNI>
Pod network. `default` = «give me a cluster that works»: a node-local bridge on a ONE-node cluster, and on MORE than one node the engine's HA default cross-node pod network, Cilium, installed and waited for automatically. `none` = install nothing; every node stays NotReady until you apply your own CNI. `cilium`/`calico`/`flannel` = a selectable profile, pinned to a version and an artefact digest, all Supported (D7-measured) — `delonix cluster network profiles` lists them with their support level
[default: default]
[possible values: default, none, cilium, calico, flannel]
--cni-dataplane <CNI_DATAPLANE>
Encapsulation / forwarding mode of the chosen profile. Omit for its default (`vxlan`, the only mode that asks nothing of the network between the nodes). `spec.network.dataplane` in a manifest
--kube-proxy <KUBE_PROXY>
`iptables` (default), `ipvs`, or `none` — the last meaning the CNI replaces kube-proxy, which changes the `kubeadm init` call itself and so cannot be turned on later. `spec.network.kubeProxy`
--cni-mtu <CNI_MTU>
Pod MTU. Omit to compute it from the node MTU and the encapsulation overhead — an MTU that does not fit drops large packets in silence
--node-mtu <NODE_MTU>
The nodes' own MTU, when it is not 1500. Only used to compute and bound `--cni-mtu`
--cni-interface <CNI_INTERFACE>
Node interface the dataplane should use, when autodetection is ambiguous. Omit to let the profile detect it
--multus
Also install Multus, as an EXTENSION over the primary CNI (secondary pod interfaces through `NetworkAttachmentDefinition`)
--hubble
Also install Hubble (Cilium's observability component)
--experimental-cni
Acknowledge that the chosen profile is experimental in this release. Without it, an experimental profile is REFUSED (DX-1705) rather than silently used
--cni-offline
Install the pod network from the local artefact cache only, never from the network. Populate it with `delonix cluster network fetch`
--boot-timeout <BOOT_TIMEOUT>
Seconds to wait for each VM to become reachable over SSH
[default: 300]
--copy-kubeconfig
Wait for every node to report `Ready` (CNI up) before the command returns. It does NOT decide anything about the kubeconfig, despite the name: that is cached to `<root>/clusters/<name>-kubeconfig.yaml` and merged into `~/.kube/config` as its own cluster/user/context (named after `--name`) on EVERY run, as soon as `kubeadm init` has written it — so the commands a later failure tells you to run can actually run. A pod-network profile waits with or without this flag
--etcd-cluster <ETCD_CLUSTER>
Auto-provision N more VMs as a DEDICATED etcd cluster (delonix generates its own CA + certs and bootstraps it) instead of the default `stacked` etcd (co-located with the control-planes). Use an ODD number for a well-defined quorum (3, 5, ...) — 1 is allowed for dev/test but has no HA (a single point of failure). Omit for today's default behavior
--cri-bin <CRI_BIN>
`delonix-cri` binary to install on the nodes. Omit = the one next to `delonix`, else the release asset of this version
--use-context
Point `kubectl` at this cluster once it is up, so a bare `kubectl get nodes` reaches it. Without this flag a `~/.kube/config` that already selects a usable context keeps it — the cluster's context is merged either way, and the command to switch to it is printed
-h, --help
Print help (see a summary with '-h')
EXAMPLES:
# VMs from the golden image plus kubeadm, without writing a manifest by hand
delonix cluster kubeadm --name lab --network k8s --workers 0
# HA: above one control-plane a HAProxy load balancer is provisioned and
# used as the endpoint
delonix cluster kubeadm --name lab --network k8s --control-plane 3 --workers 3 --cni none
# more than one node: the default CNI only serves one, so bring your own and
# apply it after the bootstrap
delonix cluster kubeadm --name lab --network k8s --workers 2 --cni none
# merge the kubeconfig into your own only after every node reports Ready
delonix cluster kubeadm --name lab --network k8s --workers 0 --copy-kubeconfig
# etcd on VMs of its own instead of stacked on the control-planes
delonix cluster kubeadm --name lab --network k8s --workers 0 --etcd-cluster 3
SEE ALSO:
delonix cluster apply · delonix get · delonix vm ls · delonix vm image pull
delonix › cluster › kubeadm--control-plane > 1 provisiona automaticamente uma VM
extra a correr HAProxy (L4, passthrough — a TLS do apiserver termina sempre no control-plane real)
à frente da porta 6443 de cada control-plane, e usa-a como controlPlaneEndpoint — sem
flag nova, dispara sozinho a partir do número de control-planes pedido. --name é
opcional (gera um nome livre no mesmo padrão dos containers); sem --vm-image, resolve
a única imagem VM dourada local ou descarrega-a do repositório oficial automaticamente. Progresso
por etapa, estilo kind create cluster (cada etapa fecha com ✓/✗), degrada para uma
linha por etapa sem TTY (pipes/CI).
--control-plane > 1 automatically provisions an
extra VM running HAProxy (L4, passthrough — the apiserver's TLS always terminates on the real
control-plane) in front of port 6443 on each control-plane, and uses it as
controlPlaneEndpoint — no new flag, it triggers on its own from the number of
control-planes requested. --name is optional (generates a free name in the same
pattern as containers); without --vm-image, it resolves the single local golden VM
image or downloads it from the official repository automatically. Step-by-step progress,
kind create cluster-style (each step closes with ✓/✗), degrading to one line per step
with no TTY (pipes/CI).
ExemplosExamples
delonix cluster kubeadm --name lab --control-plane 1 --workers 2 --cni nonedelonix cluster kubeadm --name lab --control-plane 2 --workers 3 --cni nonedelonix cluster kubeadm --name lab --control-plane 2 --etcd-cluster 3 --cni noneLaboratórioLab
Um comando, do zero a um cluster Kubernetes real a correr —
sem Docker, sem containerd, com delonix-cri como runtime.
delonix cluster kubeadm --control-plane 1 --workers 0
export KUBECONFIG=~/.delonix/clusters/*-kubeconfig.yaml
kubectl get nodesOne command, from zero to a real Kubernetes cluster running — no
Docker, no containerd, with delonix-cri as the runtime.
delonix cluster kubeadm --control-plane 1 --workers 0
export KUBECONFIG=~/.delonix/clusters/*-kubeconfig.yaml
kubectl get nodesDesafioChallenge
Constrói uma imagem local com delonix build,
importa-a directamente no containerd de cada nó com cluster load (sem passar por
registo nenhum) e corre um pod com imagePullPolicy: Never a usá-la.
delonix cluster load minha-app:v1Build a local image with delonix build, import it
directly into every node's containerd with cluster load (no registry involved), and
run a pod with imagePullPolicy: Never using it.
delonix cluster load my-app:v1