Back openDesk Edu for a sovereign, open-source education — every vote counts.
Vote nowSave products you love by clicking the heart icon.
Was Flux v2.8 und Helm v4 für GitOps-Nutzer ändern — Server-Side Apply, kstatus Health Checks, CEL-Expressions, .status.inventory, Cosign v3 und der Breaking Change beim Post-Renderer.
Nix wird oft als radikaler Bruch dargestellt: ein komplett neues Betriebssystem, eine neue Art, Software zu bauen, ein neues mentales Modell für alles. Diese Darstellung schreckt Teams ab, denn „alles auf NixOS umstellen“ klingt nach einer Migration über mehrere Quartale ohne Zwischenstopps.
Die Realität sieht anders aus. Nix ist eine Leiter — man kann Sprosse für Sprosse aufsteigen, und jede Sprosse rentiert sich, bevor man entscheidet, ob man weiter klettert. Der „Nix-Spirit“ ist kein spezifisches Tool; es ist eine Reihe von Eigenschaften, die man inkrementell übernehmen kann:
Dieser Artikel definiert sechs Stufen der Übernahme dieses Spirits, von „fixierten Tools in einer Shell“ bis hin zu „immutablen, selbstheilenden Appliances“, und begründet jede Stufe anhand realer Deployments: ein neun-Knoten-K3s-Cluster, provisioniert mit OpenTofu und Ansible, ein air-gapped drei-Knoten-K3s-Cluster mit Ceph-Storage und ein Groupware-Stack (SOGo, OpenLDAP, Stalwart), dessen Container-Images mit Nix gebaut werden.
Die Leiter ist kein Befehl, die Spitze erreichen zu müssen. Jede Sprosse rentiert sich, bevor man entscheidet, ob man weiter klettert — die günstigste (eine fixierte devShell) ist gleichzeitig diejenige, die die häufigsten täglichen Probleme löst.
Die Baseline, von der die meisten Infrastrukturen starten: Per SSH auf einen Host einloggen, Dinge apt install, Konfigurationsdateien manuell bearbeiten und hoffen, dass das Backup der Konfigurationsdatei aktuell ist. Der Zustand lebt auf der Maschine, nicht im Code.
Das Versagensmuster ist der Drift. Die Person, die den Host provisioniert hat, ist ausgeschieden; die Wiki-Seite, die den speziellen Cronjob erklärt, ist weg; der Monitoring-Alarm für den Dienst, von dem „niemand weiß, wer ihn eingerichtet hat“, wird stummgeschaltet. Audits werden zur Archäologie.
Sie wissen, dass Sie bereit für Level 1 sind, wenn einer der folgenden Punkte zutrifft:
Die erste Sprosse ist die günstigste und am unmittelbarsten nützlichste: Nutzen Sie Nix, um zu definieren, welche Tools in Ihrer Shell existieren. Eine flake.nix mit einer devShell ersetzt den Abschnitt „Installieren Sie diese 12 Tools“ in Ihrem README durch einen einzigen Befehl — nix develop —, der jedem Contributor die exakt gleiche Toolchain auf jeder Linux- oder macOS-Maschine zur Verfügung stellt.
Ein reales Beispiel aus einem Kubernetes-Operations-Repo:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let pkgs = nixpkgs.legacyPackages.${system};
in {
devShells.default = pkgs.mkShell {
packages = [
pkgs.kubectl
pkgs.kubernetes-helm
pkgs.helmfile
pkgs.ansible
pkgs.yq-go
];
};
});
}
Dies ist kein Spielzeugbeispiel — es ist das Muster, das verwendet wird, um die exakte Admin-Toolchain (kubectl 1.32.3, helm 3.15.3, helmfile 0.150.0, ansible 2.16.0, yq) für ein Multi-Cluster-Deployment zu fixieren. Die Vorteile in der Praxis:
flake.lock. Niemand schleicht eine Änderung einer Minor-Version des CLI ein, die sich in der Produktion anders verhält.nix develop funktioniert auf einem Laptop, einem Jump-Host hinter einem HTTP-Proxy und einem CI-Runner. In einer air-gapped Umgebung wird die Closure entweder vorab abgerufen oder aus einem lokalen Cache bereitgestellt — keine curl | sh aus dem Internet.Was es kostet: Das Erlernen der Flake-Syntax und einiger Nix-Idiome. Das ist ein Wochenende, kein Quartal. Wann man hier aufhört: Wenn Ihr Problem ausschließlich darin besteht, dass „die Tools zwischen den Maschinen variieren“, löst dieses Level das bereits.
Die zweite Sprosse: Nutzen Sie Nix, um die Artefakte zu bauen, die Ihr Deployment konsumiert — am häufigsten OCI-Container-Images. dockerTools.buildImage und buildLayeredImage erzeugen Images, die reproduzierbar sind, über den Store-Pfad Layer-gecached werden und frei von der Unsicherheit „letzten Dienstag von Docker Hub gezogen“ sind.
Das Muster, das sich in der Praxis bewährt hat, ist ein Flake pro Service, wobei das Image als Package-Output dient und derselbe Ausdruck als CI-Check wiederverwendet wird:
{
description = "Nix flake for OpenLDAP container images";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/release-24.05";
};
outputs = { self, nixpkgs, ... }@inputs:
let
supportedSystems = [ "x86_64-linux" "aarch64-linux" ];
mkImage = system:
import ./images/openldap.nix {
inherit system;
pkgs = nixpkgs.legacyPackages.${system};
};
in {
packages = nixpkgs.lib.genAttrs supportedSystems (system: {
openldap = mkImage system;
default = mkImage system;
});
checks = nixpkgs.lib.genAttrs supportedSystems (system: {
default = mkImage system;
});
};
}
Drei Eigenschaften dieses Flakes sind es wert, kopiert zu werden:
genAttrs über supportedSystems leitet x86_64- und aarch64-Images aus einem einzigen Ausdruck ab — keine separaten Dockerfiles, die auseinanderdriften. Derselbe Trick, via extendModules, leitet Umgebungsvarianten aus einer einzigen Basis-Konfiguration ab.checks bedeutet, dass nix flake check in der CI sie auswertet und baut. Wenn der Ausdruck bricht, bricht die CI — bevor irgendetwas in eine Registry gepusht wird.sed-Befehlen in einem Dockerfile. Ein Groupware-Frontend, das Accessibility-Fixes benötigte (ein z-index-Bug bei einem Dialog, ein Kontrastproblem bei einem Platzhalter, ein Theme-Mismatch), wird als Patch ausgeliefert, der während des Builds angewendet wird — der exakte Satz an Änderungen ist in der Versionsverwaltung sichtbar und für immer reproduzierbar.In einem air-gapped Cluster rentiert sich diese Sprosse sofort: Images werden einmal gebaut, in eine lokale Registry geladen, und die Nodes benötigen überhaupt keinen Zugriff auf Docker Hub. nix build + docker load + docker tag + push ist die gesamte Publish-Pipeline.
Was es kostet: eine dockerTools Lernkurve und anfangs langsamere Iterationen als bei einem Dockerfile. Wann man hier aufhört: wenn Ihr Team eine Handvoll Images verwaltet und der Schmerzpunkt darin liegt: „Was genau ist in diesem Image und wer hat es wann gebaut“.
Die dritte Stufe befasst sich mit dem Ökosystem rund um die Builds: Nix wird zum gemeinsamen Substrat dafür, wie Code im Team formatiert, geprüft und verteilt wird.
treefmt mit nixfmt (Formatter), statix (Linter mit Autofix) und deadnix (Entfernung von totem Code) wird zur einzigen Quelle der Wahrheit („Single Source of Truth“) dafür, was „formatiertes Nix“ bedeutet. Ein nix fmt pro Repo, erzwungen in der CI.nix flake check als CI-Gate. Eval-only-Checks, Image-Builds und sogar vollständige NixOS-Integrationstests (testers.runNixOSTest, die eine VM booten und das Service-to-Service-Verhalten prüfen) laufen, bevor etwas gemergt wird.nix-serve, Attic oder harmonia mit signierten Store-Pfaden ermöglichen es jedem Node und jedem CI-Runner, vorab gebaute Artefakte zu ziehen, anstatt sie lokal zu bauen. Ein post-build-hook lädt jeden neuen Pfad automatisch hoch. In einem Air-Gapped-Netzwerk ist dies der Unterschied zwischen „der Cluster baut in Minuten neu“ und „der Cluster baut einen Tag lang neu“.nix.buildMachines und nix.distributedBuilds zur Build-Farm der Flotte.Ein subtiles, aber mächtiges Muster auf dieser Ebene: Nix als Konfigurationsgenerator. Anstatt Kubernetes-Manifeste händisch zu schreiben, generiert das Deployment diese aus Nix — eine Library mit einer k8s Funktion wandelt typisierte Nix-Werte in YAML um. Alle 57 Services eines Deployments (von ArgoCD und Monitoring bis hin zum Mail-Stack) werden aus einem einzigen Expression-Tree abgeleitet. Die Manifeste sind im Cluster weiterhin YAML, aber es ist generiertes YAML mit einem einzigen Ursprung, und die Neugenerierung ist ein Build-Schritt, keine manuelle Bearbeitungssitzung.
Was es kostet: Infrastruktur (ein Cache-Server, eine Build-Maschine) und CI-Plumbing. Wann man hier aufhört: wenn Ihre Images mit Nix gebaut werden, Ihre Nodes und Maschinen aber immer noch imperativ verwaltet werden — Level 4 ist ein anderes Projekt.
Die vierte Stufe ist diejenige, die sich die meisten Menschen vorstellen, wenn sie „Nix“ hören: das OS selbst wird in einem Flake deklariert. /etc wird aus der Konfiguration generiert; ein Rollback ist ein Eintrag im Boot-Menü; Secrets sind im Repo verschlüsselt und nicht über Hosts verteilt.
Die modernen Muster, die alle im Ökosystem praxiserprobt sind:
disko deklariert Partitionen, Dateisysteme und LUKS-Verschlüsselung im selben Flake; nixos-anywhere installiert eine Remote-Maschine aus dieser Deklaration über SSH, ohne dass man eine ISO-Installation begleiten muss.impermanence oder systemd StateDirectory=) überlebt. Eine kompromittierte oder korrupte Maschine kehrt durch einen Neustart in ihren deklarierten Zustand zurück.agenix und ININ21 verschlüsseln Secrets im Repo; systemd LoadCredential= übergibt sie den Services zur Laufzeit.nixos-rebuild pro Host bleibt für den Single-Machine-Fall.Wo lässt das einen Cluster, der bereits Kubernetes ist, stehen? Die ehrliche Antwort aus Erfahrung: NixOS-Nodes und K8s-Workloads ergänzen einander. Die Nodes des Clusters werden reproduzierbar, selbstheilend und synchron gepatcht (ein Flake = ein bekannt-gut funktionierendes Node-Image), während die Workloads weiterhin in Containern mit ihrem eigenen Lebenszyklus laufen. Ansible hat immer noch eine Rolle beim Bootstrap und für Dinge, die Nix nicht gut modelliert — aber die driftanfällige Zwischenschicht (händisch editierte /etc, Ad-hoc-Pakete, manuelle sysctls) verschwindet.
Was es kostet: die steilste Lernkurve bisher; NixOS hat seine eigene Art, Networking, Benutzer und Services zu handhaben. Wann man hier aufhört: wenn Ihre Flotte klein ist und Ihre Nodes bereits „Pets“ sind, die Sie selten anfassen, ist der ROI möglicherweise noch nicht gegeben.
Die oberste Stufe: Die Maschine hört auf, eine Maschine zu sein, und wird zu einem Appliance. Alles Vorherige gilt, plus:
systemd-sysupdate (oder das nixos-appliance-ota-update Muster) hält zwei Slots bereit; ein fehlgeschlagener Boot führt automatisch zum vorherigen Slot zurück.lanzaboote signiert Unified Kernel Images; TPM-basierte Festplattenverschlüsselung bindet die Disk an die Hardware.Auf dieser Ebene ist das „Updaten eines Servers“ nicht mehr von einem „Deployment neuer Firmware“ zu unterscheiden. Dies ist das Muster für Edge-Devices, Kiosks und Remote-Standorte, an denen niemand per SSH einbauen kann, um ein fehlgeschlagenes Upgrade zu reparieren — aber es ist auch ein legitimes Endziel für Core-Infrastruktur-Nodes.
Um ehrlich zu bleiben, hier ist die Position der Deployments hinter den Beispielen dieses Artikels auf der Leiter:
| Layer | Level heute | Notizen |
|---|---|---|
| Admin-Tooling (kubectl, helm, helmfile, ansible) | 1 — gepinnte devShell | Ein Flake, genutzt von Laptops und Jump-Hosts |
| Mail/Groupware-Images (SOGo, OpenLDAP 2.6.7, Stalwart) | 2 — Nix-gebaute Container | Multi-Arch-Flakes, Checks in CI, lokale Registry |
| K8s-Manifest-Generierung | 3 — Nix-generiertes YAML | ~57 Services, abgeleitet aus einem Expression-Tree |
CI-Gates (treefmt, nix flake check) | 3 — partiell | Formatter und Linting eingeführt; vollständiges Check-Gate in Arbeit |
| Binary Cache für den Air-Gapped-Cluster | 3 — geplant | Attic/nix-serve + post-build-hook, signierte Store-Pfade |
| Cluster-Nodes (K3s auf Bare Metal / Proxmox) | 0–1 — OpenTofu + Ansible | Vollständig parametrisiert, aber imperativer State auf den Nodes |
| Node-OS | 4–5 — Roadmap | disko, impermanence, A/B OTA als Zielzustand |
Der Migrationspfad, sortiert nach Wert pro Aufwandseinheit:
Die Leiter ist kein Befehl, die Spitze erreichen zu müssen. Das richtige Level hängt von drei Fragen ab:
Beginnen Sie diese Woche mit Level 1 — pinnen Sie Ihre Toolchain in einem devShell, committen Sie die flake.lock und machen Sie „works on my machine“ zu einer historischen Phrase. Alles darüber hinaus ist eine Serie von kleinen, einzeln sinnvollen Wetten, keine Revolution.
Click a rung to see what it gives you, what it costs, and when to stop climbing.
Cost: A weekend of flake syntax and Nix idioms.
Stop here if: When your pain is only 'tools differ between machines', this level already fixes it.
Answer honestly about today — the assessment tells you where you stand and which rung to climb next.
Reproduzierbarkeit summiert sich. Die devShell, die Sie diese Woche pinnen, ist derselbe Expression-Tree, der eines Tages Ihre Appliances bauen wird — jede Stufe, die Sie erklimmen, macht die nächste günstiger.