# Monitoring **Dokumenten-ID:** GNMON-001-PLAN **Titel:** Host-Monitoring auf dem KI-Server: Systemmetriken und Workload-Dashboards **Stand:** 2026-10-19 **Status:** Finaler Plan nach Betreiberentscheidungen vom 19.10.2026 **Referenzen:** [GNENC-001](../encoding/GNENC-001-PLAN_Architecture.md), [GNENC-002](../encoding/GNENC-002-PLAN_Pipeline.md), [GNAI-005](../../GNAI-005-SEC_Access-Control.md), [GNAI-006](../../proxmox-server/lxc/ct-103-reverse-proxy/GNAI-006-SEC_Reverse-Proxy.md) ## 1. Zweck und Abgrenzung Host-weites Monitoring für `ghostnet-ki`: Systemmetriken (CPU, RAM, Disk, GPU-Util, VRAM) und Dashboards für Workloads. Aktuell angebunden ist die Encoding-Pipeline (GNENC-002); später erweiterbar um LLM-Metriken (GPU-Util unter Inferenz, llama.cpp-Statistik). Der Bereich ist fachlich getrennt vom Encoding-Workload (aus GNENC ausgegliedert, Betreiberentscheidung 19.10.2026), eilt aber Hardware und Host-Basis. ## 2. Architekturprinzip Filesystem-Handover wie in der Encoding-Pipeline: Der Metrics-Collector (host-seitig) schreibt `state/system.json` atomar; Workloads stellen ihre Status-Dateien bereit (Encoding: `state/jobs/*.json`). Das Dashboard liest ausschließlich Dateien (read-only Mounts) und hat weder GPU- noch Schreibzugriff. ## 3. Komponenten | Komponente | Konto | Image | Aufgabe | Betrieb | | --- | --- | --- | --- | --- | | Metrics-Collector | host-seitig (systemd-Service; root oder dedizierter Metrics-Account mit `render`-Gruppe) | — | sampelt alle 10 s CPU, RAM, Disk (Root + NFS-Export), GPU-Util und VRAM (rocm-smi/sysfs, lesend); schreibt `state/system.json` atomar | dauerhaft | | Dashboard | `gn-dashboard` (984) | Dashboard-Image (Eigenbau, gepinnt; Python + Flask) | liest `system.json` + `state/jobs/*.json` (Encoding, read-only Mount); zeigt Ressourcen und Workload-Übersicht | dauerhaft | ## 4. Konto `gn-dashboard` UID/GID 984, subid/subgid ab 624288 (65536 Stück), Home `/var/lib/ghostnet-dashboard`, Config `/etc/ghostnet-dashboard`, Quadlets `/etc/containers/systemd/users/984`, eigener rootless Podman-Store, gesperrt (Passwort `!`, Shell `/usr/sbin/nologin`, Linger aktiv). Mitglied der Gruppe `gn-media` (nur lesender Zugriff auf `state/` und `queue/` der Encoding-Pipeline). Keine GPU-Gruppenmitgliedschaft, keine `/dev/kfd`-/ `/dev/dri`-Weitergabe. ## 5. Metrics-Collector - Sampling alle 10 s; atomares Schreiben (`state/tmp/` + `mv`) nach `/var/lib/ghostnet-pipeline/state/system.json` (Mode `0644`). - Schema: ```json { "ts": "…", "cpu_util_pct": 0.0, "ram_total_bytes": 0, "ram_used_bytes": 0, "disks": [{"mount": "/", "total_bytes": 0, "used_bytes": 0}], "gpu_util_pct": 0.0, "vram_used_bytes": 0, "vram_total_bytes": 0 } ``` - GPU-Metriken werden host-seitig gelesen (rocm-smi oder sysfs); der Dashboard-Container selbst hat keinen GPU-Zugriff. - Ressourcenlimits: MemoryMax 512M, CPUWeight 50. ## 6. Dashboard - **Views:** Ressourcen (CPU, RAM, Disk, GPU-Util, VRAM aus `system.json`); Encoding-Übersicht (aktive Jobs mit Fortschritt, Queue-Tiefe pro Profil, Historie done/failed der letzten 30 Tage, Fehlerfälle mit Ablageort in `output/_failed/`); später LLM-Metriken. - **Technik:** Python/Flask, server-seitig gerendert, ohne JS-Framework. Nur read-only Mounts (`state/`, `queue/`); kein GPU-Zugriff, kein Schreibzugriff. - **Erreichbarkeit:** Ingress über NPM (CT-103) mit TLS, zugriffsgeschützt über Keycloak — analog zu den bestehenden Admin-Pfaden (GNAI-005/GNAI-006). - **Image:** schlankes Python-Base-Image + Flask, Eigenbau unter `llm-server/monitoring/images/`, Digest gepinnt. ## 7. Anbindung Encoding-Pipeline - Der Encoding-Worker schreibt `state/jobs/*.json` (Schema in GNENC-002 Abschnitt 7); das Dashboard liest read-only. - `state/` ist `gn-encoding:gn-media` mit Mode `2750`, damit `gn-dashboard` lesen kann; Schreibzugriffe bleiben beim Worker (`state/jobs/`, `state/tmp/` `0750`) und beim Collector (`state/system.json`). - Das Dashboard hat keine Schreibzugriffe in die Pipeline. ## 8. Repository-Grenzen ```text llm-server/monitoring/ ├── ansible/ # Playbook + Rolle (Collector-Service, Dashboard-Quadlet, Konto-Zustand) ├── images/ # Dashboard-Containerfile └── scripts/ # Metrics-Collector ``` Eigene Programme liegen versioniert unter `llm-server/monitoring/scripts/`; das Dashboard-Image wird gebaut und per Digest gepinnt (analog GNENC-001 Abschnitt 5). ## 9. Offene Punkte 1. NPM-Hostname und Keycloak-Client für das Dashboard (Umsetzung mit GNAI-005/GNAI-006). 2. Collector-Identität: root oder dedizierter Metrics-Account mit `render`-Gruppe — finale Festlegung bei der Umsetzung. 3. Erweiterung um LLM-Metriken (später, eigenes Thema im AI-Bereich).