04

Upgrades & Image Factory

You never upgrade packages on Talos: you replace the whole OS image. A new kernel and initramfs are written to the inactive boot slot, the node reboots into them, and if that fails the previous slot is still there. Kubernetes is upgraded separately, without reboots. And because there's no package manager, anything extra (drivers, iSCSI tools, a guest agent) is baked into the image by Image Factory as a system extension.

A/B upgrade of one node

$ talosctl -n 10.0.0.21 upgrade --image factory.talos.dev/installer/<schematic-id>:v1.11.3
boot slots
slot Abooted
v1.11.2
kernel + initramfs
slot Bprevious
v1.11.1
kernel + initramfs
STATE config · kept
EPHEMERAL /var · kept
node
worker-1Ready
kubernetes: schedulable
Running. Node boots v1.11.2 from slot A. Slot B holds whatever was there before.
one node at a time

Rolling through a cluster

Talos upgrades are per node, so the order and pace are yours. The usual pattern is control planes one at a time, each back to Ready (and etcd healthy) before the next, then workers in batches small enough for your PodDisruptionBudgets. Talos refuses to upgrade a control plane when etcd is already degraded, unless you pass --force.

Rolling upgrade planner

cp-1control plane · etcd
v1.11.2
cp-2control plane · etcd
v1.11.2
cp-3control plane · etcd
v1.11.2
worker-1worker
v1.11.2
worker-2worker
v1.11.2
worker-3worker
v1.11.2
upgraded
0/6
etcd healthy
3/3
k8s API
up
nodes draining
0

Click Upgrade on a node, or let the planner roll through the cluster.

upgrade Talos
# one node at a time; waits and streams progress by default
# (installer/<id> is the legacy path; Image Factory now prefers
#  <platform>-installer/<id>, e.g. metal-installer or nocloud-installer)
talosctl -n 10.0.0.10 upgrade \
  --image factory.talos.dev/installer/<schematic-id>:v1.11.3

talosctl -n 10.0.0.10 version          # confirm server version
talosctl -n 10.0.0.10 health           # before moving to the next node

# changed your mind / new image misbehaves after booting
talosctl -n 10.0.0.10 rollback
Version paths
Upgrade Talos through each minor release (e.g. 1.10.x → 1.11.x → 1.12.x), landing on the latest patch of each, rather than skipping minors. Check that your Kubernetes version is supported by the target Talos release before you start; upgrade Kubernetes separately with upgrade-k8s.
talosctl upgrade-k8s

Upgrading Kubernetes is a different command

The Talos image and the Kubernetes version are independent. upgrade-k8s walks the cluster, updating each control-plane static pod and then each kubelet through the Talos API, waiting for health at every step. No node reboots.

upgrade-k8s, component by component

$ talosctl -n 10.0.0.10 upgrade-k8s --to 1.34.1
nodeapiserverctrl-mgr / schedkube-proxykubeletOS
cp-11.33.51.33.51.33.51.33.5Talos v1.11.3
cp-21.33.51.33.51.33.51.33.5Talos v1.11.3
cp-31.33.51.33.51.33.51.33.5Talos v1.11.3
worker-1——1.33.51.33.5Talos v1.11.3
worker-2——1.33.51.33.5Talos v1.11.3
Kubernetes is upgraded separately from Talos: the OS column never changes here. Control-plane components go first so kubelets are never newer than the API server.
kubernetes upgrade
talosctl -n 10.0.0.10 upgrade-k8s --to 1.34.1 --dry-run   # show what would change
talosctl -n 10.0.0.10 upgrade-k8s --to 1.34.1
schematics & system extensions

Image Factory: the OS image you need, built on demand

The root filesystem is read-only, so a driver or host tool can't be installed later; it has to be part of the image. A schematic describes your customisations (official system extensions, extra kernel args). POST it to Image Factory and you get back an ID that is a hash of its content. That ID, plus a Talos version, names every artifact: installer image, ISO, disk images, PXE.

Build a schematic

system extensions
extra kernel args
schematic.yamlPOST /schematics
customization:
  systemExtensions:
    officialExtensions:
      - siderolabs/iscsi-tools
      - siderolabs/qemu-guest-agent
      - siderolabs/util-linux-tools
schematic IDillustrative, not a real ID
eaa62dbd5f738f949aaf3d99790dbced2afc1fd668f3d9ee6109a54ec02d5a83
installer image (install & upgrade)
factory.talos.dev/nocloud-installer/eaa62dbd5f738f949aaf3d99790dbced2afc1fd668f3d9ee6109a54ec02d5a83:v1.11.3
boot ISO
https://factory.talos.dev/image/eaa62dbd5f738f949aaf3d99790dbced2afc1fd668f3d9ee6109a54ec02d5a83/v1.11.3/nocloud-amd64.iso

Same schematic, same ID: the factory derives the ID from the schematic content, so it's safe to commit the ID and rebuild any image from it. Changing an extension changes the ID, and moving a node to it means a talosctl upgrade (even at the same Talos version).

register a schematic
cat > schematic.yaml <<'EOF'
customization:
  systemExtensions:
    officialExtensions:
      - siderolabs/iscsi-tools
      - siderolabs/qemu-guest-agent
      - siderolabs/util-linux-tools
EOF

curl -X POST --data-binary @schematic.yaml https://factory.talos.dev/schematics
# {"id":"<64 hex chars>"}
use it
# install & every future upgrade use the same schematic
machine:
  install:
    disk: /dev/vda
    image: factory.talos.dev/installer/<schematic-id>:v1.11.3

# check what's loaded on a node
#   talosctl -n 10.0.0.21 get extensions
Extensions are versioned with Talos
Each official extension is built for a specific Talos release, and the factory picks the matching build. That's why upgrades go through the factory image: a plain ghcr.io/siderolabs/installer image would silently drop your extensions. Newer releases also publish platform-specific installers (e.g. nocloud-installer), which the builder above shows.
  • why it mattersWhole-image A/B upgrades make every upgrade atomic and reversible: the node is either on the old image or the new one, never half-patched.
  • why it mattersKeep etcd quorum by upgrading control planes strictly one at a time; Talos's health check enforces it unless forced.
  • why it mattersThe schematic ID pins exactly which extensions a node runs. Commit it next to your machine config and every rebuild is reproducible.