Files
cluster-knaster/docs/superpowers/plans/2026-10-12-aufbau-cluster-knaster.md
T
Robert RappandClaude Opus 5.5 d875a9620e
ci / test (push) Failing after 22s
Plan 0.2: Laptop im Dock mit .181 bestätigt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 17:12:58 +02:00

59 KiB
Raw Blame History

Aufbau Cluster „knaster“ – zusammengeführter Umsetzungsplan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Die fünf installierten Proxmox-Knoten werden Schritt für Schritt zum Cluster „knaster“ ausgebaut, auf dem die Architektur aus docs/PLAN.md läuft. Grundlage sind die echte Hardware und die Aufgaben aus Planner Epic 7.

Architecture: Fünf Proxmox-Knoten mit ZFS bilden einen Cluster. Jeder GPU-Knoten bekommt eine Ubuntu-VM, an die alle seine Karten durchgereicht werden; darin laufen Docker-Container pro Rolle. Die Infrastruktur (Router, Postgres, Monitoring) läuft als LXC mit Docker und HA. Die beiden RTX-4000-Ada-Rechner bleiben Windows-Arbeitsplätze und stellen ihre Leistung über die vorhandene Worker-Registry v2 bereit. Starke Modelle laufen ausschließlich über den LiteLLM mit PSE auf appsrv08.

Tech Stack: Proxmox VE 9.2 (Debian 13, ZFS), Ubuntu 24.04 in den GPU-VMs, NVIDIA R580 (Maxwell/Pascal), llama.cpp, whisper.cpp, Docker Compose, OpenTofu (bpg/proxmox), Ansible, Prometheus/Alertmanager/Grafana, Proxmox Backup Server, n8n (n8n.mindboost.app), LiteLLM (appsrv08), Python-Paket knaster.

Spec/Quellen (bei der Umsetzung mitlesen):

  • docs/PLAN.md, docs/adr/0001–0006, docs/IMPLEMENTATION.md, docs/BETRIEB.md (dieses Repo)
  • Planner „Epic 7 — CCO KI-Agent Infrastruktur“ (Plan NLQ0gHCZkUmdMv3ko__DmZgAHU_S, Bucket IeG9IcsEG0-_ZEW5unBaiZgAEtoE)
  • C:\Users\r.rapp\it\proxmox\STAND-2026-10-08.md und healthcheck-2026-10-08.txt (Ist-Stand der Knoten)
  • Repo mygodel/nex: docs/plans/2026-10-07-nex-stt-gpu.md (Whisper im Haus), docs/plans/2026-09-29-nex-worker-registry-v2.md (Ada-Worker)

Dieser Plan löst die Abläufe in docs/PLAN.md §8 („Roadmap“) und docs/IMPLEMENTATION.md („Gemeinsames Deployment“) ab. Deren Phasen sind unten zugeordnet.


Ausgangslage (Stand 12.10.2026)

Knoten IP Hardware Platten GPUs Besonderheit
pve44 192.168.100.210 ThinkStation P310, i7-6700, 32 GB 2× 256 GB (sdb: früher Windows, seit 12.10. tank) M4000 + P2000 –
pve46 192.168.100.209 ThinkStation P310, i7-6700, 32 GB 1× 256 GB M4000 + P2000 bootet Legacy statt UEFI
pve48 192.168.100.212 ThinkStation P310, i7-6700, 32 GB 3 Platten (SanDisk): sda 256 GB Proxmox, sdb 256 GB (früher Windows, seit 12.10. tank), sdc 128 GB (früher Windows 10, seit 12.10. leer) M4000 + P2000 bootet Legacy statt UEFI
pve52 192.168.100.207 ThinkStation P320, i7-7700, 32 GB 2× 256 GB (sdb: früher Windows mit BitLocker „GODEL55“, seit 12.10. tank) nur M4000 (keine P2000 verbaut) –
pve61 192.168.100.214 Surface Book, i5-8350U, 8 GB 1× 256 GB NVMe Intel UHD 620 LAN nur über USB-NIC im Lenovo-Dock, 2 Akkus

Alle Knoten: PVE 9.2.2, Kernel 7.0.2, ext4 + LVM-thin auf einer SSD (kein ZFS), 1 GbE, kein Cluster.

Stand 12.10. abends: PVE 9.2.21, Kernel 7.0.14 (pve61 noch 7.0.2 bis zum Neustart vor Ort), Cluster knaster mit 5 Stimmen, ZFS-Pool tank (238 GB) auf pve44, pve48 und pve52.

Aufteilung der Systemplatte (per SSH geprüft, auf allen fünf Knoten gleich, alles noch leer): 69 GB local (System, ISOs, Vorlagen, lokale Backups), 141 GB local-lvm (Platten der VMs und Container), 8 GB Swap, 16 GB frei in der Volume Group. SMART: alle Platten PASSED. Samsung-SSDs (pve44, pve52) zu 3–17 % verschlissen, Surface-NVMe (pve61) zu 46 %. Bei der SanDisk in pve46 steht der Rohwert für umgelagerte Sektoren auf 100; der Wert wird überwacht. VT-x und VT-d sind aktiv. IOMMU ist geprüft: Jede Karte liegt mit ihrer Audio-Funktion in einer eigenen Gruppe (M4000 in Gruppe 1, P2000 in Gruppe 8), Passthrough ist also möglich.

Außerhalb des Clusters:

  • GODE-PC-05/06: zwei Geräte mit je einer RTX 4000 Ada (20 GB) und 64 GB RAM (Nutzer, 12.10.). Die CPU ist noch offen. nvidia-smi meldet 20475 MiB (mygodel/scripts, tests/LocalLLMWorker.Tests.ps1). Auf GODE-PC-06 läuft llama-server (CUDA, Port 8080) mit Qwen3.8-27B-IQ4-MIX (rund 15 GB), 32K Kontext, alle Layer auf der GPU, Stufe expert (start-llama-server.ps1). Job NEX-1 lief dort in 102 s erfolgreich. Das Repo-Inventar von cluster-knaster nahm zwei Karten in einem Gerät an; das wird in Task 0.4 korrigiert. Windows, tagsüber Arbeitsplätze, laufen heute schon als LLM-Worker (LocalLLMWorker.ps1).
  • appsrv08 (.29): GRP produktiv, NEX und LiteLLM mit PSE-Filter.
  • n8n: n8n.mindboost.app.
  • Gitea: gitea.mindboost.team.

Global Constraints

  • Starke Modelle (tier0, OpenRouter) nur über den LiteLLM mit PSE auf appsrv08. Kein zweiter Gateway-Weg nach außen, sonst wird die Pseudonymisierung umgangen (Epic 7 „LiteLLM Swarm: PSE-Fix“).
  • Netz: flach 192.168.100.0/24, Gateway .1, DNS .120. Feste IP-Literale, kein DNS-Name in Konfigurationen, vorerst kein VLAN.
  • Container zuerst: Dienste laufen als Docker-Container, in LXC oder in einer VM. Eine VM gibt es nur dort, wo sie ein Treiberproblem löst (GPU-VM pro Knoten, D2) oder ein Produkt sie verlangt.
  • Dry-Run: Alle knaster-Aktionen gegen Infrastruktur starten mit KNASTER_DRY_RUN=true und werden erst nach einer Woche Beobachtung einzeln freigeschaltet.
  • STT: whisper-server auf Port 8178, nur von 192.168.100.29 erreichbar. stt.openai.base_url nur als IP-Literal (nex-STT-Plan, Annahmen).
  • Ada-Rechner: Windows bleibt, Mitarbeitende haben tagsüber Vorrang, kein Proxmox darauf.
  • Datacenter-weite Einstellungen (Benutzer, 2FA, Firewall, Benachrichtigungen, Pools, Metriken) erst, wenn alle Knoten im Cluster sind.
  • Platten: Die alten Windows-SSDs sind seit 12.10. gelöscht (Freigabe D1). Systemplatten (sda, NVMe) nie anfassen; Platten nur über /dev/disk/by-id/… mit Seriennummer ansprechen (auf pve52 unterscheiden sich System- und tank-Platte nur in der letzten Ziffer).
  • Geheimnisse nie ins Repo. Zugangsdaten liegen in C:\Users\r.rapp\it\proxmox\.env, der Schlüssel unter …\proxmox\keys\.
  • Planner-Webhook tdo-codex-update: pro Aufruf nur eine Aktualisierung, vorhandene Titel nie umbenennen (Abgleich läuft über den Titel, Schwelle 0.8).

Review Focus

  1. Eine Neuinstallation löscht die Einrichtung vom 08.10. Betroffen sind Schlüssel, Paketquellen, Dock-Bindung und SSH-Hostschlüssel. Erwartung: Das Bootstrap-Skript stellt alles wieder her, und ssh -o BatchMode=yes pveXX hostname klappt danach ohne Nachfrage (Task 1.1, Test im Skript).
  2. Der Cluster-Beitritt ersetzt authorized_keys. Erwartung: Nach jedem pvecm add funktioniert der Laptop-Zugang auf allen Knoten weiter (Task 2.1, Prüfschritt).
  3. Die USB-NIC von pve61 verschwindet nach einem Stromausfall oder einem Umstecken des Docks. Erwartung: vmbr0 hängt danach wieder an der Karte, ohne Eingriff (Task 1.3, Test: Dock aus- und einstecken).
  4. Ein Ada-Worker ist tagsüber belegt oder aus. Erwartung: tier1-Anfragen landen ohne Fehler bei tier0 über PSE (Task 6.4, Unit-Test im Router).
  5. Die Rolle pve-host sperrt NVIDIA und setzt VFIO. Erwartung: Das passiert nur auf GPU-Knoten. pve61 behält seine iGPU für den Kiosk (Task 3.1, Ansible-Gruppen, Prüfung lspci -k).

