Verteilte Systeme • August 2026

Portable VM-Snapshots: Live-Migration von KI-Isolates zwischen Servern 📸

Eine der leistungsstärksten — und am wenigsten diskutierten — Fähigkeiten von KnotenCore v2.12.0 sind portable VM-Snapshots. Über die JSON-RPC-Methode knc_agent_snapshot kann die Laufzeit den vollständigen Ausführungszustand eines beliebigen Live-Isolates einfrieren — Register, Value-Stack, Callstack, heap-allozierter Speicher und ein kryptografischer Ledger-Hash — ihn in ein kompaktes binäres Blob serialisieren und mit Byte-für-Byte-Genauigkeit auf jedem anderen KnotenCore-Knoten im Cluster wiederherstellen. Dieser Beitrag erläutert das Design, das Handshake-Protokoll und das Sicherheitsmodell, das eine unterbrechungsfreie Agentenmigration ermöglicht.

1. Was ein VM-Snapshot enthält

Ein KnotenCore-Isolate ist eine in sich geschlossene Ausführungseinheit: Es besitzt eine Registerdatei, einen Operanden-Stack, einen Call-Frame-Stack, einen Heap-Bereich für komplexe Werte und einen Programmzähler, der auf den kompilierten Bytecode zeigt. Wenn knc_agent_snapshot aufgerufen wird, wird die VM an einem sicheren Yield-Point angehalten — mitten in einer Instruktion wird niemals der Zustand erfasst — und jeder dieser Bereiche wird in einem längen-präfixierten Binärformat der Reihe nach serialisiert. Der Bytecode selbst wird als content-adressierter Hash gespeichert; der empfangende Knoten holt den eigentlichen Bytecode aus dem gemeinsamen Programm-Store des Clusters, wenn er ihn noch nicht lokal gecacht hat.

Das Snapshot-Blob ist bewusst kompakt gehalten. Nur lebende Heap-Zellen, die von der aktuellen Registerdatei und dem Stack erreichbar sind, werden eingeschlossen — tote Werte, die beim letzten GC-Zyklus gesammelt wurden, werden nicht serialisiert. In der Praxis liegt ein in der Mitte einer Berechnung befindliches Isolate, das eine moderat komplexe Agenten-Policy ausführt, je nach Heap-Tiefe zwischen 4 KB und 80 KB — ein Blob, das trivial über einen Standard-JSON-RPC-Response-Body übertragen werden kann.

Das Snapshot-Format ist versioniert. Die ersten vier Bytes kodieren eine Magic-Number und eine Schema-Version, wodurch ein v2.12.0-Knoten stets einen Snapshot mit inkompatibler Schema-Version ablehnt, anstatt schweigend korrumpierten Zustand wiederherzustellen. Diese Vorwärtskompatibilitätsgarantie ist in Rolling-Upgrade-Deployments kritisch, wo Knoten vorübergehend unterschiedliche Minor-Versionen ausführen können.

2. Der knc_agent_handshake & knc_agent_restore Flow

Die Migration folgt einem dreiphasigen Protokoll. In Phase eins sendet der Orchestrator knc_agent_handshake an den Zielknoten und meldet die Isolate-ID, die Schema-Version und den Content-Hash des benötigten Bytecodes. Das Ziel antwortet mit einer Capability-Bestätigung und signalisiert, ob der Bytecode bereits gecacht ist. Falls nicht, überträgt der Orchestrator den Bytecode in einem nachfolgenden knc_program_upload-Aufruf.

In Phase zwei ruft der Orchestrator knc_agent_snapshot auf dem Quellknoten auf, um das binäre Blob und den aktuellen Ledger-Hash zu erhalten. Der Quellknoten suspendiert das Isolate, serialisiert es und gibt die base64-kodierte Nutzlast im JSON-RPC-Ergebnisfeld zurück. Das Isolate bleibt suspendiert — nicht terminiert — bis der Orchestrator die erfolgreiche Wiederherstellung auf dem Ziel bestätigt.

In Phase drei ruft der Orchestrator knc_agent_restore auf dem Zielknoten auf und übergibt das Blob und den erwarteten Ledger-Hash. Das Ziel deserialisiert den Zustand, verifiziert die Hash-Kette und setzt das Isolate genau an der Instruktion fort, an der es suspendiert wurde. Erst nach Erhalt einer Erfolgsbestätigung ruft der Orchestrator knc_agent_terminate auf dem Quellknoten auf. Das Ergebnis ist eine unterbrechungsfreie Migration: Aus Sicht des Agenten hat die Ausführung nie gestoppt.

