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.