Entscheidungen (vor der jeweiligen Phase bestätigen)

# Frage Empfehlung Begründung Alternative
D1 Speicher B – keine Neuinstallation: Die System-SSD bleibt, wie sie ist. Die zweite SSD wird remote per SSH zum ZFS-Pool tank (pve44, pve48, pve52). pve46 und pve61 bleiben ohne ZFS. Kein Einsatz vor Ort, und es bleibt mehr Platz für Gäste: 141 GB local-lvm plus 238 GB tank statt rund 200 GB auf einem Spiegel aus zwei 256-GB-Platten. Spiegeln ließe sich nur auf pve44, pve48 und pve52, pve46 und pve61 haben eine einzige Platte. Das entspricht dem ursprünglichen ADR-0002 („SSD 1 System, SSD 2+ tank“). Replikation und HA laufen zwischen pve44, pve48 und pve52. Ohne ZFS bleiben nur pve46 (GPU-VM und ops, beide brauchen kein HA) und pve61 (Kiosk). Fällt eine System-SSD aus, wird dieser Knoten neu installiert; die Gäste sind repliziert. A – Neuinstallation mit ZFS (vor Ort, USB-Stick, Monitor, Tastatur): RAID1 auf Knoten mit zwei SSDs, local-zfs überall, Systemplatte gespiegelt, pve46 auf UEFI. Lässt sich später je Knoten nachholen.
D2 GPU als VM oder LXC Pro GPU-Knoten eine Ubuntu-24.04-VM mit allen Karten des Knotens, darin Docker Compose pro Rolle. Der Host-Kernel (7.0) bleibt ohne NVIDIA, Proxmox-Updates gefährden den Treiber nicht. R580 kommt als Ubuntu-Paket und ist per Snapshot rückrollbar. IOMMU-Gruppen sind geprüft. Eine VM pro Knoten statt pro Rolle (ADR-0001) spart RAM. Das Argument „gemischte Generationen“ aus ADR-0001 gilt im Cluster nicht mehr, alle Karten sind Maxwell/Pascal. Kosten: 2–5 % CPU, fest reservierter VM-RAM (12–16 GB von 32 GB). LXC mit Host-Treiber: braucht R580 auf Kernel 7.0 oder einen festgehaltenen älteren Kernel.
D3 Ada-Rechner Windows bleibt. LocalLLMWorker.ps1 mit llama-server (CUDA) meldet sich über die Worker-Registry v2. Die knaster-Slots tier1-general/tier1-flex lösen auf einen Worker auf, der online ist, sonst tier0. Die Registry v2 ist fast fertig (44 von 55 Schritten). Mitarbeitende werden nicht gestört. vLLM läuft unter Windows nicht nativ, Multi-LoRA, QLoRA und Qwen3-TTS kommen deshalb erst mit einer späteren WSL2-Entscheidung (Phase 9). Dual-Boot mit Proxmox: scheidet aus, die Rechner werden tagsüber genutzt.
D4 LiteLLM Kein eigener LiteLLM im knaster-Infra. Der Router nutzt den LiteLLM auf appsrv08 (mit PSE), die lokalen Slots werden dort als Modelle eingetragen. Es läuft bereits ein dritter LiteLLM; noch einer würde PSE für tier0 umgehen. Ein Modellwechsel bleibt eine Datenänderung. Eigener LiteLLM nur für lokale Slots, ohne OpenRouter-Zugang.
D6 Orchestrierung der Gäste-Dienste k3s (Server auf Dienst-VM k3s, Agents = GPU-VMs, NVIDIA Device Plugin), Portainer auf appsrv08 als Oberfläche über den Portainer-Agent (NodePort 30778). Entschieden 15.10.2026. Nutzer will die vier GPU-Hosts in Portainer als einen Cluster sehen. Portainer kennt dafür nur Swarm oder Kubernetes; Kubernetes plant GPUs sauber (Device-Plugin), Ökosystem (Helm) größer. GPU-Rechenleistung identisch, Grundlast k3s ~0,5–1 GB je Knoten. Docker Swarm (kaum GPU-Planung, kein Helm), RKE2 (gleiches Haus, schwerer), kubeadm.
D5 IP-Plan Knoten behalten .207–.214. Gäste bekommen einen festen Block außerhalb des DHCP-Bereichs. Vorschlag .220–.239, wird in Task 0.3 gegen den DHCP-Bereich geprüft. Die STT-Konfiguration braucht IP-Literale. Die alten GODEL-DNS-Einträge zeigen, dass die Knoten-IPs aus DHCP stammen, deshalb Reservierungen anlegen. VLAN svc (PLAN §1.4) später, wenn der Switch das zulässt.

Was hängt woran (Stand 12.10.)

Die Speicherfreigabe (D1) liegt seit 12.10. vor, tank steht auf pve44, pve48 und pve52; die rechte Spalte ist damit freigeschaltet. D2 ist entschieden (12.10.). D5 ist zurückgestellt: Gäste starten mit DHCP; feste IPs müssen vor Phase 6 stehen, weil STT und die LiteLLM-Slots IP-Literale nutzen. 19.10.: Reservierungen für pve44, pve52, gpu-pve52 und den Laptop bestätigt, Rest siehe Task 0.2.

Sofort möglich Braucht D2 (entschieden) Braucht die Speicherfreigabe
1.3 pve61-Netz am Dock · 5.1 Backup-Ziel entscheiden · 6.4 Worker-Registry v2 (nex) · NEX P1–P8 0.4 Site-Dateien/ADRs · 1.1 Erst-Update aller Knoten · 2.1 Cluster · Phase 4 (Benutzer, 2FA, Benachrichtigungen, Firewall, Pools, Zertifikat, Update-Routine) · 3.1/3.2 ops-LXC und GPU-VMs auf local-lvm (vorerst DHCP) · 3.3 Benchmark 1.2 tank anlegen · 2.2 Replikation/HA · 5.2 Infra-LXC mit HA (alternativ zuerst auf local-lvm, später verschieben) · 5.3 Kiosk-Anzeige · Phase 8 GRP-Test

Task 1.2 läuft am besten nach dem Cluster (2.1): Dann wird tank einmal für alle drei Knoten angelegt (pvesm add … --nodes pve44,pve48,pve52), statt die Speicherdefinition beim Beitritt zu überschreiben.

RAM-Budget je Knoten

Bei einem Knoten mit 32 GB sind 6 GB fest belegt: 2 GB für den Host und 4 GB ZFS-ARC. Eine GPU-VM reserviert ihre 12 GB vollständig, Passthrough erlaubt kein Ballooning. Damit bleiben auf einem GPU-Knoten 14 GB für Container und als Reserve für den Failover.

pve48 hat laut Inventar vom 12.10. M4000 und P2000 und ist damit der vierte GPU-Knoten. Im Einsatz sind insgesamt 4× M4000 und 3× P2000; pve52 hat nur die M4000.

Gast RAM Knoten
gpu-pve44, gpu-pve46, gpu-pve48, gpu-pve52 je 12 GB, fest auf dem eigenen Knoten
infra (LXC) 8 GB pve44 auf tank, Replikation nach pve52 und pve48
ops (LXC) 2 GB pve46 (kein HA nötig, per Ansible neu aufsetzbar; 2 GB statt 1 GB, pve46 hat keinen ZFS-ARC)
pbs (VM) 4 GB pve52
grp-test (LXC) 4 GB pve48 auf tank, Replikation nach pve44
pve61 8 GB gesamt keine Gäste, nur Kiosk

Regeln:

  • Die Summe der Gäste je Knoten bleibt bei höchstens 26 GB (32 − 6).
  • Das Replikationsziel von infra hat immer mindestens 8 GB frei, sonst scheitert der HA-Neustart still.
  • Prüfung nach jedem neuen Gast: pvesh get /nodes/<knoten>/status --output-format json | jq .memory.

Phase 0 – Bestandsaufnahme und Repo an die Wirklichkeit anpassen

Ersetzt PLAN §8 „0 Fundament“ (Teil Inventar) und IMPLEMENTATION „Gemeinsames Deployment“ Schritt 1.

Task 0.1: Zugang zu pve48 und Inventar aller Knoten

Wo: Teil a vor Ort an der Konsole von pve48, Teil b remote · Planner: „Proxmox: pve48 root-Passwort klären und SSH-Schlüssel nachtragen“

  • a: Richtiges Passwort in .env (PVE48_PASS) eingetragen (12.10., der alte Wert war falsch).
  • b: Schlüssel verteilt (push_keys.py pve48), Paketquellen auf pve-no-subscription umgestellt (Sicherung /root/apt-backup-2026-10-12/, 184 Updates offen, kein Upgrade). Prüfung: ssh -o BatchMode=yes pve48 hostname → pve48.
  • c: Inventar pve48 (12.10.): P310, i7-6700, 32 GB, Legacy-Boot, VT-d aktiv, M4000 in Gruppe 1, P2000 in Gruppe 8, 1 GbE, Wake-on-LAN g, SMART aller drei Platten PASSED. Eingetragen in Ausgangslage und healthcheck-2026-10-08.txt.
  • d: pve52 hat nur die M4000, eine P2000 ist dort nicht verbaut (Nutzer, 12.10.). Es sind 3× P2000 im Einsatz (pve44, pve46, pve48).
  • d2: Verbleib von Godel45 klären (im STT-Plan aufgeführt).
  • e: Ada-Rechner GODE-PC-05/06: je Gerät eine RTX 4000 Ada (20 GB) und 64 GB RAM (Nutzer, 12.10.).
  • e2: CPU der Ada-Rechner erfassen, nebenbei aus dem Heartbeat der Worker-Registry v2 (cpuCores) oder mit Get-CimInstance Win32_Processor.

