The philosophy

Every component on a Talos node is either: (1) the immutable Talos OS image, or (2) Kubernetes itself, or (3) a workload Kubernetes scheduled. Nothing else. The configuration is declarative; reapplying it makes a node match the desired state. Upgrades are A/B partition swaps; on failure, the node boots the previous image automatically.

Install talosctl

# Linux / macOS
curl -sL https://talos.dev/install | sh
# or specific version
curl -Lo /usr/local/bin/talosctl \
    https://github.com/siderolabs/talos/releases/latest/download/talosctl-linux-amd64
chmod +x /usr/local/bin/talosctl

talosctl version --client

Pick a topology

The simplest production-ready cluster: 1 control plane + 2 workers (3 nodes total). For HA control plane: 3 control plane + 3 workers. For a homelab single-node: a single "controlplane" node with allowSchedulingOnControlPlanes: true.

Generate cluster config

# Pick a virtual IP for the control plane endpoint (or use the first CP node's IP)
talosctl gen config my-cluster https://192.168.1.100:6443

# Generates three files:
#   controlplane.yaml  — for control-plane nodes
#   worker.yaml        — for worker nodes
#   talosconfig        — the client config for talosctl + kubectl

The two YAML files are the entire desired state of each role: kernel args, disk layout, network config, kubelet config, container runtime, the API server / scheduler / controller manager. Edit them to taste before applying.

Boot the install media

Get the Talos image from factory.talos.dev — the factory lets you build a custom image with the specific kernel modules, system extensions (iSCSI, NVIDIA drivers, util-linux), and overlay drivers you need. Output formats: ISO, raw disk image, qcow2 (for VMs), Raspberry Pi, AWS / GCP / Azure / DO disk images.

Boot each target machine from the image. On first boot, Talos comes up in "maintenance mode" — it has a Talos API listening but no configuration yet. The console prints the assigned IP.

Apply the config

# Set talosctl's default endpoint and config file
export TALOSCONFIG=$PWD/talosconfig
talosctl --talosconfig=talosconfig config endpoint 192.168.1.100

# Apply controlplane config to the first node
talosctl apply-config --insecure \
    --nodes 192.168.1.100 \
    --file controlplane.yaml

# Worker nodes
talosctl apply-config --insecure --nodes 192.168.1.101 --file worker.yaml
talosctl apply-config --insecure --nodes 192.168.1.102 --file worker.yaml

Within ~30 seconds each node has applied its config: laid out disks, configured networking, started containerd, joined the cluster.

Bootstrap the cluster

# Once on a single control-plane node, run bootstrap to initialize etcd
talosctl bootstrap --nodes 192.168.1.100

# Get the kubeconfig
talosctl kubeconfig --nodes 192.168.1.100

# Now kubectl works
kubectl get nodes

That's the whole bring-up. From here it's a regular Kubernetes cluster; pair with Argo CD (see that tutorial) and k9s (see that tutorial) for the operational layer.

The talosctl CLI

Everything you'd normally SSH for, talosctl provides via API:

talosctl --nodes 192.168.1.100 dashboard           # live dashboard (top-style)
talosctl --nodes 192.168.1.100 logs kubelet
talosctl --nodes 192.168.1.100 logs containerd
talosctl --nodes 192.168.1.100 service             # list system services
talosctl --nodes 192.168.1.100 disks               # disks + partitions
talosctl --nodes 192.168.1.100 memory
talosctl --nodes 192.168.1.100 processes
talosctl --nodes 192.168.1.100 stats               # cgroup stats per container
talosctl --nodes 192.168.1.100 read /etc/hostname  # read any file from any node

No shell, but everything is observable.

Upgrades

# Upgrade Talos itself (the OS)
talosctl --nodes 192.168.1.100 upgrade \
    --image ghcr.io/siderolabs/installer:v1.9.0

# Talos pulls the new image, writes it to the inactive partition, and reboots
# into it. On failure, it rolls back to the previous partition automatically.

# Upgrade Kubernetes
talosctl --nodes 192.168.1.100 upgrade-k8s --to 1.32.0

Both operations are atomic per node; the cluster stays available because cordon-drain is built into the upgrade flow.

System extensions

Need a kernel module the base image doesn't include (NVIDIA drivers, iSCSI initiator, util-linux tools, QEMU guest agent)? Build a custom image at factory.talos.dev with the extensions checked, then talosctl upgrade to that image. Extensions are added at the image level, not at runtime — immutability is preserved.

Storage

Talos's storage story is "let Kubernetes handle it." Pair with Longhorn or Rook-Ceph for persistent volumes that span nodes. For single-node clusters, the local-path-provisioner just writes to a directory on disk.

Network

Out of the box, Flannel as the CNI. For more advanced features (Cilium replacement of kube-proxy, eBPF, hubble observability), see the Cilium tutorial — same idea applies, just install via Helm after the cluster is up.

Where Talos isn't the right tool

  • If the cluster needs to run non-container workloads (a database directly on the host, a SystemD service) — Talos can't accommodate it; Kubernetes is the only execution surface. For mixed workloads, use Nomad (see that tutorial) or a general-purpose Linux + K3s.
  • If the team isn't ready to operate Kubernetes — Talos doesn't simplify K8s; it simplifies the OS layer. K8s knowledge is still required.
  • For "I want to SSH in and debug" — no SSH. Debug via API and Kubernetes-native debug tools (kubectl debug, ephemeral debug containers).

Talos vs alternatives

  • Flatcar Linux — immutable but still general-purpose. Better fit if you want SSH + systemd + ostree-style updates.
  • Bottlerocket — AWS's container-optimized OS. Similar philosophy, AWS-specific tooling.
  • K3OS — ancestor concept; less maintained in 2026.
  • NixOS (see that tutorial) — declarative but general-purpose; you describe a Kubernetes-running NixOS, not a Kubernetes-only OS.

For "we're running Kubernetes, we want the OS layer to disappear," Talos is the strongest expression of that goal in 2026.