Skip to main content

Replace Is a Disaster on Bare Metal: What Talos Linux's In-Place Philosophy Means for Your Cluster API Fleet

9 min readDora NodaDora Noda
Share
On this page

"Whenever you change something, Cluster API says it wants to replace that machine," Sidero Labs founder Andrew Smirnov told The New Stack. "This works great in the cloud, but on bare metal, that's a disaster." Sidero tried building on Cluster API first. Then they walked away and built Talos Linux and Omni around the opposite principle: "Changes in place, upgrades in place, everything in place."

Here is the verdict up front, because this post exists to settle one question: is that a real operational tradeoff, or a solved problem? It is real — replacing a bare-metal node costs an order of magnitude more disruption than replacing a cloud VM, and no API abstraction changes that physics.

But the gap is narrower than Sidero's quote suggests. Cluster API v1.12, released in January 2026, learned to update machines in place, and the Talos ecosystem's own Cluster API providers are adopting the same mechanism. If you run a CAPH-managed Hetzner fleet, you probably do not need to switch platforms. You need to upgrade Cluster API and turn the new behavior on.

What follows is the runbook-level comparison behind that verdict: what a replace-based node upgrade actually costs on metal, how Talos and Omni do it instead (including the parts of the in-place story nobody advertises), and the three concrete steps that close most of the gap without leaving Cluster API.

What "replace the machine" costs on bare metal

Start with the runbook, because the philosophy debate is really a runbook debate. On a Cluster API fleet provisioned onto Hetzner hardware (CAPH), a node OS or kubelet upgrade before v1.12 goes like this:

  1. You edit the Machine spec — a new image, a new kubelet version, a changed label.
  2. Cluster API creates a replacement Machine. On cloud infra that means one API call and a fresh VM in a minute or two. On bare metal it means reprovisioning a physical server: the infra provider must reset the box, netboot or reimage it, and wait for it to come back.
  3. The new node bootstraps, joins the cluster, and workloads drain off the old node onto it.
  4. The old Machine is deleted. For a control-plane node, that means an etcd member removal and re-add — quorum churn on every single upgrade step, serialized across the control plane.

Step 2 is where the cloud mental model breaks. A bare-metal server cannot be conjured; if you run three control-plane nodes and want a rolling replace, you need a fourth machine standing by, or you accept running degraded while each box is reimaged. BMC-mediated resets are flakier than cloud API calls — an IPMI hang turns a routine upgrade into hands-on recovery. And every replace cycle replays the riskiest part of provisioning (bootstrapping, joining, etcd membership) instead of skipping it.

Summarized against the in-place alternative:

Upgrade stepReplace-the-machine (CAPI pre-v1.12 on metal)In-place (Talos/Omni model)
Provisioning work per nodeFull reimage + reboot + rejoinNone — same machine, new image staged
Spare capacity neededA free box per rolling slotNone beyond normal headroom
Control-plane risk per nodeetcd member removed and re-addedetcd never leaves; kubelet/k8s restarts in place
Failure modeNew node never joins; old node already drainedUpgrade fails; node reboots back to previous image
Config-change costAny spec edit rolls the nodeOnly opted-in fields trigger any action at all

That table is the entire reason Omni exists. Sidero's bet is that on metal, the replace cycle's failure modes dominate everything else, so the platform should be architected to never run that cycle for routine change.

How Talos and Omni do it instead — and what it costs

Talos Linux is an OS built for exactly one job: running Kubernetes. It is immutable (read-only root filesystem), minimal, and API-only — no SSH, no shell, no package manager. Every node interaction goes over a mutual-TLS gRPC API through talosctl. That sounds austere until you see what it buys: because the whole OS is a single versioned image, an "upgrade" is staging a new image and rebooting into it, with the previous image retained for rollback. There is no package-by-package drift to reconcile, because there are no packages.

Omni is the fleet layer on top. Machines boot a Talos image associated with your Omni account, phone home over SideroLink (a WireGuard tunnel), and show up as unallocated inventory; you attach them to clusters from a UI or omnictl. Upgrades roll node by node in place. You can run Omni as Sidero's SaaS or self-host it — it ships as a Go binary/Docker container with embedded etcd, good into the low hundreds of nodes — and there is a free tier for homelab-scale use.