Task 0.2: DHCP-Bereich und IP-Plan (D5)

Wo: remote (DHCP-Server, vermutlich DC .120 oder UniFi) · Planner: „PVE-Config: Netzwerk prüfen – Bridge, VLAN-Fähigkeit und NIC-Kompatibilität“

  • (14.10.) ops und infra auf feste Adressen .173/.188 umgestellt (BETRIEB §10), damit hängt der Steuerrechner nicht mehr am Lease. Laptop kam am 14.10. per Dock mit .181, als zweite Adresse in firewall.management aufgenommen.
  • Reservierungen beim DC-Support anfordern (15.10. angefragt; MAC-Liste vom 14.10.: Knoten, ops bc:24:11:c1:d9:c8, infra bc:24:11:6d:e5:c0, gpu-pve52 bc:24:11:92:4b:eb, nachreichen: k3s-VM bc:24:11:a5:d5:52 → .124, Laptop WLAN 34:fd:70:65:06:6c und Dock 84:ba:59:fb:e0:36) plus Ausschluss .220–.239. Nötig ist dafür nur die Gruppe „DHCP-Administratoren“ auf dem DC .120, kein Domänen-Admin.
    • (19.10., Bestätigung an den Nutzer) Feste Adressen per Reservierung: pve44 (.210), pve52 (.207), gpu-pve52 (.174, node.json auf infra) und der Laptop über WLAN (.151, gemessen) und LAN im Dock (.181, gemessen 19.10.). Damit ist die Laptop-Sperre aus BETRIEB §10 behoben.
    • Laut DC derzeit nicht konfigurierbar: infra (.188), pve46 (.209), pve48 (.212). Alle drei sind im Gast bzw. in /etc/network/interfaces statisch eingestellt (19.10. geprüft), hängen also an keinem Lease. Restrisiko: Der DHCP-Server vergibt die Adresse an ein anderes Gerät, dann gibt es einen Konflikt. Ob das droht, zeigt erst „DHCP-Bereich auslesen“ (liegen die Adressen im Bereich?). Liegen sie darin, als Alternative einen Ausschluss der Einzeladressen erfragen.
    • Ohne Rückmeldung: ops (.173, statisch), k3s-VM (.124), gpu-pve44/46/48, pve61 (.214), Ausschluss .220–.239.
  • Später (Phase 9): eigenes Verwaltungs-/Dienstnetz als VLAN, Vorbedingung: Switch kann VLAN, Routing beim Netzverantwortlichen geklärt. Bis dahin bleibt die Adressliste in der Proxmox-Firewall der Schutz.
  • DHCP-Bereich auslesen. Seit 13.10. dringender: Die Firewall (4.4) lässt nur .151 (Laptop), .173 (ops) und .188 (infra) an die Verwaltungsports; ein Lease-Wechsel sperrt die Quelle aus (BETRIEB §10). Für .207, .209, .210, .212 und .214 Reservierungen auf die MACs der Knoten anlegen (MACs stehen im Healthcheck). Ebenso eine Reservierung für den Admin-Laptop (heute .151 per WLAN). Die Firewall in 4.4 lässt nur diese Adresse zu, ein Lease-Wechsel würde sonst aussperren. 19.10.: Laptop, pve44 und pve52 reserviert; der Bereich selbst ist noch nicht ausgelesen und entscheidet über das Restrisiko für infra, pve46, pve48.
  • Gäste-Block festlegen (Vorschlag .220–.239) und als Ausschluss im DHCP eintragen. Prüfung: ping auf jede Adresse des Blocks → keine Antwort. DHCP-Ausschluss sichtbar.

Task 0.3: Entscheidungen D1–D5 bestätigen

Wo: Gespräch mit dem Nutzer

  • D1 entschieden (12.10.): Variante B, keine Neuinstallation. Alle alten Windows-Platten werden für den Cluster vollständig gelöscht.
  • D1-Freigabe zum Löschen (12.10., „festplatten alle platt machen“): pve44 sdb NTFS, pve52 sdb BitLocker „GODEL55“, pve48 sdb und sdc. Alle vier gelöscht (Task 1.2).
  • D2 entschieden (12.10.): eine GPU-VM pro Knoten. Vorteil, der schon heute greift: Das anstehende Kernel-Update 7.0.2 → 7.0.14 berührt keinen NVIDIA-Treiber.
  • D5 zurückgestellt (12.10., „Schritt zwei“): Gäste vorerst per DHCP. Für feste IPs braucht es keinen DNS-Eintrag, sondern einen Ausschluss bzw. Reservierungen im DHCP-Server. Den verwaltet nicht der Nutzer. Dabei auch die Knoten-IPs .207–.214 reservieren lassen (Corosync bindet an sie). Stand 19.10. in Task 0.2.
  • D3 und D4 bestätigen. Ergebnis als Abschnitt „Entscheidungen 2026-10“ in docs/PLAN.md §9 eintragen.

Task 0.4: Site-Dateien, Ansible-Inventar und ADRs an die echte Hardware anpassen

Wo: remote, Repo · Files:

  • Modify: sites/knaster/inventory.yaml, sites/knaster/proxmox.yaml, sites/knaster/registry.yaml, platform/proxmox/ansible/inventory.yml, docs/PLAN.md §1.3, §1.4 und §9
  • Modify: docs/adr/0001-gpu-vms-infra-lxc.md (eine VM pro Knoten), docs/adr/0002-storage-zfs-kein-ceph.md (D1), docs/adr/0006-legacy-gpus-llamacpp-tts-auf-ada.md (Ada unter Windows, D3)
  • Test: core/tests/test_inventory_validate.py

Interfaces:

  • Produces: Proxmox-Knoten pve44, pve46, pve48, pve52, pve61, dazu die Inventar-Knoten gode-pc-05 und gode-pc-06 (Ada, ohne Proxmox, nur im Inventar). PCI-Mappings gpu-m4000-pve44, gpu-p2000-pve44, gpu-m4000-pve46, gpu-p2000-pve46, gpu-m4000-pve52, gpu-m4000-pve48, gpu-p2000-pve48. GPU-VMs gpu-pve44 (vmid 244), gpu-pve46 (246), gpu-pve48 (248), gpu-pve52 (252). Infra-LXC infra (vmid 101). Ansible-Gruppen pve_all, pve_gpu_hosts, pve_kiosk.

  • Step 1: Failing test. In test_inventory_validate.py den Test test_site_knaster_matches_real_nodes anlegen:

    • Die Inventar-Knoten sind genau {pve44, pve46, pve48, pve52, pve61, gode-pc-05, gode-pc-06}.
    • proxmox.yaml enthält keine IP aus 10.20.0.0/24.
    • Jedes pci_mappings[*].node und jedes vms[*].node liegt in {pve44, pve46, pve48, pve52}.
  • Step 2: make test → FAIL (alte Annahmen pve-ada, pve1–pve4).

  • Step 3: Site-Dateien umschreiben. Werte für IDs und Pfade aus lspci -nn und dem Healthcheck: M4000 10de:13f1 auf 0000:01:00, P2000 10de:1c30 auf 0000:02:00. Gateway 192.168.100.1, DNS 192.168.100.120, keine vlan_svc, Gast-IPs aus D5. Die M4000 bleiben disabled: true bis zum Benchmark-Tag (Task 3.3). Die Ada-Slots (tier1-general, tier1-flex, tts-de-hq) behalten vorerst ihre Engine. In registry.yaml entfallen bei ihnen nur pve_node und vmid. Die Umstellung auf die Worker-Registry folgt in Task 6.4.

  • Step 4: make test && make validate → PASS. knaster placement plan --inventory sites/knaster/inventory.yaml liefert eine Zuordnung ohne Fehler.

  • Step 5: Commit sites: Inventar und Zielbild an echte Knoten (pve44–pve61) angepasst; ADR-0001/0002/0006 ergänzt.


Phase 1 – Knoten-Grundlage (vor dem Cluster)

Task 1.1: Bootstrap-Skript für einen frischen Knoten

Wo: remote · Planner: „PVE-Config: Erst-Update aller Knoten (apt full-upgrade)“ · Files: Create platform/proxmox/scripts/bootstrap-node.sh, Create platform/proxmox/scripts/README.md

Interfaces:

  • Produces: bootstrap-node.sh <knoten>, idempotent. Ausgabe endet mit BOOTSTRAP OK <hostname> oder Exit ≠ 0.

  • Step 1: Das Skript (läuft auf dem Laptop, Git-Bash) erledigt Folgendes (12.10.: ssh-keygen -R nur mit --reinstall, Update abgekoppelt per systemd-run):

    • alten Hostschlüssel mit ssh-keygen -R <ip> entfernen
    • Schlüssel per Passwort aus .env eintragen, mit dem SSH_ASKPASS-Verfahren vom 08.10. (nur anhängen, grep -qxF)
    • Enterprise-Quellen auf Enabled: no setzen, proxmox.sources mit pve-no-subscription anlegen, vorher sichern
    • apt-get update && apt-get -y full-upgrade
    • Pakete ethtool lm-sensors installieren
    • Prüfen: timedatectl show -p NTPSynchronized = yes
  • Step 2: Zweiter Lauf gegen denselben Knoten → keine Änderung, wieder BOOTSTRAP OK (pve44, 12.10., 17 s).

  • Step 3: Commit.

  • Step 4 (Ausführung 12.10.): Alle Knoten auf PVE 9.2.21 / Kernel 7.0.14-23 gebracht (pve44, pve46, pve48, pve52 neu gestartet und geprüft; pve61 Neustart offen); nach jedem Neustart Kernel, systemctl --failed, vmbr0, NTP sowie GPU-Adressen und IOMMU-Gruppen geprüft. pve61 wird erst neu gestartet, wenn der Nutzer vor Ort ist (USB-NIC im Dock).

