Skip to content

Getting Started with Talos

Talos Linux is a minimal, immutable operating system designed specifically for running Kubernetes. It provides enhanced security through API-driven configuration with no shell access, automatic updates, and a reduced attack surface. This guide shows you how to use Talos with KSail for local development (Docker provider), cloud deployments (Hetzner Cloud provider), or managed clusters through Sidero Omni (Omni provider).

Talos Linux is fundamentally different from traditional Linux distributions:

  • Immutable: No package manager, no shell, no SSH—the OS cannot be modified at runtime
  • API-driven: All configuration happens via the Talos API using machine config patches
  • Secure by default: Minimal attack surface with only essential services running
  • Kubernetes-native: Designed specifically for Kubernetes, not general-purpose computing
  • Declarative: Configuration is defined as code and applied atomically

Talos is ideal for security-focused production workloads, GitOps workflows, and multi-cloud deployments requiring immutable infrastructure. However, it’s not suitable for quick prototyping (use Vanilla or K3s instead), scenarios requiring shell access or traditional Linux tools, or environments that require Windows/macOS nodes or a general-purpose Linux OS with shell and package management.

Create a Talos cluster on your local machine using Docker containers as nodes.

  • Docker Desktop or Docker Engine installed and running
  • docker ps command works
Terminal window
ksail cluster init \
--name talos-dev \
--distribution Talos \
--provider Docker \
--control-planes 1 \
--workers 2

This creates:

  • ksail.yaml — KSail configuration
  • talos/ directory — Talos configuration patches
Terminal window
ksail cluster create

KSail will:

  1. Download the Talos Docker image
  2. Create Docker containers as control plane and worker nodes
  3. Bootstrap the Kubernetes cluster
  4. Configure kubectl context
  5. Install CNI (Cilium by default)

Expected output:

✓ Creating Talos cluster...
✓ Bootstrapping Kubernetes...
✓ Installing Cilium CNI...
✓ Cluster ready!
Cluster: talos-dev
Nodes: 3 (1 control plane, 2 workers)
Provider: Docker
Terminal window
# Check cluster info
ksail cluster info
# View nodes
kubectl get nodes
# View all pods
kubectl get pods -A
Terminal window
# Create a test deployment
kubectl create deployment nginx --image=nginx
# Expose it
kubectl expose deployment nginx --port=80 --type=NodePort
# Check the service
kubectl get svc nginx
Terminal window
# Delete the cluster and all resources
ksail cluster delete

Talos excels at immutable infrastructure where all changes happen via declarative configuration patches stored in version control—making configuration drift impossible. It’s particularly valuable for security-focused production deployments where no SSH access, API-driven operations, and a minimal attack surface are requirements (ideal for compliance-regulated workloads with GitOps tooling like Flux or ArgoCD).

For multi-environment consistency, use the same Talos distribution from local Docker development through production Hetzner Cloud deployments—configuration patches are portable and behavior is identical across providers, eliminating “works on my machine” issues.

Common operations via Talos API:

Terminal window
talosctl -n <node-ip> get machineconfig # View configuration
talosctl -n <node-ip> version # Check Talos version
talosctl -n <node-ip> logs # System logs
talosctl -n <node-ip> upgrade --image ghcr.io/siderolabs/installer:v1.6.0
graph TB
    subgraph "Docker Host"
        subgraph "Control Plane Container"
            ETCD[etcd]
            API[kube-apiserver]
            SCHED[kube-scheduler]
            CM[kube-controller-manager]
            KUBELET_CP[kubelet]
        end
        
        subgraph "Worker Container 1"
            KUBELET_W1[kubelet]
            POD1[Pods]
        end
        
        subgraph "Worker Container 2"
            KUBELET_W2[kubelet]
            POD2[Pods]
        end
        
        NETWORK[Docker Bridge Network]
        
        API -.->|manages| KUBELET_W1
        API -.->|manages| KUBELET_W2
        
        KUBELET_CP -->|runs| POD1
        KUBELET_W1 -->|runs| POD1
        KUBELET_W2 -->|runs| POD2
        
        NETWORK -.->|connectivity| API
        NETWORK -.->|connectivity| KUBELET_W1
        NETWORK -.->|connectivity| KUBELET_W2
    end