// Phase 1 — Handshake mit Zielknoten
{"jsonrpc":"2.0","method":"knc_agent_handshake",
 "params":{"isolate_id":"agt-7f3a","schema_version":"2.12.0",
            "bytecode_hash":"sha256:e3b0c44298fc..."},
 "id":1}

// Phase 2 — Snapshot vom Quellknoten
{"jsonrpc":"2.0","method":"knc_agent_snapshot",
 "params":{"isolate_id":"agt-7f3a","suspend":true},
 "id":2}
// → result: { "blob": "<base64>", "ledger_hash": "sha256:a1b2c3..." }

// Phase 3 — Restore auf Zielknoten
{"jsonrpc":"2.0","method":"knc_agent_restore",
 "params":{"isolate_id":"agt-7f3a","blob":"<base64>",
            "expected_ledger_hash":"sha256:a1b2c3..."},
 "id":3}

3. SHA-256-kryptografische Ledger-Kette als Schutz gegen Replay-Angriffe

Jedes KnotenCore-Isolate pflegt einen monoton fortschreitenden Ledger-Hash. Jedes Mal, wenn das Isolate eine zustandsändernde Operation ausführt — eine Variable schreiben, eine native Funktion aufrufen, ein Ergebnis yielden — wird der aktuelle Hash aktualisiert: new_hash = SHA-256(prev_hash || operation_descriptor). Dies bildet eine manipulationsgeschützte Kette, die die vollständige kausale Geschichte der Ausführung des Isolates erfasst.

Der Ledger-Hash erfüllt im Snapshot-Protokoll zwei Zwecke. Erstens fungiert er als Zustands-Fingerabdruck: Quelle und Ziel berechnen den erwarteten Hash unabhängig voneinander, und eine Nichtübereinstimmung lässt knc_agent_restore einen LedgerMismatch-Fehler zurückgeben und verweigert das Wiederbeleben eines manipulierten oder veralteten Blobs. Zweitens schützt er vor Replay-Angriffen — ein Angreifer, der ein gültiges Snapshot-Blob abfängt, kann es nicht später erneut einschleusen, da der Zielknoten erkennt, dass der Ledger-Hash nicht mehr mit dem aktuellen Cluster-Zustand für diese Isolate-ID übereinstimmt.

In sicherheitskritischen Deployments kann der Orchestrator zusätzlich einen clusterweit monoton aufsteigenden Ledger-Epoch-Zähler vorschreiben, der jeden Rollback zu einem früheren Snapshot verhindert — selbst wenn ein Angreifer Zugang zu mehreren historischen Blobs hat. Dies verleiht der Zustandsmigration von KnotenCore die gleichen Replay-Resistenz-Garantien, die typischerweise mit kryptografischen Session-Tokens verbunden werden — direkt auf ausführbaren Agentenzustand angewandt.

4. Praktische Anwendungen: Live-Load-Balancing und Fehlerwiederherstellung

Das Snapshot-Protokoll erschließt zwei Klassen von Cluster-Operationen, die bisher nicht möglich waren: proaktives Load-Balancing und transparente Fehlerwiederherstellung. Beim Load-Balancing kann ein Orchestrator, der den CPU- und Speicherdruck pro Knoten überwacht, heiße Isolates zur Laufzeit auf weniger ausgelastete Knoten migrieren — ohne die laufende Aufgabe des Agenten zu unterbrechen. Das Agentenprogramm sieht keine Diskontinuität; es wacht einfach auf einem anderen physischen Host auf und macht dort weiter, wo es aufgehört hat.

Bei der Fehlerwiederherstellung können Knoten, die ein SIGTERM von einem Container-Orchestrator empfangen, vor dem Herunterfahren Checkpoint-Snapshots für alle laufenden Isolates aussenden. Ein Recovery-Controller überwacht diese Checkpoints und stellt sie innerhalb von Sekunden auf Ersatzknoten wieder her, wodurch effektive RTO-Werte weit unter dem erreicht werden, was traditionelle Prozess-Neustart-Strategien bieten können. Da der Snapshot den vollständigen Heap und Call-Stack umfasst — nicht nur die persistente Ausgabe des Programms — setzt der wiederhergestellte Agent die Berechnung mitten in der Ausführung fort, anstatt von vorne zu beginnen.

In Kombination mit dem in v2.12.0 eingeführten Headless-Build-Profil positionieren portable Snapshots KnotenCore als erstklassige Laufzeit für autonome KI-Workloads, die Infrastrukturturbulenzen — Knotenersatz, Rolling Upgrades und Cloud-Spot-Instance-Evictions — überstehen müssen, ohne die Ausführungskontinuität zu opfern.