Task 1.2: Speicher (D1)

Planner: „Proxmox: Speicher aller Knoten richtig konfigurieren“ (enthält die frühere Aufgabe zur RAM-Planung)

Variante B (Empfehlung) – remote, ohne Neuinstallation

  • Freigabe aus Task 0.3 liegt vor (12.10.). Auf pve44, pve48 und pve52 die zweite SSD gelöscht und tank angelegt. Die Platten wurden nur über ihre Seriennummer angesprochen; vor dem Löschen wurde geprüft, dass sie nicht die Systemplatte, nicht eingehängt und nicht in Benutzung sind:

    Knoten tank auf Systemplatte (unberührt)
    pve44 ata-SAMSUNG_MZ7LN256HAJQ-000L7_S3S7NY0K403015 Samsung S20HNAAH271598
    pve48 ata-SanDisk_SD6SB1M256G1022I_140877401621 SanDisk 164862429106
    pve52 ata-SAMSUNG_MZ7LN256HAJQ-000L7_S3S7NY0K403017 Samsung S3S7NY0K403016 (gleiches Modell, nur die letzte Ziffer unterscheidet sich)

    Ablauf je Platte: wipefs -a (Partitionen, dann Platte), sgdisk --zap-all, blkdiscard. Danach zpool create -o ashift=12 -O compression=lz4 -O atime=off tank /dev/disk/by-id/<ssd2> und systemctl enable zfs-import@tank.service. Einmal im Cluster: pvesm add zfspool tank --pool tank --content images,rootdir --sparse 1 --nodes pve44,pve48,pve52. pve48 sdc (SanDisk 128 GB, 140621401586) ist ebenfalls gelöscht und bleibt vorerst ungenutzt. Als Stripe in tank würde sie das Ausfallrisiko verdoppeln.

  • ZFS-ARC auf 4 GiB begrenzt: /etc/modprobe.d/zfs.conf, update-initramfs -u -k all, zusätzlich sofort über /sys/module/zfs/parameters/zfs_arc_max. Prüfung 12.10.: zpool status tank → ONLINE auf allen drei Knoten. pvesm status → tank active auf pve44, pve48 und pve52 (auf pve46 und pve61 disabled, wie gewollt).

  • Neustart-Probe (12.10.): pve48 (Legacy-BIOS) und pve44 (UEFI) neu gestartet. Beide starten von sda, tank wird importiert (ONLINE, pvesm active), ARC = 4294967296, keine fehlgeschlagenen Dienste, GPU-Stand unverändert, Quorum 5/5.

  • Nebenbefund pve44: Die EFI-Partition sda2 ist nicht unter /boot/efi eingehängt (kein Eintrag in /etc/fstab). Der Start klappt, aber GRUB-Updates erreichen die EFI-Partition nicht. Eintrag UUID=BB96-13D2 /boot/efi vfat defaults 0 1 nachtragen, grub-install prüfen. Die alten Windows-Starteinträge im UEFI (pve44 Boot000E, pve52 Boot000D) zeigen ins Leere und können mit efibootmgr -b <nr> -B entfernt werden.

Variante A – Neuinstallation mit ZFS

Wo: vor Ort, USB-Stick mit PVE 9.2 (ISO und Prüfsumme in C:\Users\r.rapp\it\proxmox)

Reihenfolge: pve46 (eine Platte, Legacy → UEFI), dann pve44, pve52, pve48 und zuletzt pve61 mit angestecktem Dock (der USB-C-Adapter ist zurückgegeben).

  • Pro Knoten: BIOS auf UEFI, Secure Boot aus. Installer: gleicher Hostname und gleiche IP wie bisher, ZFS (RAID1) bzw. ZFS (RAID0) bei einer Platte, ashift=12, compress=on.
  • Prüfpunkt iGPU (GPU-Knoten): Im BIOS die Onboard-Grafik als primäre Anzeige einstellen und den Monitor ans Mainboard anschließen. Prüfung: Die Proxmox-Konsole erscheint am Mainboard-Anschluss. Rückfall, falls das BIOS die iGPU bei eingesteckter Karte abschaltet: die P2000 in Steckplatz 1 und die M4000 in Steckplatz 2 tauschen. Die Boot-Grafik ist dann die P2000; für sie gilt beim Passthrough in Task 3.2 x-vga/ROM-Prüfung.
  • Neues root-Passwort trägt der Nutzer vor dem nächsten Schritt in .env ein (PVExx_PASS), sonst scheitert das Bootstrap-Skript.
  • Danach bootstrap-node.sh <knoten> → BOOTSTRAP OK.
  • ZFS-ARC begrenzen: zfs_arc_max = 4 GiB auf 32-GB-Knoten, 1 GiB auf pve61 (/etc/modprobe.d/zfs.conf, update-initramfs -u). Prüfung: zpool status → ONLINE. pvesm status → local-zfs active. cat /sys/module/zfs/parameters/zfs_arc_max → 4294967296 bzw. 1073741824.

Task 1.3: pve61 – Netzwerk am Dock robust machen, Akku schonen

Wo: remote, Akku-Einstellung vor Ort · Planner: Teil von „Proxmox: pve61 (Surface) zeigt das Grafana-Dashboard als Kiosk“

  • NIC des Docks per systemd-.link auf den Namen nic0 festlegen, Zuordnung über die MAC 3c:e1:a1:c0:83:9d. bridge-ports nic0 in /etc/network/interfaces. Nach dem Ausstecken hängt ein udev-Hook ifup/ifreload die Karte wieder an vmbr0.
  • Test (vor Ort): Dock 10 s ausstecken und wieder einstecken → nach höchstens 30 s ping 192.168.100.214 vom Laptop ok.
  • Surface-UEFI „Battery Limit“ einschalten (Lauter-Taste + Einschalten). Prüfung: grep . /sys/class/power_supply/BAT*/capacity pendelt bei etwa 50 %.

Phase 2 – Cluster

Ersetzt GPU-Knoten 3 (Teil Cluster). Mit 5 Stimmen ist kein QDevice nötig.

Task 2.1: Cluster „knaster“ bilden

Wo: remote · Planner: „GPU-Knoten 3: Cluster mit QDevice (Container auf appsrv08), NVIDIA-Treiber, GPU-Container“ (Teil Cluster)

  • Auf pve44: pvecm create knaster --link0 192.168.100.210 (12.10.).
  • Nacheinander auf pve46, pve48, pve52 und pve61 beigetreten (12.10.). Statt pvecm add (fragt das Passwort am Terminal ab) pvesh create /cluster/config/join --hostname 192.168.100.210 --fingerprint <sha256 von pve44> --link0 <eigene IP> --password …, Passwort per stdin, Windows-Zeilenende entfernen. Nach jedem Beitritt den Laptop-Schlüssel in /etc/pve/priv/authorized_keys prüfen und gegebenenfalls einmal ergänzen. Prüfung: pvecm status → Quorate: Yes, Total votes: 5. for n in pve44 pve46 pve48 pve52 pve61; do ssh -o BatchMode=yes $n hostname; done → fünf Namen.
  • Datacenter-Optionen: Migrationsnetz 192.168.100.0/24, Typ secure. Ergebnis 12.10.: Nodes: 5, Quorate: Yes, Total votes: 5, Schlüssel-Login auf allen fünf Knoten ok.

Task 2.2: HA-Regeln und Replikation

Wo: remote

  • Node-Affinity-Regeln (12.10., per Ansible pve-host, nicht tofu – der Token braucht so kein Sys.Console): Regel knaster-infra, ct:101, pve44:2,pve52:1,pve48:1, strikt. Infra-Dienste nur auf pve44, pve48, pve52. pve61 bekommt keine HA-Gäste, GPU-VMs bleiben an ihrem Knoten.
  • Replikation (12.10.): Jobs 101-0 → pve52 und 101-1 → pve48, */15, Erstlauf je 14 s. Test 12.10.: Manuelles migrate nach pve52 lehnt PVE 9 ab (niedrigere Priorität, solange pve44 lebt – gewollt). Wartungsmodus ha-manager crm-command node-maintenance enable pve44 → infra nach 36 s auf pve48 gestartet, Testdatei aktuell, Docker läuft, IP gleich; disable → nach 41 s zurück auf pve44. Echter Ausfall (Strom weg) noch nicht getestet – nur vor Ort. Prüfung: ha-manager rules config bzw. ha-manager groupconfig zeigt die Regeln.

Phase 3 – GPU-Grundlage und Benchmark-Tag

Task 3.1: Steuerrechner „ops“ und Host-Rolle nur für GPU-Knoten