Key characteristics:

  • Each node is a Docker container running Talos Linux
  • Containers communicate via Docker network
  • No VM overhead—direct container-to-container communication
  • MetalLB provides LoadBalancer services (optional, via --load-balancer Enabled)
graph TB
    subgraph "Hetzner Cloud"
        subgraph "Control Plane Server"
            ETCD[etcd]
            API[kube-apiserver]
            SCHED[kube-scheduler]
            CM[kube-controller-manager]
            KUBELET_CP[kubelet]
        end
        
        subgraph "Worker Server 1"
            KUBELET_W1[kubelet]
            POD1[Pods]
        end
        
        subgraph "Worker Server 2"
            KUBELET_W2[kubelet]
            POD2[Pods]
        end
        
        LB[Hetzner Cloud Load Balancer]
        CSI[Hetzner CSI Driver]
        CCM[Hetzner Cloud Controller Manager]
        
        API -.->|manages| KUBELET_W1
        API -.->|manages| KUBELET_W2
        
        CCM -.->|provisions| LB
        CSI -.->|provisions volumes| KUBELET_W1
        CSI -.->|provisions volumes| KUBELET_W2
        
        LB -->|routes traffic| POD1
        LB -->|routes traffic| POD2
    end
    
    USER[Internet Users]
    USER -->|https://| LB

Key characteristics:

  • Each node is a Hetzner Cloud server running Talos Linux
  • Hetzner Cloud Controller Manager provides LoadBalancer support
  • Hetzner CSI Driver provides persistent volumes
  • Public IPs for external access
FeatureVanilla (Kind)K3s (K3d)TalosVCluster
MaturityProductionProductionProductionProduction
Setup Time~2 min~1 min~3 min (Docker)~1 min
Node WeightHeavyLightMediumVery Light
Multi-node✅✅✅✅
Shell Access✅✅❌ (API-only)✅
Immutable OS❌❌✅N/A
Production Ready❌ (local)⚠️ (edge)✅✅ (nested)
LoadBalancer SupportOptionalBuilt-inOptional/CloudSynced
Cloud Providers❌❌✅ (Hetzner)❌
Security PostureStandardStandard✅ EnhancedStandard
Configuration StyleYAMLYAMLPatches (YAML)Helm Values
Learning CurveLowLowMediumMedium

Choose Talos when:

  • Security and compliance are priorities
  • You want immutable infrastructure
  • You’re deploying to production (Hetzner or other clouds in future)
  • You embrace API-driven operations

Choose others when:

  • You need shell access for debugging (Vanilla, K3s, VCluster)
  • You want the fastest setup (K3s, VCluster)
  • You’re running CI/CD tests (VCluster for isolation)
  • You want upstream Kubernetes (Vanilla)

Check Docker status (docker ps, docker network ls), verify HCLOUD_TOKEN for Hetzner, or try cleaning up and retrying with ksail cluster delete && ksail cluster create.

Check CNI pods are running (kubectl get pods -n kube-system and look for your CNI pods, e.g. cilium- or calico-), verify Talos health (talosctl -n <node-ip> health), or reinstall CNI with ksail cluster update.

Verify MetalLB is enabled in ksail.yaml (loadBalancer: Enabled), check MetalLB pods (kubectl get pods -n metallb-system), and verify IP pool exists (kubectl get ipaddresspools -n metallb-system).

Check ~/.talos/config exists, verify node IPs with kubectl get nodes -o wide, and use explicit node IP with talosctl -n <node-ip> --talosconfig ~/.talos/config get members.

Adjust control plane and worker nodes in your existing ksail.yaml (requires distribution: Talos):

# Partial snippet — add to your existing ksail.yaml
spec:
cluster:
distribution: Talos
talos:
controlPlanes: 3 # HA setup
workers: 5

Use Hetzner CSI driver for cloud volumes:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
accessModes: [ReadWriteOnce]
storageClassName: hcloud-volumes
resources:
requests:
storage: 10Gi

Upgrade without cluster recreation: talosctl -n <node-ip> upgrade --image ghcr.io/siderolabs/installer:v1.6.0. See Talos upgrade docs for coordination details.

Enable Flux or ArgoCD for declarative workload management—see GitOps Workflows.

  • Vanilla (Kind): Upstream Kubernetes for maximum compatibility
  • K3s (K3d): Lightweight K3s for resource-constrained environments and CI/CD
  • VCluster: Virtual clusters for multi-tenancy