Ik heb geschreven over Talos Linux als het immutable Kubernetes OS, en ik heb Arch vs NixOS voor werkstations vergeleken. Maar er is een vraag die ik vaak krijg: wat dacht je van NixOS voor Kubernetes nodes?

Zowel NixOS als Talos zijn declaratief. Beide kunnen immutable zijn. Beide versioneren hun configuratie. Dus waarom zou je de ene boven de andere kiezen voor Kubernetes?

Ik heb beide in productie gedraaid. Dit is wat ik geleerd heb.

Het Filosofische Verschil

Voordat we in details duiken, begrijp het kernverschil:

Talos Linux is een single-purpose besturingssysteem. Het bestaat om Kubernetes te draaien. Niets anders. Elke designbeslissing optimaliseert voor dat ene doel.

NixOS is een general-purpose besturingssysteem dat toevallig uitstekend is in Kubernetes draaien. Het kan alles wat een traditionele Linux kan, maar met declaratieve configuratie.

Dit is niet alleen een marketing-onderscheid. Het vormt fundamenteel waar elk systeem goed in is.

Configuratie Modellen

Talos: YAML All The Way

Talos configuratie is rechttoe rechtaan YAML:

machine:
  type: controlplane
  network:
    hostname: node-01
    interfaces:
      - interface: eth0
        dhcp: true
  install:
    disk: /dev/sda
cluster:
  clusterName: production
  controlPlane:
    endpoint: https://k8s.example.com:6443

Je past het toe met talosctl apply-config, en de node convergeert naar die staat. Simpel, voorspelbaar, geen verrassingen.

NixOS: De Nix Taal

NixOS configuratie is geschreven in Nix, een functionele taal:

{ config, pkgs, ... }:

{
  networking.hostName = "node-01";

  services.k3s = {
    enable = true;
    role = "server";
    extraFlags = toString [
      "--cluster-init"
      "--disable traefik"
    ];
  };

  # Je kunt hier alles doen
  services.prometheus.exporters.node.enable = true;
  virtualisation.docker.enable = true;

  system.stateVersion = "24.05";
}

Je past het toe met nixos-rebuild switch, en het systeem convergeert naar de gedeclareerde staat.

De Trade-off

Talos’s YAML is beperkt maar leerbaar in een middag. NixOS’s Nix taal is krachtig maar kost weken om comfortabel mee te worden.

Als je alleen Kubernetes nodig hebt, wint Talos’s eenvoud. Als je Kubernetes plus andere dingen nodig hebt, is NixOS’s flexibiliteit de leercurve waard.

Security Posture

Talos: Veilig Door Verwijdering

Talos bereikt security door attack surface te verwijderen:

  • Geen SSH daemon
  • Geen shell
  • Geen package manager
  • Read-only root filesystem
  • Minimale userspace (alleen containerd, kubelet en essentials)

Een aanvaller die een container compromitteert en ontsnapt naar de host vindt… niets bruikbaars. Geen tools om mee te pivoten, geen persistence mechanismen, geen manier om malware te installeren.

NixOS: Veilig Door Configuratie

NixOS kan significant gehardend worden, maar het is opt-in:

{
  # Disable SSH password auth
  services.openssh = {
    enable = true;
    settings.PasswordAuthentication = false;
  };

  # Firewall
  networking.firewall = {
    enable = true;
    allowedTCPPorts = [ 6443 ];
  };

  # Read-only store (altijd waar)
  # Maar /etc, /var, /home zijn nog steeds mutable
}

NixOS’s /nix/store is altijd read-only, wat geweldig is. Maar de rest van het filesystem is standaard mutable. Je kunt het immutable maken met extra configuratie, maar het is niet de default.

De Trade-off

Talos is secure out of the box. NixOS kan secure gemaakt worden, maar vereist bewuste configuratie. Voor Kubernetes nodes specifiek zijn Talos’s paranoïde defaults waarschijnlijk wat je wilt.

Flexibiliteit vs Focus

Dit is waar de systemen het meest dramatisch divergeren.

Wat NixOS Kan Dat Talos Niet Kan

Met NixOS kan je Kubernetes node ook draaien:

  • Systeem services: Prometheus node exporter, log shippers, monitoring agents — als systemd services, niet pods
  • Non-containerized workloads: Soms heb je een bare-metal database of legacy app nodig naast Kubernetes
  • Custom tooling: Installeer elk pakket uit nixpkgs (80.000+ pakketten)
  • Development tools: Als je op de node zelf moet debuggen, kun je tools installeren

Voorbeeld: een lokale PostgreSQL draaien naast Kubernetes voor testing:

{
  services.k3s.enable = true;

  services.postgresql = {
    enable = true;
    package = pkgs.postgresql_15;
  };
}

Wat Talos Doet Dat NixOS Niet Wil

Talos’s restricties zijn features:

  • Geen drift: Je kunt letterlijk geen ongedocumenteerde wijzigingen maken
  • Gedwongen discipline: Elke wijziging gaat via config → API → apply
  • Simpeler mentaal model: De node is de config, niets anders
  • Kleiner attack surface: Wat niet bestaat kan niet geëxploiteerd worden