Wo: remote · Files: Modify platform/proxmox/ansible/inventory.yml, platform/proxmox/ansible/playbooks/site.yml, Create platform/proxmox/README.md (Abschnitt ops-LXC)

  • LXC ops (12.10.): CT 100 auf pve46, Debian 13.6, unprivilegiert, 2 Kerne, 2 GB, 8 GB local-lvm, DHCP (heute 192.168.100.173, Alias ops in der SSH-Konfiguration des Laptops). ansible-core 2.19.11, OpenTofu 1.13.1 (offizielles signiertes Repo), git, make, python3-venv. Eigener Schlüssel root@ops steht in /etc/pve/priv/authorized_keys (gilt für alle Knoten), known_hosts vom Laptop übernommen (geprüfte Einträge), StrictHostKeyChecking yes. Repo-Clone anonym über HTTPS (Branch plan/aufbau-2026-10-12); geändert wird auf dem Laptop, ops macht nur git pull.
  • site.yml: pve-host nur für pve_gpu_hosts (pve44, pve46, pve48, pve52). pve61 steht in pve_kiosk ohne VFIO und Blacklist.
  • Rolle pve-host ergänzen (12.10., IDs liest die Rolle per lspci -n -d 10de: auf dem Knoten; zusätzlich softdep nouveau/snd_hda_intel pre: vfio-pci, initcall_blacklist=sysfb_init, Handler update-initramfs; Handler-Fehler behoben: proxmox-boot-tool refresh || update-grub erreichte update-grub nie): /etc/modprobe.d/vfio.conf mit options vfio-pci ids=<liste> und softdep nvidia pre: vfio-pci. Die Liste enthält die Grafik- und die Audio-Funktionen der Karten. Die IDs aus lspci -nn -s 01:00 und lspci -nn -s 02:00 auf dem Knoten lesen, nicht aus dem Gedächtnis eintragen; auf allen GPU-Knoten gelesen (12.10.): M4000 10de:13f1 + Audio 10de:0fbb, P2000 10de:1c30 + Audio 10de:10f1.
  • ansible-playbook playbooks/site.yml --limit pve_gpu_hosts --check, danach der echte Lauf. Knoten einzeln neu starten (12.10.: pve48 als Pilot inkl. Wegwerf-VM mit beiden Karten, dann pve44, pve52, pve46). Ergebnis 12.10.: auf allen vier GPU-Knoten jede NVIDIA-Funktion an vfio-pci, keine fehlgeschlagenen Dienste. Die M4000 ist überall die Boot-Grafik und es gibt keine iGPU: Der lokale Bildschirm bleibt nach dem frühen Start schwarz, Zugang per SSH/Weboberfläche, GRUB-Menü bleibt sichtbar. Die P2000 kann kein FLR, der Bus-Reset klappt („reset done“). Prüfung: lspci -nnk -s 01:00 und lspci -nnk -s 02:00 auf jedem GPU-Knoten → bei allen Funktionen Kernel driver in use: vfio-pci. Auf pve61: lspci -k -s 00:02.0 → i915.

Task 3.2: Resource Mappings, Template und GPU-VMs

Wo: remote (ops-LXC) · Planner: „GPU-Knoten 3 …“ (Teil NVIDIA, GPU-Container)

  • PCI-Resource-Mappings aus sites/knaster/proxmox.yaml anlegen (Namen aus Task 0.4) – per tofu (proxmox_hardware_mapping_pci), 12.10.
  • Ubuntu-24.04-Cloud-Template je Knoten (12.10.): 9044, 9046, 9048, 9052 statt 9000 überall, weil VMIDs clusterweit eindeutig sind. platform/proxmox/scripts/make-template.sh <knoten> <vmid> (Prüfsumme gegen SHA256SUMS, kein Secure Boot wegen DKMS, Gast-Agent an).
  • API-Benutzer tofu@pve mit Token tofu@pve!ops (12.10.), Rechte nur: / PVEAuditor, /vms PVEVMAdmin, /storage PVEDatastoreUser, /sdn/zones/localnetwork PVESDNUser, /mapping/pci PVEMappingAdmin. Token nur auf ops in /root/.config/knaster/tofu.env (600). Für HA (5.2) kommt Sys.Console hinzu.
  • tofu-Code an D2/D5 angepasst (12.10.): bpg/proxmox ~> 0.116.0, hostpci dynamisch aus vms.*.gpus, DHCP mit Adresse über den qemu-guest-agent (Vendor-Snippet local:snippets/knaster-vendor.yaml aus pve-host), Speicher je Gast, Ausgabe ansible_inventory. tofu plan: 11 neue Objekte.
  • (12.10.) tofu plan und dann tofu apply für gpu-pve44, gpu-pve46, gpu-pve48 und gpu-pve52: alle Karten des Knotens, 12 GB RAM, 4 Kerne, Systemplatte 40 GB und Modellplatte 60 GB auf local-lvm (Variante B) bzw. local-zfs (Variante A), IPs aus D5.
  • ansible-playbook … --limit gpu_vms (Rollen docker-host und gpu-node, driver_generation: legacy = R580 → 580.178.04, DKMS), 12.10. Ergebnis 12.10., auch nach Neustart aller VMs: gpu-pve44/46/48 sehen M4000 + P2000, gpu-pve52 die M4000, docker run --gpus all … sieht alle Karten, Modellplatte 60 GB unter /srv/models. Befund DHCP: Nach dem ersten Neustart hatten zwei VMs ihre Adressen getauscht (DUID als Client-ID); die strenge Hostschlüssel-Prüfung hat gestoppt. Jetzt dhcp-identifier: mac (netplan), Zugang nach jedem Neustart mit scripts/refresh-vm-access.sh auffrischen. Dauerhaft löst das nur D5 (Reservierungen auf die MACs: gpu-pve44 bc:24:11:6a:67:15, gpu-pve46 bc:24:11:75:ad:33, gpu-pve48 bc:24:11:f5:da:73, gpu-pve52 bc:24:11:92:4b:eb). 19.10.: gpu-pve52 reserviert (.174), die übrigen drei offen. Prüfung in jeder VM: nvidia-smi -L → beide Karten. docker run --rm --gpus all nvidia/cuda:12.6.3-base-ubuntu24.04 nvidia-smi → beide Karten.

Task 3.3: Benchmark-Tag (fasst drei Pläne zusammen)

Wo: remote, Strommessung vor Ort (Messgerät an der Steckdose) · Planner: „GPU-Knoten 4: Geschwindigkeitstests (Gate) auf M4000 und P2000“ · ersetzt außerdem den „Benchmark-Tag“ aus IMPLEMENTATION und den Gate-Task 1 des nex-STT-Plans

  • llama-bench je Kartentyp: Embedding-Modell, 3–4B Q4 (verifier/signature), 7B Q4. Tokens/s und VRAM messen. (12.10., gpu-pve48, llama.cpp b6000/CUDA 12.4, sm_52/61) pp512/tg128 in t/s: Embedding 0.6B Q8 M4000 929 / P2000 1009; Qwen3-4B Q4 M4000 197/15,1, P2000 271/14,5; Qwen3-8B Q4 M4000 115/10,0, P2000 152/9,0. VRAM beim Katalog-Kontext 2,8 / 4,1 / 7,7 GiB, das 8B mit 16k passt nur auf die M4000. Details in ADR-0006.
  • whisper.cpp large-v3-turbo, Sprache de: Sekunden je 10 s Diktat auf M4000 und P2000. Klärt, ob CC 5.2 überhaupt rechnet. Zusätzlich die Dialekt-Testsätze.
    • (12.10., gpu-pve48, v1.9.5, synthetisches Piper-Audio) P2000: 3,5 s je 10-s-Clip, 2,5 s je 10 s bei 33 s Audio; M4000 zum Vergleich 2,7 s bzw. 2,1 s. CC 5.2 rechnet, Flash-Attention eingeschlossen. M4000 im Dienst: gpu-pve52 (Task 6.2).
    • Offen: Dialekt-Testsätze (echte Sprecher nötig).
  • knaster bench tts (Piper, CPU). (12.10., Image tts-piper, 4 vCPU i7-6700) RTF 0,17 bei 241 Zeichen, 0,11 bei 596 Zeichen.
  • Strom je Knoten: Leerlauf und Volllast beider Karten (400-W-Netzteil, erwartet etwa 300 W).
  • Ergebnis eintragen in catalog/models.yaml und sites/knaster/registry.yaml, in ADR-0006 „M4000 wieder aufnehmen ja/nein“ und in die STT-Entscheidung D131/D133 (nex). Commit.
    • (12.10.) Katalog: vram_gb gemessen (Embedding 2,8, 4B 4,1, 8B 7,8 aufgerundet) und Messwerte als note. Die Registry hat keine Felder für Messwerte und bleibt unverändert. ADR-0006 Nachtrag „Benchmark“: M4000 ja für STT auf pve52, auf pve44/46/48 vorerst nein (P2000 gleich schnell bei halber Leistung). knaster validate und pytest core grün (außer dem bekannten Windows-Fehler in test_tts_server), Placement unverändert, alle aktiven Rollen auf gemessenen P2000.
    • Offen: STT-Entscheidung D131/D133 im nex-Repo, disabled der M4000 auf pve52 erst nach der Strommessung (Nutzer). Rerank-VRAM neben Embedding auf der P2000 ungemessen. Für Task 6.1: Compose count: 1 greift die M4000, device_ids setzen. Prüfung: make validate → PASS, Placement ordnet jede aktive Rolle einer gemessenen Karte zu.

Phase 4 – Cluster-Grundkonfiguration (erst wenn alle Knoten drin sind)

