Skip to main content

k0rdent 1.0 vs Plain Cluster API: What a Super Control Plane Actually Buys Your Fleet

15 min readDora NodaDora Noda
Share

On February 6, 2025, Mirantis launched k0rdent as the first open-source Distributed Container Management Environment (DCME) — a "super control plane" for Kubernetes fleets. Six months later, on August 7, 2025, the CNCF announced k0rdent v1.0.0 as a production-grade, template-driven platform for managing clusters and services at scale. The pitch is ambitious: one declarative API to provision, upgrade, observe, and cost-track every cluster you own, from bare metal to managed cloud.

If you already run Cluster API (CAPI) with a Hetzner provider (CAPH) and Flux CD — the stack underneath bex — the honest question is whether k0rdent replaces plumbing you already have, or adds a layer you don't yet need. The short answer, with receipts:

DimensionPlain Cluster API (CAPH + Flux)k0rdent DCME (KCM + KSM + KOF)
Cluster provisioning200–400 lines of YAML per Cluster~40-line ClusterDeployment referencing a versioned template
Service / add-on rolloutFlux HelmRelease/Kustomization per cluster, by handServiceTemplate + MultiClusterService with label selectors, driven by Sveltos
Upgrade path safetyManual version bumps, no upgrade-path validationServiceTemplateChain with explicit sequential vs direct upgrade semantics
Multi-cluster visibilityOne kubectl context at a timeKOF: VictoriaMetrics + OpenCost across mothership and workload clusters, GPU tracking included
Provider breadthOne provider per management cluster (CAPH, CAPD, etc.)Single API across AWS, Azure, GCP, OpenStack, vSphere, k0smotron (hosted control planes)
Operational overheadLean: CAPI controllers + FluxOpinionated: extra CRDs, mothership control plane, Sveltos, Velero-coupled backups

For a fleet under ten clusters on a single provider, plain CAPI wins on simplicity. For a fleet spanning providers, regions, and a catalog of shared services, k0rdent's opinionated DCME starts to pay for itself. Below is what actually shipped, where each layer helps, and where it adds weight a lean platform like bex should consciously defer.

What k0rdent v1.0 Actually Shipped

k0rdent is not a replacement for Cluster API — it is a distribution and opinions layer built on top of it. The CNCF announcement frames it as a DCME: a Kubernetes-native environment that makes fleet management composable, the same way Kubernetes made machine management declarative. The project launched publicly on February 6, 2025 via Mirantis and reached v1.0.0 on August 7, 2025 with three core components, each handling a distinct day-0 to day-2 concern:

  • KCM (k0rdent Cluster Manager): Lifecycle for Kubernetes clusters themselves — provisioning, scaling, upgrades, and remediation — powered directly by Cluster API. KCM wraps the usual CAPI sprawl (Cluster, MachineDeployment, control-plane providers, infrastructure providers, bootstrap providers) behind a single ClusterDeployment custom resource. Instead of authoring and version-pinning every CAPI object, an operator picks a ClusterTemplate (a versioned, immutable template) and supplies a credential and config block for the specifics. The result is roughly 30–50 lines of YAML for a new cluster instead of several hundred. KCM also handles template validation, provider distribution, and, since late in the v0 cycle, Velero-backed backup and recovery for workload clusters and the mothership itself.

  • KSM (k0rdent State Manager / k0rdent Service Management): Service and add-on orchestration across the fleet. Where CAPI stops at "the cluster exists," KSM answers "what runs on it." Operators define ServiceTemplate objects for reusable services (Ingress NGINX, cert-manager, Istio, policy engines, monitoring stacks) and bind them to clusters via MultiClusterService selectors. Under the hood, KSM delegates rendering and distribution to Project Sveltos, with Helm as the package format and Flux reconciliation semantics. Versioning and upgrade policy live in ServiceTemplateChain, which models explicit upgrade paths — for example, that ingress-nginx 4.11.0 may go directly to 4.13.0 or must step through 4.12.0 — with shared visibility into which versions are available and which chains apply. In early k0rdent, service chains had no versioning and ambiguous selection when multiple chains referenced one template; v1.0's Chain → Template hierarchy with first-class versioning closed that gap.

  • KOF (k0rdent Observability & FinOps): Centralized observability and cost visibility. KOF ships as a composable stack integrating VictoriaMetrics for metrics, OpenCost for Kubernetes-native cost attribution, and centralized logging and dashboards. It distinguishes mothership (management cluster) from regional and child-cluster telemetry, including control-plane health, GPU utilization tracking (relevant for AI workloads), and per-cluster, per-namespace, per-workload cost reporting. For a platform team that currently glues together a separate Prometheus, Grafana, and ad-hoc cost spreadsheet per provider, KOF's claim is a single pane that speaks Kubernetes natively.