An honest accounting has to include the in-place side's own costs, which the marketing never leads with:

  • Failed upgrades still reboot the node. A/B images make rollback fast, but a bad image still takes the node down until the rollback completes. In-place narrows the blast radius; it does not eliminate reboots.
  • Omni becomes load-bearing infrastructure. Either you depend on Sidero's SaaS for your management plane, or you self-host an Omni instance that now needs its own backups, upgrades, and availability story. The SideroLink tunnel and the Image Factory fetch on first boot are new dependencies in your boot path — outbound HTTPS to Sidero's infrastructure is required at provision time.
  • In-place mutation invites drift. When machines are never recreated from a template, the distance between "what the declaration says" and "what the box actually is" can only grow. Replace-based systems get drift correction for free — every roll rebuilds from source. In-place systems must invest in it deliberately.
  • It is a second control plane to learn. Omni's machine classes, templates, and cluster templates are a real API surface with real concepts. Adopting Omni is not adopting "less machinery"; it is adopting different machinery.

So the tradeoff is genuine: replace-the-machine buys you drift-free declarative state at the price of a brutal per-change cycle on metal; in-place buys you a cheap per-change cycle at the price of a stateful fleet manager you must now operate. Which leads to the twist.

The twist: Cluster API learned to do it in place

On January 27, 2026, the Cluster API project shipped v1.12 with two headline features, presented by SIG lead Fabrizio Pandini: in-place updates and chained upgrades. The mechanics matter more than the names.

In-place updates work through an update extension (a Runtime SDK extension): when you change a Machine's desired state, Cluster API now picks the best tool for that specific change. Eligible edits — the safe, low-risk spec changes — are applied directly to the existing Machine without replacement. Only changes that genuinely require a fresh box still trigger a rollout. Both KubeadmControlPlane and MachineDeployment objects support it.

Chained upgrades solve the adjacent annoyance: clusters on managed topologies can now jump multiple Kubernetes minor versions in one declared move, with Cluster API computing the upgrade plan, instead of stepping through each minor one at a time.

Two honest limits, because this post promised no hand-waving:

  1. Kubernetes version bumps still replace. In-place covers eligible machine-spec changes; moving the Kubernetes version itself still rolls nodes the classic way. The most disruptive upgrade you run is the one v1.12 changes least.
  2. One extension per hook. Cluster API allows only one Runtime Extension per hook, so the in-place extension cannot coexist with another extension on the same hook — a real constraint for fleets with custom extension chains.

And here is the detail that reframes the whole Talos-vs-CAPI narrative: Talos works with Cluster API. The community cluster-api-bootstrap-provider-talos (CABPT) and cluster-api-control-plane-provider-talos (CACPPT) projects put Talos nodes under CAPI management, and as of an August 2026 design doc, CABPT is implementing v1.12-style in-place updates for TalosControlPlane itself — replicating what KubeadmControlPlane does. Sidero's divergence was Omni-vs-CAPI, not Talos-vs-CAPI. "Talos nodes, CAPI-managed, updated in place" is not a contradiction; it is the middle path the ecosystem is actively building.

The verdict for a CAPH-managed Hetzner fleet

Put it together and the 2026 answer is narrower than either camp's pitch. Sidero was right about the physics: on bare metal, replace-per-change is genuinely expensive, and an immutable image OS that upgrades by reboot is the right node substrate whether or not you adopt Omni. But "Cluster API always replaces" stopped being true in January 2026. For a team already running a CAPH-managed fleet on Hetzner, the rational move is a three-step program, not a platform migration:

  1. Upgrade the management cluster to Cluster API v1.12+ and enable the in-place update extension, so routine Machine spec edits stop triggering full reprovision cycles. Test it in staging first: apply a low-risk spec change and confirm via kubectl describe on the Machine that the controller picks the in-place strategy.
  2. Audit which of your changes are in-place-eligible and which still roll. OS/kubelet image bumps and Kubernetes version upgrades still replace — plan those as maintenance windows with spare capacity. Everything eligible now rides the cheap path, which is most day-to-day change.
  3. Evaluate Talos as a node OS independently of Omni. If your fleet's pain is node-substrate reliability (drift, SSH sprawl, snowflake boxes), CABPT/CACPPT lets you adopt Talos images under your existing CAPI management. Reach for Omni itself when your fleet is mostly static bare metal where even occasional replaces hurt, and you would rather operate Sidero's purpose-built fleet manager than tune CAPI's extension chain yourself.

The philosophical divide turned out to be a version skew. "Everything in place" was the future Sidero built while Cluster API caught up — and now that it has, the interesting question is not which philosophy wins, but which combination of Talos images, CAPI orchestration, and in-place updates gives your fleet the cheapest boring upgrade. For most Hetzner-backed fleets, that combination runs on the management cluster you already have.

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