Wo: remote. Jede Aufgabe hier entspricht einer Planner-Aufgabe.

  • 4.1 Benutzer und Token (13.10. erledigt, Rolle pve-cluster/playbooks/cluster.yml: Gruppe admins (Administrator auf /), r.rapp@pve mit Passwort per scripts/pve-admin-user.sh, Rolle KnasterHealer + healer@pve!knaster nur auf /pool/gpu, Token auf ops /root/.config/knaster/healer.env; BETRIEB §8) (12.10. teilweise: tofu@pve!ops mit engen ACLs und monitoring@pve!prom (PVEAuditor, Geheimnis nur auf ops /root/.config/knaster/pve-exporter.env) angelegt; offen: persönlicher Admin-Benutzer (Name vom Nutzer), healer@pve!knaster) („PVE-Config: Persönlicher Admin-Benutzer, Rollen und API-Token anlegen“): Admin-Benutzer und Gruppe, root@pam nur als Notfallzugang. Token monitoring@pve!prom (PVEAuditor), healer@pve!knaster (nur VM.PowerMgmt auf GPU-VMs, PLAN §3), tofu@pve!ops.
  • 4.2 2FA (13.10.: TOTP + Recovery-Keys für r.rapp@pve, Datei it/proxmox/tfa-r.rapp.txt; root@pam bewusst ohne 2FA als Notfallzugang, BETRIEB §8) („PVE-Config: Zwei-Faktor-Authentifizierung für Admin-Konten aktivieren“): TOTP für root@pam und Admin. Recovery-Keys offline ablegen.
  • 4.3 Benachrichtigungen (13.10.: Ziel knaster-mail → ki@mygodel.de per Sendmail direkt an die MX, Matcher knaster-alles, default-matcher aus, Testmail zugestellt; BETRIEB §9) („PVE-Config: Benachrichtigungen (Notification Center) einrichten“): SMTP-Ziel Büro-Postfach, Matcher für Backup, Fencing und Updates. Testnachricht kommt an.
  • 4.4 Firewall (13.10.: aktiv auf allen Knoten, IPSET admin = Knoten + .151/.29/.173/.188, ACCEPT +admin dann DROP /24 auf 22/8006/3128/5900-5999/60000-60050 – management taugt nicht, Proxmox ergänzt es stets um das /24; Totmannschalter im Playbook; Negativtest aus GPU-VM bestanden; BETRIEB §10) („PVE-Config: Firewall auf Datacenter- und Knotenebene einrichten“): IP-Set admin (Laptop) und appsrv08 (.29). Zuerst Allow-Regeln für 8006, 22 und ICMP, dann aktivieren. Konsole als Rückfall bereithalten. Prüfung: Weboberfläche vom Laptop ok, von einem anderen Rechner gesperrt.
  • 4.5 Ordnung (12.10.: Pools gpu = 244/246/248/252 per tofu, infra = 100/101 per pveum – beim Container würde pool_id in tofu ein Ersetzen erzwingen; Tags knaster, gpu, legacy, infra, ops per tofu/pct. LXC-Standard so umgesetzt: unprivilegiert, Debian 13.6, Nesting nur bei Docker) („PVE-Config: Ressourcenpools und Tags festlegen“, „PVE-Config: Standard für neue LXC-Container festlegen“): Pools infra, gpu, test. Tags gpu, infra, test. LXC-Standard: unprivilegiert, Debian-13-Vorlage, Nesting nur für Docker.
  • 4.6 Zertifikat (13.10.: CA nach it/proxmox/pve-root-ca.pem kopiert, Knotenzertifikate tragen die IP als SAN; Import am Laptop per certutil -user -addstore Root …, BETRIEB §11) („PVE-Config: Web-GUI-Zertifikat festlegen (niedrige Priorität)“): /etc/pve/pve-root-ca.pem auf dem Laptop als vertrauenswürdig importieren.
  • 4.7 Update-Routine (12.10.: docs/BETRIEB.md Abschnitt 6, Wartungsmodus getestet) („PVE-Config: Update- und Neustart-Routine festlegen (rollierend, Knoten für Knoten)“): Ablauf in docs/BETRIEB.md eintragen (Wartungsmodus, ein Knoten nach dem anderen, GPU-VMs vorher sauber stoppen).

Phase 5 – Backup und Monitoring

Task 5.1: Proxmox Backup Server

Wo: remote, Speicherort vor Ort · Planner: „Proxmox: Backup-System überlegen“ (beantwortet PLAN §9, offener Punkt 6)

  • Ziel-Speicher entscheiden. Empfehlung: externer Datenträger oder NAS, nicht die Toshiba-Platte „BACKUP“ des Nutzers. Prüfung 12.10. (nur lesend): Die angeschlossene 4-TB-HDD ist die Toshiba „BACKUP“ (USB, exFAT, rund 126 GB belegt), Windows meldet „Full Repair Needed“ und Controller-/Paging-Fehler (Event 11/51). Für den Cluster ausgeschlossen. Vorschlag: eigene 4-TB-CMR-Platte intern per SATA in pve52 oder pve44 (auf allen vier P310/P320 melden ata2–ata4 „link down“, freie Schächte/Kabel vor Ort prüfen). Surface/pve61 scheidet aus (Platte und einzige Netzkarte hängen an derselben USB-Kette). PBS als VM pbs (vmid 110), Datastore auf dem Ziel.
  • Jobs: nächtlich Infra-LXC, ops-LXC und GPU-VMs (ohne Modellplatte), Aufbewahrung 7 Tage, 4 Wochen und 6 Monate. Dazu ein wöchentlicher Verify-Job.
  • Restore-Test: Infra-LXC als Kopie zurückspielen. Prüfung: Die Kopie startet, docker ps zeigt die Dienste.

Task 5.2: Infra-LXC mit Monitoring (ein Stack)

Wo: remote · Planner: „Proxmox: Grafana-Dashboard für den Cluster“, „PVE-Config: Verfügbarkeits-Monitoring und Log-Kontrolle ergänzen“ · Files: Modify deploy/compose/infra/docker-compose.yml, deploy/prometheus/prometheus.yml

  • deploy/compose/infra ohne den Dienst litellm (D4). Router zeigt auf http://192.168.100.29:<LiteLLM-Port>. Image-Tags pinnen (offener Punkt aus IMPLEMENTATION). 12.10.: erledigt, alle Images gepinnt; Port offen (LiteLLM auf appsrv08 nicht im LAN veröffentlicht, vorläufig :4000 in roles/infra-stack/defaults, Task 6.3).
  • LXC infra (vmid 101, Nesting, 4 Kerne, 8 GB, Knoten laut RAM-Budget) mit HA und Replikation (Task 2.2), 12.10.: tofu, Debian 13 auf tank (60 GB), DHCP .188, Docker + Compose 2.26 (Rolle docker-host).
  • Compose-Stack mit KNASTER_DRY_RUN=true. 12.10.: Rolle infra-stack, playbooks/monitoring.yml, idempotent; Geheimnisse nur in /opt/knaster/infra/.env (BETRIEB §7).
  • Prometheus-Ziele: pve-exporter (Token aus 4.1), node-exporter und nvidia_gpu_exporter in den GPU-VMs, Router. 12.10.: GPU-VMs per file_sd (monitoring-targets.yml), Rolle gpu-exporters; alle 5 Knoten und 7 GPUs sichtbar.
  • Grafana: Dashboards für Proxmox, Knoten, GPU (Community-JSON) und knaster. Konto kiosk mit Rolle Viewer. 12.10.: grafana.com 10347, 1860, 14574 und „knaster – Übersicht“; Kiosk-Passwort in /opt/knaster/infra/.env (für 5.3).
  • Alertmanager an den Router (Healer, Dry-Run) und an n8n knaster-notify. Der Workflow wird inaktiv importiert, dann aktiviert. 12.10.: Router erledigt (Test-Alert kommt mit 200 an), n8n-Receiver nur vorbereitet (auskommentiert, Format passt nicht direkt, braucht den Nutzer). Prüfung: Grafana zeigt alle 5 Knoten und alle GPUs. Ein Test-Alert (amtool alert add test) erscheint im Kanal. 12.10.: Knoten/GPUs ja, Test-Alert im Alertmanager und beim Router ja, Kanal (n8n) offen. HA-Probe (Wartungsmodus pve44, zweimal hin und zurück) bestanden, nachdem ein ZFS-Cache-Fehler gefunden und im LXC abgefangen wurde (BETRIEB §7).

Task 5.3: Kiosk auf pve61

Wo: remote, Abnahme vor Ort · Planner: „Proxmox: pve61 (Surface) zeigt das Grafana-Dashboard als Kiosk“

  • Empfehlung: minimaler Kiosk direkt auf dem Host (cage + chromium als eigener Benutzer, systemd-Dienst, Bildschirmschoner aus). Das ist eine bewusste kleine Ausnahme von „Container zuerst“, weil ein Kiosk Bildschirm und Eingabe des Geräts braucht.
  • URL: Grafana-Playlist im Kiosk-Modus mit Konto kiosk. Prüfung: Nach einem Neustart von pve61 zeigt der Bildschirm ohne Eingriff das Dashboard.

Phase 6 – Data Plane