A fourth cross-cutting capability threads through all three: IPAM and DNS automation via Cluster API's In-Cluster IPAM Provider, automating address allocation and DNS record lifecycle alongside machine provisioning rather than leaving them as out-of-band manual steps.

The v1.0 release also tightened production hardening: provider version matrices were pinned and tested (CAPI 1.9.x, CAPA/CAPZ/CAPG at their 2.x/1.x stable lines, k0smotron, Sveltos 0.50+), global Helm values propagation was verified against actual helm template rendering, and managed vs adopted cluster semantics were clarified so templates that make no sense for provider-managed control planes (EKS, GKE, AKS) or pre-existing adopted clusters are not applied.

Just after v1.0, both k0rdent and its companion k0s distribution achieved CNCF Certified Kubernetes AI Conformance at Kubernetes v1.35 (announced July 22, 2026), a signal that the DCME's fleet-wide provisioning story now claims coverage for the GPU and inference workloads many platforms still treat as exceptions.

What Plain Cluster API Already Gives You — and Where It Stops

If you run bex today, your fleet's control plane is Cluster API plus a Hetzner provider plus Flux CD, and that already covers more than the "I need a DCME" narrative implies.

What plain CAPI does well. A CAPI management cluster is a reconciliation engine for machines: declare Cluster, HetznerCluster, KubeadmControlPlane, HetznerMachineTemplate, and MachineDeployment, and the controllers drive real Hetzner Cloud servers into existence, join them to the right control plane, and keep them there. Machine health checks, rolling upgrades, and node remediation all work within that model. For a single-provider fleet on Hetzner — which is precisely bex's default and the place platform teams should start — plain CAPI plus CAPH is the only provisioning layer you need. No additional CRD, no extra controller, no translation layer between your intent and the provider's API.

Flux closes the loop on the workload side. Once the cluster exists, Flux's HelmRelease and Kustomization controllers reconcile application and platform state from Git: the same Git commit that declares the desired cluster size also declares which Ingress controller version, which observability stack, and which tenant applications belong on that cluster. Rollback is a git revert. The model is boring in the best way: it works the same on one cluster as on ten, because each cluster is an independent reconciliation target with the same source-of-truth shape.

Where the gap appears. Plain CAPI stops at the cluster boundary. It provisions clusters; it does not distribute a consistent service catalog across them. Concretely, if you want cert-manager v1.14 on every dev cluster and v1.15 on prod, with an explicit policy for how a given cluster graduates between those versions, plain CAPI offers no primitive for it. You end up with one Flux Kustomization per cluster per add-on, copied or templated by hand, with upgrade sequencing enforced only by the order in which someone merges pull requests. There is no first-class ServiceTemplate or MultiClusterService to query when an operator asks "which clusters are still on the old Ingress and why."

Two more gaps inherit that per-cluster scope: observability and cost. A plain CAPI fleet typically runs one Prometheus/Thanos stack per cluster or a hand-rolled central aggregator, and one cost model per provider. There is no Fleet-wide "total GPU-hours consumed by tenant X across Hetzner and AWS dev clusters last week" without building it yourself — which is exactly the seam KOF claims.

The clearest example of the hand-rolled tax is multi-provider intent. A plain CAPI management cluster can watch multiple infrastructure providers (CAPH, CAPA, CAPZ), but the YAML for an AWS cluster looks nothing like the YAML for a Hetzner cluster, and there is no shared template language to say "give me a production-shaped cluster on whatever provider this environment maps to." Each provider's cluster shape is its own bespoke directory of manifests. k0rdent's ClusterTemplate is an opinion about that problem: a provider-specific template versioned and curated once, instantiated declaratively per environment.

Where k0rdent Adds Value: Three Specific Wins

Against that baseline, k0rdent's DCME buys three concrete things that otherwise become glue code a team writes and then maintains.