De Trade-off

Als je nodes alleen Kubernetes workloads draaien, voorkomen Talos’s restricties fouten. Als je nodes meer moeten doen, is NixOS’s flexibiliteit noodzakelijk.

Upgrade en Rollback

Talos: Transactionele OS Updates

talosctl upgrade --nodes 192.168.1.10 \
  --image ghcr.io/siderolabs/installer:v1.7.0

Talos schrijft het nieuwe OS naar een alternatieve partitie en reboot. Als het faalt te booten, automatische rollback naar de vorige versie. De upgrade is atomic — het slaagt volledig of faalt volledig.

NixOS: Generation-Based Rollback

nixos-rebuild switch --flake .#node-01

NixOS creëert een nieuwe “generation” voor elke configuratiewijziging. Elke generation is bootbaar vanuit GRUB. Rollback is een vorige generation selecteren:

nixos-rebuild switch --rollback
# Of selecteer vanuit boot menu

NixOS bewaart standaard meerdere generations, dus je kunt rollbacken naar configuraties van weken geleden.

De Trade-off

Beide hebben uitstekende rollback verhalen. Talos is meer automatisch (gefaalde boots triggeren rollback). NixOS is flexibeler (bewaar willekeurige generations, rollback gedeeltelijk).

Kubernetes Integratie

Talos: Gebouwd voor Kubernetes

Talos bevat alles wat nodig is voor Kubernetes:

  • Kubernetes componenten zijn ingebouwd
  • CNI configuratie is onderdeel van machine config
  • etcd management wordt automatisch afgehandeld
  • Certificate rotation is automatisch
  • Upgrades coördineren met Kubernetes (drain, upgrade, uncordon)

Je installeert Kubernetes niet op Talos. Kubernetes is onderdeel van Talos.

NixOS: Kubernetes als Service

NixOS biedt meerdere opties:

# Optie 1: K3s (lichtgewicht)
services.k3s = {
  enable = true;
  role = "server";
};

# Optie 2: Volledige Kubernetes via kubeadm
services.kubernetes = {
  roles = ["master" "node"];
  masterAddress = "k8s.example.com";
};

# Optie 3: Alleen de kubelet
services.kubernetes.kubelet.enable = true;

Je kiest hoe Kubernetes gedeployed wordt. Dit betekent meer beslissingen maar ook meer opties.

De Trade-off

Talos’s opinionated integratie betekent minder beslissingen en betere defaults voor Kubernetes. NixOS’s flexibiliteit betekent dat je Kubernetes kunt integreren hoe je wilt, maar je moet die beslissingen maken.

Debugging en Troubleshooting

Talos: API-Only Access

# Logs bekijken
talosctl logs kubelet --nodes 192.168.1.10

# Systeem info ophalen
talosctl get members

# Bestanden lezen
talosctl read /etc/hosts

# Dashboard (read-only TUI)
talosctl dashboard

Alles via de API. Geen SSH, geen shell. Voor noodgevallen is er een debug container feature, maar het is opzettelijk onhandig.

NixOS: Volledige Linux Access

# SSH erin
ssh root@192.168.1.10

# Gebruik elke tool
htop
journalctl -u k3s
kubectl get nodes
vim /etc/nixos/configuration.nix

Het is een volledig Linux systeem. Al je vertrouwde tools werken. Dit is comfortabel maar potentieel gevaarlijk — elke SSH sessie is een kans om ongedocumenteerde wijzigingen te maken.

De Trade-off

Talos dwingt je te debuggen via juiste kanalen (API, logs, metrics). NixOS laat je debuggen hoe je wilt, inclusief manieren die drift kunnen veroorzaken.

Mijn Aanbeveling

Na beide gedraaid te hebben, is dit mijn beslisframework:

Kies Talos Wanneer:

  • Kubernetes de enige workload is op deze nodes
  • Security paramount is — je wilt minimaal attack surface
  • Je guardrails wilt — drift voorkomen is belangrijker dan flexibiliteit
  • Je comfortabel bent met API-driven management
  • Je team gedisciplineerd is in declaratieve workflows

Kies NixOS Wanneer:

  • Je non-Kubernetes workloads nodig hebt op dezelfde nodes
  • Je volledige Linux flexibiliteit wilt met declaratieve voordelen
  • Je specifieke packages nodig hebt niet beschikbaar als Talos extensions
  • Je team al geïnvesteerd is in het Nix ecosysteem
  • Je diep wilt customizen voorbij wat Talos toestaat

Mijn Setup

Ik gebruik eigenlijk beide:

  • Homelab Kubernetes: Talos. De nodes draaien alleen Kubernetes, en ik wil de security en eenvoud.
  • Homelab auxiliary servers: NixOS. Deze draaien dingen als Postgres, backup services en monitoring infrastructuur die ik niet in Kubernetes wil.