Ersetzt PLAN §8 „1 Data Plane“.

  • (15.10.) 6.0 k3s (D6): Dienst-VM k3s (tofu service_vms, HA + Replikation über Rolle pve-host), Rollen k3s-server, k3s-agent, k3s-apps, Manifeste deploy/k8s/, playbooks/k3s.yml. Fünf Knoten Ready, nvidia.com/gpu 2/2/2/1, Portainer-Agent läuft (NodePort 30778 von Laptop erreichbar). Umzugstest: NEX-Sprachdienste als Deployments (playbooks/nex-speech-k3s.yml), Rundlauf TTS→STT korrekt. BETRIEB §14.
    • (15.10.) Portainer CE 2.45.1 im Cluster (Dienst-VM k3s) mit der Datenbank von appsrv08: Rollback BE→CE geprüft, API-Schlüssel gültig (playbooks/portainer-k3s.yml, BETRIEB §14). Grund: Business-Lizenz zählt die fünf k3s-Knoten (Angebot ~1000 €), CE ist frei. Offen (Nutzer, Admin-Login nötig): Umgebung „appsrv08“ (Agent 192.168.100.29:9001, läuft) anlegen und godel-deployer freigeben; dann nginx portainer.mygodel.de auf :30779 umstellen, EE stoppen, nex-Admin-Endpoint/URL anpassen (mit SearXNG-Variable im nex-Repo).
    • (15.10.) Zuteilung angehoben, weil der Cluster nur die Hälfte der Hosts zeigte: GPU-VMs 4→8 vCPU, 12→20 GB; infra 8→4 GB; ZFS-ARC 4→2 GB (neu in Rolle pve-host, cluster.zfs_arc_max_mb); tofu reboot_after_update=false, VMs einzeln per qm reboot (je ~30 s bis Ready). k3s: 34 vCPU, 83 GB. Nutzer-Idee pve61 als Cache: geht nicht, ARC ist Host-lokal; pve61 (8 GB, kein tank) bleibt Quorum/Kiosk, könnte später CPU-Agent werden.
    • (15.10.) Umzug 3: RustDesk-Server (Stack rustdesk auf appsrv08) als Deployment + Service LoadBalancer in k3s (playbooks/rustdesk-k3s.yml), gleiches Schlüsselpaar, Ports auf allen Knoten erreichbar. Clients zeigen weiter auf .29; Umstellung erst mit fester Adresse/DNS-Name (Nutzer), dann Installer-Name im Stack rustdesk-updater und Stack rustdesk auf appsrv08 abschalten.
    • (15.10.) Umzugstest 2 aus Portainer-Umgebung appsrv08: SearXNG (nex-searxng) als Deployment + NodePort 30880 in k3s, Suche liefert Treffer. Cutover: Nutzer hat 15.10. Weg 2 gewählt (SEARXNG_URL im nex-Admin als Stack-Variable konfigurierbar machen, nex-Repo), Rollout nach DHCP-Reservierung der k3s-VM.
    • (19.10.) Agenten im Cluster (nex-Spec 2026-10-19 D256–D267): Namespace nex mit Brücke zu appsrv08 (Services ohne Selector: router 4100, know 14200, access 4300, grp-mcp-intern 8790), ServiceAccount nex-admin (Role nur Namespace, Token auf ops), Playbook playbooks/nex-k3s.yml; nex-admin 0.2.1 auf appsrv08 legt neue Agenten als Deployment/PVC/Secret/NodePort-Service an, Umzug per UI/API, Traefik auf appsrv08 leitet Port-Adressen an NodePort +20000. Offen: Pull-Secret gitea-registry (Gitea-Token read:package in /root/.config/knaster/gitea-registry.env, dann Playbook), Umzugsprobe nextest3, feste Adresse der k3s-VM (NEX_K3S_HOST).
    • Offen: Umgebung in Portainer (appsrv08) anlegen (Nutzer, 15.10. laut Nutzer erledigt), DHCP-Reservierung für VM 110 (bc:24:11:a5:d5:52), llama.cpp (6.1) direkt als k3s-Manifeste statt Compose, Monitoring der Pods (Task 6.5), Exporter-Stacks umziehen, Docker danach aus den VMs entfernen.
  • 6.1 GPU-Rollen: ab 15.10. als k3s-Manifeste (D6) statt Compose: deploy/compose/gpu-llamacpp in den GPU-VMs nach der Zuordnung aus Task 3.3, also Embedding und Rerank redundant auf zwei Knoten, Chat für verifier und signature. Prüfung: Canary-Checks grün (knaster Canary-Prober).
  • 6.2 STT und TTS für NEX – Auftrag vom 12.10. mit Abgleich: docs/auftraege/2026-10-12-sprachmodelle-nex.md (Erkennung whisper.cpp auf einer M4000, naheliegend gpu-pve52; Ausgabe Piper auf CPU, Port 8179; Abnahme und Rückmeldeformat dort). Läuft nach Task 3.2, gern als Subagent. Blockiert für die Abnahme: feste IP (D5). Bisheriger Text (nex-STT-Plan Tasks 2–4): whisper-server als zusätzlicher Dienst in der GPU-VM des in Task 3.3 gewählten Knotens. Neuer Slot stt-de im Katalog. Port 8178 nur von 192.168.100.29 (Firewall der VM bzw. des Gasts). Prüfung: Von appsrv08 liefert curl -F file=@probe.wav http://<IP>:8178/v1/audio/transcriptions deutschen Text, von einem anderen Rechner wird der Zugriff abgelehnt.
    • (12.10.) Umgesetzt in gpu-pve52: nex-stt (whisper.cpp v1.9.4, CUDA 12.6, sm_52/61, large-v3-turbo, Port 8178) und nex-tts (Piper 1.8.0, de_DE-thorsten-high + de_DE-kerstin-low, Port 8179) als deploy/compose/nex-speech, Rolle/Playbook nex-speech. ufw in der VM (8178/8179 nur von .29, SSH aus dem LAN), Proxmox-Firewall bewusst aus.
    • (12.10.) Tests in der VM und von ops (temporäre Regel, danach entfernt): 10 s → 2,94 s, 60 s → 8,63 s (Median), TTS-TTFB 0,64–0,91 s (mp3/pcm/opus), Autostart nach qm reboot 252 geprüft, keine Texte in Logs. Rückmeldung im Auftrag.
    • (19.10.) Feste IP: 192.168.100.174 per DHCP-Reservierung bestätigt (D5, Task 0.2).
    • Offen: Abnahme von appsrv08 durch das NEX-Team, Slot stt-de (Core kennt kein kind: stt), tts-de später nach infra.
  • 6.3 Lokale Slots in LiteLLM (D4): embed-default, rerank-default, verifier-small und signature-extractor als Modelle im LiteLLM auf appsrv08 eintragen (IP-Literale). Prüfung: curl http://192.168.100.29:<port>/v1/models listet die Slots, ein Aufruf je Slot antwortet.
  • 6.4 Ada-Worker (D3) · Planner: „LLM-Worker: direkte Inferenz-Schnittstelle für LiteLLM (zusätzlich zum Job-Poll), Tunnel, Registry, Fallback-Kette“
    • Offene Schritte der Worker-Registry v2 im Repo mygodel/nex abschließen.
    • Gefilterte Ports auf GODE-PC-05/06 freigeben (nex-STT-Plan, Anhang A).
    • Im knaster-Router engine: worker-registry umsetzen: GET /webhook/llm-worker-list lesen und einen Worker wählen, der online ist; sonst Eskalation auf tier0.
    • Tests in core/tests/test_router.py:
      • test_worker_registry_slot_uses_online_worker
      • test_worker_registry_slot_falls_back_to_tier0_when_list_empty
      • test_worker_registry_slot_falls_back_when_list_unreachable
    • Prüfung: make test PASS. Live tagsüber geht eine tier1-Anfrage an tier0, nachts an GODE-PC-05.
  • 6.5 Pod-Monitoring (k3s in Grafana) · Planner: „Proxmox: Grafana-Dashboard für den Cluster“ · Files: Create deploy/k8s/monitoring/, platform/proxmox/ansible/playbooks/monitoring-k3s.yml, deploy/grafana/dashboards/k3s-pods.json; Modify deploy/prometheus/prometheus.yml, deploy/prometheus/alerts.yml, config/healer-rules.yaml, platform/proxmox/scripts/monitoring-targets.py, Rolle infra-stack (Token, Ziele), deploy/compose/infra/docker-compose.yml, core/tests/test_artifacts.py, BETRIEB §7/§14 Ausgangslage 19.10.: Grafana 12.4 und Prometheus laufen auf infra mit Dashboards für Proxmox, Knoten, GPU und knaster; für k3s gibt es kein Ziel. Zustand und Speicher der Pods zeigt bisher nur nex-admin über die Metrics-API (metrics-server, nur Momentwerte, keine Grafana-Datenquelle).
    • (19.10.) kube-state-metrics v2.19.1 im Namespace kube-system (deploy/k8s/monitoring/kube-state-metrics.yaml, nur die nötigen Ressourcen), Service NodePort 30808.
    • (19.10.) ServiceAccount prometheus-infra, ClusterRole nur get nodes/metrics, langlebiges Token-Secret. Token und CA legt playbooks/monitoring-k3s.yml auf ops ab (/root/.config/knaster/k3s-prometheus.token, k3s-ca.crt), die Rolle infra-stack kopiert sie nach /opt/knaster/infra/secrets/k3s/ (nur dieser Ordner in Prometheus eingehängt). Die kubelet-Zertifikate sind von k3s-server-ca signiert und tragen die Knoten-IP (geprüft auf gpu-pve52), daher TLS ohne insecure_skip_verify.
    • (19.10.) Ziele per file_sd aus kubectl get nodes (statt tofu, so ist die k3s-VM dabei): monitoring-targets.py --k3s-nodes schreibt kubelet.json (alle Knoten, 10250) und kube-state-metrics.json (ein Ziel, NodePort auf der Dienst-VM k3s, sonst erster bereiter Knoten; instance fest, damit ein Wechsel keine neuen Reihen erzeugt).
    • (19.10.) Prometheus-Jobs kubelet, cadvisor, kube-state-metrics. cAdvisor behält nur CPU, Arbeitssatz, RSS, OOM und Netz und verwirft Reihen ohne Pod sowie Pod-Summen/Pause-Container.
    • Speicher von Prometheus eine Woche beobachten (infra hat 4 GB).
    • ufw: Die Rolle k3s-agent erlaubt 10250 und 30000–32767 schon seit 15.10. aus dem LAN, keine Änderung nötig.
    • (19.10.) Dashboard „k3s – Pods“ (deploy/grafana/dashboards/k3s-pods.json, eigenes statt Community, passend zu den behaltenen Metriken): Namespace-Auswahl mit Vorgabe nex, Kennzahlen, Speicher/CPU je Pod, Tabelle mit Knoten, Neustarts, Speicher gegen Request/Limit, Pods und Speicher je Knoten, PVC-Belegung.
    • Dashboard in die Kiosk-Playlist (5.3) aufnehmen, sobald es die Playlist gibt.
    • (19.10.) Alerts K3sNodeNotReady, K3sPodCrashLooping (> 10 min), K3sDeploymentUnavailable (> 15 min), K3sContainerMemoryNearLimit (> 90 %, 10 min); Healer-Regeln nur notify.
    • Prüfung: make test PASS (Struktur von prometheus.yml/alerts.yml). Auf infra zeigt api/v1/targets die Jobs kubelet, cadvisor, kube-state-metrics mit allen fünf Knoten up. Grafana zeigt für nex dieselben Pods und ungefähr denselben Speicher wie kubectl top pods -n nex. Ein absichtlich kaputtes Test-Deployment löst den CrashLoop-Alert aus.
    • (19.10.) Prüfung bestanden: alle 11 k3s-Ziele up; Speicher je Pod in nex gleich kubectl top (344/354/122 MiB); ~2000 neue Reihen; Dashboard im Ordner knaster. Test-Deployment knaster-crashtest (busybox, exit 1): K3sDeploymentUnavailable feuert nach 15 min; K3sPodCrashLooping flackerte zwischen den Neustarts und blieb pending, seit max_over_time(…[5m]) feuert er nach ~14 min. Test-Deployment gelöscht.