1. Template hierarchy that makes scale declarative, not copy-paste. The ClusterDeploymentClusterTemplate and MultiClusterServiceServiceTemplateServiceTemplateChain chain collapses two dimensions of sprawl at once. On the cluster side, a ClusterDeployment like this is the entire declaration for a production cluster on Hetzner via a community-maintained hosted-control-plane template:

yaml
apiVersion: k0rdent.mirantis.com/v1beta1
kind: ClusterDeployment
metadata:
  name: prod-hetzner-1
  namespace: kcm-system
spec:
  template: hetzner-hosted-cp
  credential: hetzner-credential
  config:
    region: fsn1
    apiHost: api.prod-cluster.example.com
    konnectivityHost: konnectivity.prod-cluster.example.com

The template itself carries the rest — control-plane sizing, machine types, bootstrap config, CNI choices — versioned and authored once. Compare that to the equivalent plain CAPI directory of Cluster, HetznerCluster, KubeadmControlPlane, and placement manifests, each copy with environment-specific mutations littered across overlays.

On the services side, MultiClusterService with a label selector is how one platform decision — "every dev-tier cluster gets ingress-nginx 4.13.0" — becomes one object rather than N Flux overlays:

yaml
apiVersion: k0rdent.mirantis.com/v1beta1
kind: MultiClusterService
metadata:
  name: global-ingress
spec:
  clusterSelector:
    matchLabels:
      cluster-deployment/tier: dev
  services:
    - template: ingress-nginx-4-13-0
      priority: 200

KSM, via Sveltos, renders the Helm chart against matching clusters, reports rollout status per target, and — crucially — surfaces upgrade availability through the ServiceTemplateChain. That chain encodes policy: "4.11.0 may go directly to 4.13.0 in staging, but must step through 4.12.0 in production," a rule plain CAPI has nowhere to put. Earlier k0rdent releases allowed multiple chains to ambiguously reference a single template with no visibility into which path applied; the v1.0 hierarchy fixes that.

2. Unified observability and FinOps across the DCME. KOF's integration of VictoriaMetrics and OpenCost into one stack that aggregates the mothership plus every workload cluster is, for a platform team, the difference between seeing fleet-wide cost and seeing N per-cluster dashboards. GPU utilization tracking, control-plane health per workload cluster, and cost attribution by cluster, namespace, and workload are the surfaces that matter once a platform hosts both web workloads and agent/inference jobs. For bex, whose default is still a single CPU/RAM Hetzner fleet without GPU nodes, the GPU surface is not load-bearing today — but the cost-consolidation surface is. A self-hosted PaaS collects egress, compute, and storage charges via Hetzner billing and per-cluster metrics; KOF's pitch is that those numbers arrive in one OpenCost view rather than reconciled by hand.

3. Multi-provider fleet management from one API. k0rdent's DCME is intentionally provider-agnostic: one ClusterDeployment shape provisions against AWS (CAPA), Azure (CAPZ), GCP (CAPG), OpenStack (CAPO), vSphere (CAPV), or k0smotron-managed hosted control planes, distinguished by ClusterTemplate and credential rather than by bespoke manifest trees. For a platform team that knows the next hard requirement will be "the same fleet, with a second provider for sovereign or regional reasons," that single API surface is the actual asset — not just the current cluster count, but the cost of adding a provider in the future. Plain CAPI can already watch multiple providers; k0rdent makes them feel like one platform.

Where k0rdent Adds Weight: The Honest Tradeoffs

Every opinions layer trades freedom for weight, and k0rdent's choices are real enough that a lean fleet should name them before adopting.

Extra CRDs and an extra controller path. A minimal bex fleet today runs a handful of well-understood controllers: CAPI core, CAPH, control-plane and bootstrap providers, Flux. k0rdent adds ClusterDeployment, ClusterTemplate, ServiceTemplate, MultiClusterService, ServiceTemplateChain, and their status controllers, plus Sveltos as the service-distribution engine and Velero as the backup substrate. Each is another API to learn, another upgrade cadence to coordinate, and another reconciler whose failure surface the platform team owns. For a fleet that currently provisions only Hetzner CX/CPX nodes and rolls add-ons via Flux, that is net new complexity without yet a problem large enough to justify it.