Deze combinatie geeft me het beste van beide werelden: locked-down Kubernetes nodes die niet kunnen driften, plus flexibele NixOS machines voor al het andere.

De Hybride Aanpak

Sommige teams draaien NixOS voor control plane nodes (waar ze meer debugging access willen) en Talos voor worker nodes (waar ze maximale security willen). Dit kan werken, maar voegt operationele complexiteit toe.

Een andere optie: begin met NixOS voor bekendheid, migreer dan naar Talos als je team volwassener wordt in declaratieve operations. NixOS leert het mentale model; Talos enforced het.

De KubeVirt Optie: Kubernetes als Control Plane voor Alles

Er is een derde aanpak die vermelding verdient: KubeVirt gebruiken om NixOS als VMs binnen Kubernetes te draaien. Dit draait het model om — in plaats van te kiezen tussen NixOS en Talos voor je nodes, gebruik je Talos (of een ander minimaal OS) voor de bare metal, en draai je NixOS workloads als VMs beheerd door Kubernetes.

De stack ziet er zo uit:

flowchart TD
    subgraph stack["KubeVirt Stack"]
        ArgoCD["ArgoCD (GitOps)"]
        KubeVirt["KubeVirt VMs (NixOS, andere OSes)"]
        K8s["Kubernetes (K3s/Talos)"]
        BareMetal["Bare Metal (Ansible provisioned)"]
        ArgoCD --> KubeVirt
        KubeVirt --> K8s
        K8s --> BareMetal
    end

Waarom Dit Werkt

Je VM definities worden Kubernetes manifests:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: nixos-workload-01
spec:
  running: true
  template:
    spec:
      domain:
        resources:
          requests:
            memory: 4Gi
            cpu: 2
        devices:
          disks:
            - name: nixos-disk
              disk:
                bus: virtio
      volumes:
        - name: nixos-disk
          persistentVolumeClaim:
            claimName: nixos-workload-01-pvc

Beheerd door ArgoCD, leeft deze VM definitie in Git. De NixOS configuratie binnen de VM leeft ook in Git. Alles is declaratief, auditeerbaar en version-controlled.

De Volledig Declaratieve Stack

Combineer dit met:

  • Ansible voor bare metal provisioning (installeer Talos/K3s op fysieke nodes)
  • ArgoCD voor het beheren van alles in Kubernetes (inclusief KubeVirt VMs)
  • NixOS flakes voor VM configuraties (gepulled vanuit Git tijdens VM boot)

Het resultaat: je hele infrastructuur — van bare metal tot VMs tot Kubernetes workloads — is gedefinieerd in Git. Wijzig een VM’s NixOS config, commit, ArgoCD synct, de VM herbouwt. Volledige audit trail, volledige reproduceerbaarheid.

Wanneer Dit Zinvol Is

Deze aanpak schittert wanneer:

  • Je gemixte workloads nodig hebt (sommige gecontaineriseerd, sommige vereisen volledige VMs)
  • Je één control plane (Kubernetes) wilt voor alles
  • Je workloads hebt die niet gecontaineriseerd kunnen worden maar toch GitOps wilt
  • Je al KubeVirt draait om andere redenen

De trade-off is complexiteit. Je draait nu een virtualisatielaag binnen Kubernetes. Maar als je VMs nodig hebt, is ze declaratief beheren via dezelfde GitOps pipeline als al het andere krachtig.

Voorbeeld: Database op NixOS VM

Stel je wilt een PostgreSQL server met specifieke kernel tuning die niet in een container past. In plaats van een aparte NixOS server onderhouden:

  1. Definieer de VM in een KubeVirt manifest (in Git)
  2. De VM boot NixOS, haalt zijn config op vanuit een flake (in Git)
  3. ArgoCD beheert de VM lifecycle
  4. Backups, monitoring, networking — allemaal via Kubernetes

De database krijgt NixOS’s flexibiliteit. Jij krijgt Kubernetes’s orchestration. Alles staat in Git.

Conclusie

Zowel NixOS als Talos representeren de toekomst van infrastructuur: declaratief, reproduceerbaar, version-controlled. De keuze tussen hen gaat niet over welke “beter” is — het gaat over welke constraints je behoeften dienen.

Talos beperkt je tot Kubernetes-only, API-only, minimal-surface operations. Die constraints zijn features als je een secure, drift-free Kubernetes platform wilt.

NixOS beperkt je tot declaratieve configuratie terwijl volledige Linux flexibiliteit behouden blijft. Die constraints zijn features als je die flexibiliteit nodig hebt.

De vraag is niet “NixOS of Talos?” Het is “Welke constraints wil ik?”

Voor pure Kubernetes nodes neig ik naar Talos. Voor al het andere neig ik naar NixOS. En steeds meer denk ik dat het juiste antwoord beide is — elk in zijn juiste rol.


Beide communities zijn uitstekend. Beide systemen worden actief ontwikkeld. Je kunt eigenlijk niet verkeerd kiezen met beide — je bent al vooruit door declaratief te denken over je infrastructuur.