Phase 7 – Kernpfad

Ersetzt PLAN §8 „2 Kernpfad“.

  • n8n-Workflows knaster-request, knaster-jobs und knaster-service-routine inaktiv importieren und Credentials setzen (n8n/README.md).
  • Ende-zu-Ende: Eine Anfrage läuft über Router, Verifier und Eskalation über den PSE-LiteLLM. Die Dry-Run-Woche beginnt.
  • Nex-STT-Plan Tasks 5–8: Hermes-Overlay stt.openai.base_url mit IP-Literal, Rückfall auf CPU, Abnahme.
  • Offen und hier zu entscheiden: Langfuse (PLAN §2.4) steht nicht im Infra-Compose.

Phase 8 – GRP als Testdienst

Planner: „Proxmox: GRP als Testservice in einen LXC-Container umziehen“ · Voraussetzung: PBS (Task 5.1)

  • LXC grp-test (Pool test, Docker) mit einer Kopie der GRP-Daten von appsrv08. Die Produktion bleibt unangetastet. Feste IP aus D5, Zugriff nur intern. Prüfung: Die Testinstanz läuft, das Backup des Containers ist im PBS sichtbar.

Phase 9 – knaster-Ausbau (eigene Pläne folgen)

Die Software-Phasen aus PLAN §8 bleiben inhaltlich gültig und bekommen jeweils einen eigenen Plan:

  • „3 Skills“: Hermes als Skill-Autor
  • „4 Robustheit“: Healer live, Aktionen einzeln freischalten
  • „5 Lifecycle“: QLoRA-Training. Voraussetzung ist die Entscheidung über WSL2 bzw. vLLM auf den Ada-Rechnern nachts (D3, Folgeentscheidung).
  • „6 Portabilität“

Am Ende von Phase 9 wird das Betriebshandbuch abgeschlossen („PVE-Config: Betriebshandbuch und Testvorgehen anlegen“). Das geschieht als Erweiterung von docs/BETRIEB.md, nicht als neues Dokument.


Parallelspur NEX (ohne Cluster-Bezug, nach Dringlichkeit)

# Planner-Aufgabe Warum jetzt
P1 LiteLLM Swarm: PSE-Fix ausrollen (Klartext-Abfluss) Datenschutz-Leck auf dem Swarm (D4 nutzt den schon reparierten LiteLLM auf appsrv08)
P2 NEX: Startpasswort astreit ändern Passwort lag lesbar in S:\IT\Nex
P3 NEX aufräumen: Testinstanz, Schlüsseldateien ca.key liegt ungeschützt
P4 NEX: Gitea/Portainer-Schritte für Port je Agent und Registry (Teil 1 der Checkliste) blockiert nex-admin
P5 nex-admin 1: eigene Tokens anlegen und Stack nex deployen → nex-admin 2 → nex-admin 3 → nex-admin 4 in dieser Reihenfolge
P6 NEX - Admin Mail in n8n anlegen und Wächter-Mail testen nach nex-admin 1
P7 Arbeitsplatz-Setup-Skript am eigenen PC testen unabhängig
P8 NEX Websuche: eigenes SearXNG im Stack nex unabhängig

Zuordnung Epic 7 → Plan (Duplikate zusammengeführt)

Planner-Aufgabe (exakter Titel) Im Plan Planner-Aktion nach Freigabe
Proxmox: pve48 root-Passwort klären und SSH-Schlüssel nachtragen Task 0.1 bleibt
PVE-Config: Netzwerk prüfen – Bridge, VLAN-Fähigkeit und NIC-Kompatibilität Task 0.2 (D5), VLAN später 13.10. geprüft (BETRIEB §12: e1000e/r8152, 1 GBit, kein VLAN-aware, keine Hänger), erledigt; Reservierungen bleiben in 0.2
Proxmox: Konfiguration aller Knoten durcharbeiten aufgeteilt auf 0.1, 1.1–1.3 schließen mit Verweis auf diesen Plan
PVE-Config: Erst-Update aller Knoten (apt full-upgrade) Task 1.1 bleibt
Proxmox: Speicher aller Knoten richtig konfigurieren D1, Task 1.2 bleibt
PVE-Config: RAM-Planung je Knoten (Host-Reserve, ZFS-ARC, KSM, Swap) Task 1.2 (ARC), Task 3.2 (VM-RAM) zusammengeführt in „Speicher …“, schließen
GPU-Knoten 3: Cluster mit QDevice (Container auf appsrv08), NVIDIA-Treiber, GPU-Container Tasks 2.1, 2.2, 3.1, 3.2 bleibt (Titel unverändert), Beschreibung: kein QDevice, GPU als VM
GPU-Knoten 4: Geschwindigkeitstests (Gate) auf M4000 und P2000 Task 3.3 (mit knaster-Benchmark-Tag und STT-Gate) bleibt, Beschreibung ergänzen
PVE-Config: Persönlicher Admin-Benutzer, Rollen und API-Token anlegen 4.1 bleibt
PVE-Config: Zwei-Faktor-Authentifizierung für Admin-Konten aktivieren 4.2 bleibt
PVE-Config: Benachrichtigungen (Notification Center) einrichten 4.3 bleibt
PVE-Config: Firewall auf Datacenter- und Knotenebene einrichten 4.4 bleibt
PVE-Config: Ressourcenpools und Tags festlegen 4.5 bleibt
PVE-Config: Standard für neue LXC-Container festlegen 4.5 zusammengeführt in „Ressourcenpools …“, schließen
PVE-Config: Web-GUI-Zertifikat festlegen (niedrige Priorität) 4.6 bleibt
PVE-Config: Update- und Neustart-Routine festlegen (rollierend, Knoten für Knoten) 4.7 bleibt
Proxmox: Backup-System überlegen Task 5.1 bleibt
Proxmox: Grafana-Dashboard für den Cluster Task 5.2 (knaster-Stack statt InfluxDB) bleibt, Beschreibung ändern
PVE-Config: Verfügbarkeits-Monitoring und Log-Kontrolle ergänzen Task 5.2 (Alertmanager, Healer) zusammengeführt in „Grafana-Dashboard …“, schließen
Proxmox: pve61 (Surface) zeigt das Grafana-Dashboard als Kiosk Tasks 1.3, 5.3 bleibt
LLM-Worker: direkte Inferenz-Schnittstelle für LiteLLM (zusätzlich zum Job-Poll), Tunnel, Registry, Fallback-Kette Task 6.4 bleibt, Beschreibung: Registry v2 + knaster-Brücke
Proxmox: GRP als Testservice in einen LXC-Container umziehen Phase 8 bleibt
PVE-Config: Betriebshandbuch und Testvorgehen anlegen Phase 9 (docs/BETRIEB.md) 13.10. erledigt: §8–§13 und scripts/healthcheck.sh
P1–P8 (NEX-Aufgaben) Parallelspur bleiben

Neu angelegt (nur Schritte ohne bestehende Aufgabe, keine Duplikate):

  • „knaster: Entscheidungen D1–D5 bestätigen“ (0.3)
  • „knaster: Site-Dateien und ADRs an echte Hardware anpassen“ (0.4)
  • „knaster: GPU-Dienste (llama.cpp) in den GPU-VMs“ (6.1)
  • „knaster: STT-Dienst whisper-server im Haus“ (6.2)
  • „knaster: lokale Slots im LiteLLM auf appsrv08“ (6.3)
  • „knaster: Kernpfad Ende-zu-Ende im Dry-Run“ (Phase 7)

Cluster und GPU-VMs laufen über „GPU-Knoten 3“, der Infra-LXC über „Proxmox: Grafana-Dashboard für den Cluster“.

Zuordnung der knaster-Roadmap (PLAN §8): 0 Fundament → Phasen 0–5 · 1 Data Plane → Phase 6 · 2 Kernpfad → Phase 7 · 3–6 → Phase 9.

Zuordnung nex-STT-Plan: Task 0 erledigt · Task 1 → 3.3 · Tasks 2–4 → 6.2 · Tasks 5–8 → Phase 7.