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: delonix cluster [OPTIONS] <COMMAND>

Commands:
  create      Create a local Kubernetes cluster **without a manifest and without Docker**
  destroy     Remove a kind-mode cluster entirely — nodes, network, kubeconfig, `~/.kube/config` entry
  kubeadm     Provision VMs (golden VM image) + `kubeadm` bootstrap
  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
  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 (see a summary with '-h')

COMMAND MAP:
  Lifecycle    stop · start · destroy · create · kubeadm · upgrade
  Create       init
  Interact     ls · load · kubeconfig · health · drain · uncordon
  Declarative  kube · apply
  Maintenance  prune

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

  # 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 image vm pull

  delonix › cluster

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: delonix 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 (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 › kube

ExemplosExamples

Gerar manifestos Kubernetes a partir de um recurso Delonix
Generate Kubernetes manifests from a Delonix resource
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: delonix 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 (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 › load

ExemplosExamples

Levar uma imagem local para dentro dos nós (o kind load, sem registo)
Get a local image into the nodes (kind load, no registry)
delonix build -t app:dev .
delonix cluster load app:dev --name lab

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: delonix 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 (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 › create

ExemplosExamples

Cluster local em modo kind (containers como nós, sem Docker)
Local cluster in kind mode (containers as nodes, no Docker)
delonix cluster create --name lab
Com workers
With workers
delonix cluster create --name lab --workers 2

cluster 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 [OPTIONS] [NAME]

Arguments:
  [NAME]
          Cluster name. Omit when there is only one cached

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 (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 › kubeconfig

Lê 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

O único cluster que existe — não precisa de nome
delonix cluster kubeconfig
Um específico, redireccionado para um ficheiro
delonix cluster kubeconfig lab > lab.yaml

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: delonix 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 (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 › init

ExemplosExamples

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

cluster apply

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

Usage: delonix 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

      --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 › apply

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.

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

Bootstrap num manifesto `kind: KubernetesCluster`
Bootstrap from a `kind: KubernetesCluster` manifest
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: delonix 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

      --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:
  # VMs from the golden image plus kubeadm, without writing a manifest by hand
  delonix cluster kubeadm --name lab --network k8s

  # 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

  # merge the kubeconfig into your own only after every node reports Ready
  delonix cluster kubeadm --name lab --network k8s --copy-kubeconfig

  # etcd on VMs of its own instead of stacked on the control-planes
  delonix cluster kubeadm --name lab --network k8s --etcd-cluster 3

SEE ALSO:
  delonix cluster apply · delonix get · delonix vm ls · delonix image vm 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

Do zero: 1 control-plane + 2 workers
From scratch: 1 control-plane + 2 workers
delonix cluster kubeadm --name lab --control-plane 1 --workers 2
HA: 2 control-planes + 3 workers (HAProxy automático)
HA: 2 control-planes + 3 workers (automatic HAProxy)
delonix cluster kubeadm --name lab --control-plane 2 --workers 3
Etcd externo dedicado (3 VMs extra, quórum ímpar)
Dedicated external etcd (3 extra VMs, odd quorum)
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