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).

Usage: dlx cluster [OPTIONS] <COMMAND>

Commands:
  init     Initialize a project with the cluster manifests (kind/vm/ssh) — files ALREADY FILLED IN (images included), ready to use without editing anything
  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
  ls       List the clusters and the state of their nodes [alias: list]
  delete   Remove a kind-mode cluster (stops and deletes the nodes + kubeconfig)
  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
  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`)
  apply    Apply the `kind: Cluster` document(s) of a manifest
  kubeadm  Provision VMs (golden VM image) + `kubeadm` bootstrap — from zero to a working cluster, without writing a manifest by hand
  help     Print this message or the help of the given subcommand(s)

Options:
      --l18n <en|pt>  Output language: `en` (default) or `pt` (Portuguese, pt_AO). Also settable via `$DELONIX_L18N`. Global — works before any subcommand
  -h, --help          Print help

cluster 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: dlx cluster kube [OPTIONS] <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:
      --l18n <en|pt>  Output language: `en` (default) or `pt` (Portuguese, pt_AO). Also settable via `$DELONIX_L18N`. Global — works before any subcommand
  -h, --help          Print help

Exemplos

Gerar manifestos Kubernetes a partir de um recurso Delonix
delonix cluster kube generate

cluster 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: dlx cluster load [OPTIONS] <IMAGES>...

Arguments:
  <IMAGES>...  Images to load (`repo:tag`, as they appear in `delonix image ls`)

Options:
      --l18n <en|pt>  Output language: `en` (default) or `pt` (Portuguese, pt_AO). Also settable via `$DELONIX_L18N`. Global — works before any subcommand
      --name <NAME>   Cluster name. Omit when there is only one — with several, this says which
  -h, --help          Print help

Exemplos

Levar uma imagem local para dentro dos nós (o kind load, sem registo)
delonix build -t app:dev .
delonix cluster load app:dev --name lab

cluster delete

Remove a kind-mode cluster (stops and deletes the nodes + kubeconfig)

Usage: dlx cluster delete [OPTIONS]

Options:
      --l18n <en|pt>  Output language: `en` (default) or `pt` (Portuguese, pt_AO). Also settable via `$DELONIX_L18N`. Global — works before any subcommand
      --name <NAME>   [default: delonix]
  -h, --help          Print help

Exemplos

Apagar o cluster e os seus nós
delonix cluster delete --name lab

cluster ls

List the clusters and the state of their nodes

Usage: dlx cluster ls [OPTIONS]

Options:
      --l18n <en|pt>  Output language: `en` (default) or `pt` (Portuguese, pt_AO). Also settable via `$DELONIX_L18N`. Global — works before any subcommand
  -h, --help          Print help

Exemplos

Que clusters existem neste host
delonix cluster ls

cluster 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: dlx cluster create [OPTIONS]

Options:
      --l18n <en|pt>
          Output language: `en` (default) or `pt` (Portuguese, pt_AO). Also settable via `$DELONIX_L18N`. Global — works before any subcommand
      --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]
  -h, --help
          Print help

Exemplos

Cluster local em modo kind (containers como nós, sem Docker)
delonix cluster create --name lab
Com workers
delonix cluster create --name lab --workers 2

cluster init

Initialize a project with the cluster manifests (kind/vm/ssh) — files ALREADY FILLED IN (images included), ready to use without editing anything

Usage: dlx cluster init [OPTIONS] [DIR]

Arguments:
  [DIR]  Project directory (default: the current one) [default: .]

Options:
      --l18n <en|pt>   Output language: `en` (default) or `pt` (Portuguese, pt_AO). Also settable via `$DELONIX_L18N`. Global — works before any subcommand
      --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

Exemplos

Scaffold de um cloud.yaml para cluster apply
delonix cluster init ./meu-cluster

cluster apply

Apply the kind: Cluster document(s) of a manifest

Usage: dlx cluster apply [OPTIONS]

Options:
  -f, --file <FILE>   
      --l18n <en|pt>  Output language: `en` (default) or `pt` (Portuguese, pt_AO). Also settable via `$DELONIX_L18N`. Global — works before any subcommand
  -h, --help          Print help

Todas 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.

Exemplos

Bootstrap num manifesto `kind: Cluster`
delonix cluster apply -f cloud.yaml

cluster kubeadm

Provision VMs (golden VM image) + kubeadm bootstrap — from zero to a working cluster, without writing a manifest by hand

Usage: dlx cluster kubeadm [OPTIONS] --network <NETWORK>

Options:
      --l18n <en|pt>
          Output language: `en` (default) or `pt` (Portuguese, pt_AO). Also settable via `$DELONIX_L18N`. Global — works before any subcommand
      --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 image --vm ls`). Omit = uses the only local image that exists
      --network <NETWORK>
          Already-created network (`delonix network create`) — no magic default
      --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]
      --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 fetching the kubeconfig, then MERGE it into `~/.kube/config` as its own cluster/user/context (named after `--name`) instead of leaving other clusters' contexts untouched only by accident. Without this, the kubeconfig is still written to `<root>/clusters/<name>-kubeconfig.yaml` right after `kubeadm join`, before the CNI has necessarily finished
      --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
  -h, --help
          Print help

--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).

Exemplos

Do zero: 1 control-plane + 2 workers
delonix cluster kubeadm --name lab --control-plane 1 --workers 2
HA: 2 control-planes + 3 workers (HAProxy automático)
delonix cluster kubeadm --name lab --control-plane 2 --workers 3
Etcd externo dedicado (3 VMs extra, quórum ímpar)
delonix cluster kubeadm --name lab --control-plane 2 --etcd-cluster 3

Laborató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 2
export KUBECONFIG=~/.delonix/clusters/*-kubeconfig.yaml
kubectl get nodes

One 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 2
export KUBECONFIG=~/.delonix/clusters/*-kubeconfig.yaml
kubectl get nodes

DesafioChallenge

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:v1

Build 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