Zum Inhalt springen
labkompass

Logbuch#homeos#audit#monitoring#docker

„Targets up“ ist keine Gesundheitsaussage

Von Niclas Hennrich · veröffentlicht · geschehen am


ProblemBehoben

Etwas ist ausgefallen oder kaputtgegangen. Gehört zum Vorhaben HomeOS — Control Center mit drei Säulen.

ENV-Variablen, die den Container nie erreichten
19
API-Endpunkte ohne UI-Nutzung (von 195)
59
Tests danach (vorher 1223)
1272

HomeOS ist mein selbst gebautes Control Center fürs Homelab — aus dem Infrastruktur-NOC erwachsen, mit drei Säulen: Infrastruktur, Haus und Family. In fünf Tagen hatte ich fünf große Läufe darüber gejagt: Haus-Modul, Family-Säule, System-Audit, Meal Planning, Security-Audit. 1223 Tests grün, alles ausgerollt. Genau das machte mich misstrauisch.

Was ich wollte: nicht die TODO-Dateien lesen, sondern das reale System auf offene Schleifen absuchen. Eine API ohne Oberfläche. Daten, die geholt, aber nie gezeigt werden. Ein Flag ohne Konsumenten. Doku, die etwas anderes behauptet als der Code. Bei dem Tempo entstehen solche Lücken, und kein Einzel-Audit sieht sie — Parität und Abdeckung sind Querschnittsfragen, die kein Feature-Audit stellt.

Wie: fünf parallele, rein lesende Audits — Backend-Inventar, Frontend-Inventar, API gegen UI, Git-Historie gegen Doku, Infrastruktur-Abdeckung — plus eine Live-Baseline auf optimus. Gezählt, nicht geschätzt: 195 API-Endpunkte, 100 davon schreibend, 59 ohne jede Nutzung in der Oberfläche, 15 tote Client-Wrapper, zwei komplett tote Tabellen. Null kaputte Pfade, null TODO im Produktionscode. Klingt sauber. Die drei interessanten Funde standen in keinem Backlog.

Fund eins: eine Fehlerklasse, die ich für tot hielt. Beide Compose-Dateien zählten die Umgebungsvariablen einzeln auf. 19 Variablen, die in der Beispiel-Env sauber dokumentiert waren — der komplette Retention-Block, alle Agenten-Einstellungen, mehr — erreichten den Container nie. Still galten die Code-Defaults. Das ist exakt der Mechanismus, der die Prod eine Zeit lang auf dem Mock-Adapter laufen ließ. Diesen einen Fall hatte ich behoben. Den Mechanismus nicht.

Fund zwei: das Selbst-Monitoring war seit seiner Einführung rot. Die HTTP-Probes auf die eigene UI und API liefen gegen den Host-Port — aus dem eigenen Docker-Netz heraus ist das ein Hairpin, und der läuft in den Timeout. Die 48-Stunden-Historie zeigt durchgehend probe_success 0. Aufgefallen ist es nie, weil die Übersicht „30/30 Targets up" meldete, und das sieht aus wie Gesundheit. Ist es aber nicht: Das Target ist der Exporter, der die Probe ausführt. Der war erreichbar. Die Probe darin war es nicht. Target up ≠ Probe erfolgreich.

Fund drei: eine ehrliche Probe findet mehr als geplant. Ein neuer TCP-Check auf mein Tor-Relay meldete sofort ehrlich 0 — und beantwortete damit nicht die Frage „Relay erreichbar?", sondern zeigte, dass der Check von innen etwas anderes misst als ein Client von außen. Von dort läuft das Relay unbeeindruckt weiter, der Heartbeat zählte 94 518 eingehende Verbindungen. Eine Probe, die 0 meldet, ist trotzdem wertvoller als eine, die nie lief: Sie stellt die richtige Frage, auch wenn die Antwort erst einmal „so nicht" lautet.

Was ich in einem Zug umgesetzt habe: rund 34 Aufgaben. env_file: in beiden Compose-Dateien plus ein Paritäts-Check als Wächter — der beim ersten Lauf prompt eine frische, undokumentierte Einstellung fand. Ein Supervisor für alle Hintergrund-Loops: Absturz heißt jetzt Log und Neustart mit Backoff; vorher starb ein Poller still, wenn Postgres beim Start noch nicht bereit war. Die Status-Engine schreibt Statuswechsel als Ereignis — die Tabelle hatte bis dahin genau einen Produzenten, den Seed. Das Backup-Skript meldet seinen Erfolgs-Zeitstempel an VictoriaMetrics, die Übersicht alarmiert ab 48 Stunden Stille. Drei UI-Sackgassen geschlossen, je eine komplette API ohne Oberfläche. Und eine Korrekturnotiz an einer älteren Deployment-Validierung, die nachweislich Mock-Daten für echt erklärt hatte.

Danach: 32/32 Targets up — und das Selbst-Monitoring zum ersten Mal wirklich grün. Tests von 1223 auf 1272.

Was ich mitnehme:

  • „Targets up" ist keine Gesundheitsaussage. Ein Scrape-Target kann monatelang up sein, während die Probe darin durchgehend 0 meldet. Wer Probes einführt, muss die erste erfolgreiche Messung sehen, nicht den ersten erfolgreichen Scrape.
  • Eine Fehlerklasse ist erst tot, wenn ein Wächter sie totprüft. Den Einzelfall zu beheben reicht nicht, solange der Mechanismus weiterlebt. Der Paritäts-Check fing die nächste Instanz noch am selben Tag.
  • Backlog-Status verrotten an Meilenstein-Grenzen. Vier erledigte Aufgaben standen auf TODO — alle als letzte Zeilen vor einer Meilenstein-Überschrift. Ein erledigter Task, der von einem offenen abhängt, ist maschinell findbar.
  • Getrennte Audits sehen getrennte Dinge. Fünf spezialisierte Perspektiven plus Live-Baseline fanden an einem Tag, was fünf thematische Läufe liegen ließen.