Schluss mit geratenen Resource-Requests — VPA und Goldilocks im Recommend-Only-Modus

Auf vier ARM-Boards ist jedes Mebibyte gezählt — trotzdem habe ich CPU- und Memory-Requests jahrelang aus dem Bauch gesetzt. Der Vertical Pod Autoscaler beobachtet jetzt den echten Verbrauch und schreibt Empfehlungen, Goldilocks macht sie als Dashboard lesbar. Bewusst nur als Ratgeber: VPA fasst keinen einzigen Pod von selbst an.

Resource-Requests und -Limits habe ich in meinem Lab lange so gesetzt, wie man es eben macht: ein paar Werte aus dem Bauch, 100m/128Mi als Reflex, und dann nie wieder angefasst. Auf einer dicken Cloud ist das egal. Auf vier RK1-Boards mit endlichem ARM-Speicher ist es das nicht: Setze ich zu hoch, verschenke ich Kapazität, die kein anderer Pod mehr bekommt, weil der Scheduler den Request reserviert, nicht den Verbrauch. Setze ich zu niedrig, holt mir der OOM-Killer nachts einen Pod ab oder die CPU wird in den Boden gethrottlet. Beides hatte ich. Was mir fehlte, war kein Gefühl, sondern eine Zahl.

Ein CI-Broker für Radicle, der wirklich baut — die Reise durch jede Wand

Vor zwei Wochen stand der Plan: ein CI-Broker, der auf Patch-Events meiner Radicle-Seed-Node hört, in-cluster baut und signiert. Das Diagramm war sauber. Die Realität war ein wochenlanger Kampf mit cib-Entrypoints, Flux, das meine Shell-Variablen auffraß, stale :latest-Tags, rootless buildah, das in Kubernetes prinzipiell nicht geht, und einem binfmt_misc-Handler, der auf Kernel 6.x immer wieder verschwand. Hier ist jede Wand, gegen die ich gelaufen bin — und wie der Broker am Ende doch baut.

In Radicle CI — eine Pipeline, die auf Patches reagiert habe ich den Plan beschrieben: Meine Seed-Node läuft in-cluster und führt einen Event-Stream — jede neue Patch-Ref, jedes COB-Update wird sichtbar. Ein CI-Broker abonniert diesen Stream, übersetzt ein Patch-Event in einen Build und schreibt das Ergebnis zurück auf den Patch. Sauberes Diagramm, klare Idee, ein offenes Trust-Problem, das ich für lösbar hielt.

Was dieser Beitrag erzählt, ist die Lücke zwischen dem Diagramm und einem grünen Häkchen. Sie war größer, als mir lieb war. Zwischen „der Broker ist deployt" und „der Broker baut wirklich ein signiertes Image" lagen rund zwei Dutzend Commits, die fast alle fix: heißen — und jeder davon steht für eine Wand, gegen die ich gelaufen bin. Kein Architektur-Pitch, sondern ein Reisebericht durch Entrypoints, die nicht stimmen, durch Flux, das meine Shell-Variablen frisst, durch rootless buildah, das in Kubernetes prinzipiell nicht funktioniert, und durch einen Kernel, der meinen QEMU-Handler immer wieder vergaß.

Das Lab wird multi-cluster — wiederholbar föderiert und evaluiert

Aus einem handverdrahteten Cluster plus Wegwerf-Test wurde ein wiederholbares Muster: ein Cluster pro Befehl, Apps im cluster-scope, Flux-Tenants, eine aufgeräumte Headscale-Domain — und Föderation statt Node-Mesh. Inklusive der Vorgeschichte (warum ClusterMesh rausflog), einer nüchternen Stabilitäts-Bewertung und dem, was als Nächstes fällig ist: Monitoring, Alerting, Backup und HA für die Föderations-Wurzel.

Die letzten Tage im Lab waren ein Strukturschnitt. Lange gab es genau einen ernsthaften Cluster — hydra, bare-metal — und daneben einen Wegwerf-Test, von dem die ClusterMesh-Episode erzählte. Inzwischen ist daraus ein wiederholbares Muster geworden: ein Cluster pro Befehl, Anwendungen im cluster-scope, Flux-Tenants, eine aufgeräumte Tailnet-Domain — und eine Föderation, die bewusst kein Pod-Mesh ist. Dieser Beitrag fasst die Änderungen zusammen, spricht ehrlich über die Probleme dahinter und bewertet, wie produktionstauglich das Ganze wirklich ist.

Renovate als Dependency-Bot für ein GitOps-Monorepo

Mein Lab ist ein einziges Flux-Repository — Helm-Charts, Container-Images, Talos- und Kubernetes-Versionen, CLI-Pins in Dockerfiles und shell.nix. Renovate hält das alles aktuell, automerged das Unkritische und zwingt mich bei Ceph, Cilium und Vault zum Hinschauen. Hier ist, wie ich es scharf gestellt habe.

Mein Lab ist ein einziges Repository: ein GitOps-Monorepo, aus dem Flux mehrere Talos-Cluster reconciled. Alles, was eine Version trägt, steht darin — Helm-Charts, Container-Images, die Talos- und Kubernetes-Version, dazu CLI-Pins in einem Dockerfile und in shell.nix. Manuell halte ich das nicht aktuell. Das macht Renovate , und zwar so, dass es mir die langweiligen Bumps abnimmt und mich genau bei den drei, vier Dingen stoppt, bei denen ein blinder Merge teuer wäre.

Ceph auf vier ARM-Boards — das Speicher-Fundament unterm Lab

Fast jeder Lab-Artikel sagt beiläufig ceph-block oder ceph-filesystem — erklärt wurde es nie. Hier ist die Schicht darunter: Rook-Ceph, das die NVMe von vier RK1-Boards zu einem fehlertoleranten Speicher bündelt. Mit der echten CephCluster-Config, dem OSD-pro-NVMe-Mapping, den drei StorageClasses — und den Day-2-Kriegsgeschichten, wenn ein MON-Quorum oder eine OSD wegbricht.

In nahezu jedem Beitrag taucht es beiläufig auf: storageClass: ceph-block, eine RWO-PVC, ein copyMethod: Snapshot. Erklärt habe ich diese Schicht nie — dabei funktioniert ohne sie nichts. Das hier ist das Fundament: Rook -Ceph, das die NVMe-SSDs der Turing-Pi-/RK1-Boards zu einem fehlertoleranten Speicher zusammenfasst.