The mothership as a single control plane. k0rdent centralizes fleet lifecycle in a management ("mothership") cluster. That cluster is a single point of topology coordination: if it is unhealthy, new clusters do not provision, service rollouts do not distribute, and fleet-wide reconciliation stalls. k0rdent hardens this with Velero-coupled backup/restore and the ability to self-manage the mothership's own lifecycle, but the blast radius is structurally larger than N independent CAPI management clusters each watching one provider. For a fleet whose blast radius today is bounded per-management-cluster, consolidating into one mothership is a risk decision, not just an operational simplification.

Sveltos and Velero as opinionated dependencies. The service-distribution and backup choices are real dependencies, not optional plugins. Teams that have already standardized on Flux-only app distribution or a different backup strategy will find k0rdent's opinions either duplicative or constraining. The DCME earns its keep only if the team prefers its chosen distribution and backup semantics over whatever they already run.

Learning curve for the platform team. k0rdent shrinks per-cluster YAML by centralizing shape into templates, but it adds a system-level learning curve: how to author or curate a ClusterTemplate, how to model ServiceTemplateChain upgrade intent, how MultiClusterService selectors compose, how KOF's regional vs child storage and DNS integrations are wired. For a two- or three-person platform team that can already reason cleanly about a CAPI+Flux repo, that curve is steeper than the copy-paste cost it replaces — at least until cluster counts and service diversity make the copy-paste cost the larger drag.

Decision Framework: When to Adopt, When to Wait

The right choice hinges on fleet shape, not philosophy:

Fleet signalPlain CAPI + Flux winsk0rdent DCME wins
Cluster count1–8 clusters, same provider10+ clusters, or clear path to that within a year
Provider diversitySingle provider (Hetzner, or Hetzner + local Docker)Multi-cloud or on-prem + cloud, sovereign splits, bare-metal mix
Service catalog breadthSmall, stable set (Ingress, cert-manager, monitoring)Large or fast-changing catalog with explicit upgrade-path policy
Platform team size1–3, prefers minimal control plane3+, benefits from templated distribution and fleet-wide policy
Cost/observability needPer-cluster metrics sufficientFleet-wide cost attribution, GPU-aware reporting, one pane for mothership + workload clusters

For bex today — a single-provider Hetzner fleet managed by CAPH, with Flux-distributed services, no GPU node pools, and a render-compatible API as the tenant-facing surface — the recommendation is deliberate: stay on plain CAPI plus Flux, and keep the DCME adoption criteria explicit. That criteria list is:

  • A second infrastructure provider becomes a hard requirement (sovereign data residency, regional redundancy, or a managed-control-plane off-ramp) rather than a nice-to-have comparison.
  • The service catalog graduates past hand-auditable: six-plus shared platform services with non-trivial upgrade-path rules (direct vs sequential across environments) that the team can articulate as policy rather than ad-hoc merge discipline.
  • Cost reporting graduates from "what did Hetzner bill last month" to "which namespace + workload + cluster drove last month's cost at fleet scope," a question KOF's OpenCost surface answers natively.

When one or more of those fires, k0rdent is worth a bounded pilot: one mothership, two templates (one single-provider standing, one second-provider proof-of-concept), and one MultiClusterService that the team already manages the hard way today. Measure the before/after in lines of fleet YAML removed, upgrade-policy decisions made visible, and operator time per cluster lifecycle event — not in architecture diagrams.

The Governance Read

The deeper k0rdent bet is not about a particular CRD — it is that fleet operations converge on a Kubernetes-native, template-driven substrate rather than remaining bespoke glue around CAPI primitives. Plain CAPI proved that a Kubernetes reconciliation loop is the right way to own machine lifecycle; k0rdent argues that the next two layers up — service distribution and fleet-wide observability/FinOps — belong inside the same reconciliation loop, not in external automation that re-creates what the control plane already does.

Whether that wager pays for a given fleet depends on fleet shape, not on the elegance of the wager. A lean PaaS on owned Hetzner hardware does not need a DCME to deploy and operate apps well. It needs a provider it trusts, a Git repo that reconciles, and a fleet story the on-call team can reason about at 2 a.m. Plain CAPI plus Flux is that story today. k0rdent's contribution is making the growth path beyond it — more clusters, more providers, more services, more cost surfaces — a path with fewer hand-rolled seams than the one before it.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex