Deployments
TL;DR
- Ein deployment ist die Laufzeit-Materialisierung eines backend — der typisierte Graph, der als Container auf einem runtime läuft, hinter den endpoint-URLs, die Traffic bedienen, mit dem operativen Zustand, den das Team beobachtet.
- Ein deployment ist 1:1 mit einem backend. Jedes backend hat höchstens ein lebendes deployment; denselben Workflow in zwei Umgebungen auszuführen bedeutet, zuerst das backend zu forken und jeden Fork unabhängig zu deployen. Genau diese Einschränkung macht "was gerade in Produktion ist" eindeutig.
- endpoint-URLs sind eine backend-Eigenschaft, keine deployment-Eigenschaft. Das backend veröffentlicht sie, sobald es Aliase deklariert; das deployment ist der lebende Prozess, der diese URLs bedienen lässt. Baust du das deployment ab, bleiben die URLs bestehen, antworten aber mit 404.
- Das deployment besitzt das lebende runtime; es besitzt weder die Graph-Definition (die liegt im backend) noch die UI (die liegt in der Application). Das runtime kann abgebaut, ersetzt oder migriert werden, ohne eine der anderen Schichten zu berühren.
- "Gesund" bedeutet runtime-Bereitschaft, nicht Verhaltenskorrektheit. Ein
running-deployment bestätigt, dass die Container hochgefahren sind; dass repräsentative Eingaben die erwartete Ausgabe erzeugen, ist das, was bestätigt, dass die solution funktioniert.
Was ein deployment tatsächlich ist
Ein deployment ist die Laufzeit-Materialisierung eines backend. Das Operationslog auf dem backend ist die Eingabe; die auf einem runtime laufenden Container sind die Ausgabe. Das backend ist eine typisierte Graph-Definition, die im Workspace liegt; das deployment ist eine Materialisierung dieses Graphen auf realer Rechenleistung, mit einem Lebenszyklus, der in Minuten bis Wochen statt in Monaten gemessen wird.
Die Trennung zwischen Graph und runtime ist beabsichtigt. Das backend bleibt die inspizierbare Definition, und das deployment ist das wegwerfbare runtime — auf Wunsch abgebaut, nach runtime-Wartung neu gestartet, bei einem Versionssprung komplett ersetzt, auf ein anderes runtime migriert, ohne den Graphen neu zu schreiben. Eine backend-Änderung riskiert daher nicht, ein laufendes System lahmzulegen, ein Redeploy ist nicht mit dem Graph-Editing verwoben, und ein Umgebungsunterschied ist ein separates backend statt dupliziertem Graph-Zustand.
Die Einheit auf der runtime-Seite ist der Container, nicht der Graph. Jeder vertex im deployten backend wird zu einem Komponenten-Container; jede Kante wird zu Plattform-Transport zwischen ihnen. Ob der vertex ein Python-Modellserver, ein C++-Stream-Prozessor oder eine transformation-Primitive ist, ändert diese Form nicht — es ändert nur, was darin läuft. Ein deployment zu betreiben sieht aus wie der Betrieb jeder anderen containerisierten Last, sodass bestehende Container-Debugging-Instinkte direkt anwendbar sind.
Mentales Modell — ein backend, ein deployment
┌────────────────────┐ owns endpoint ┌──────────────────┐
│ Backend prod-bid │── aliases ──▶ │ Deployment │
└─────────┬──────────┘ │ Runtime X · prod │
│ fork └──────────────────┘
├─────────────────────────┐
▼ ▼
┌────────────────────┐ ┌────────────────────┐
│ Backend stg-bid │ │ Backend dbg-bid │
└─────────┬──────────┘ └──────────┬─────────┘
│ owns aliases │ owns aliases
▼ ▼
┌────────────────────┐ ┌────────────────────┐
│ Deployment │ │ Deployment │
│ Runtime Y · stg │ │ Runtime Z · debug │
└────────────────────┘ └────────────────────┘
Das backend ist die typisierte Graph-Definition; das deployment ist die lebende Materialisierung genau dieses backend auf einem bestimmten runtime. Um "denselben Graphen" anderswo aufzustellen, forke das backend in ein Geschwister-Objekt und deploye den Fork. Die Forks teilen einen Vorfahren und einen Ausgangsgraphen; ab dem Fork-Punkt sind sie unabhängige Objekte mit eigenen Operationshistorien und eigenen deployments.
Jede deployment-Zeile trägt ihre ID, ihren Status, das runtime, auf dem sie gelandet ist, das backend, das sie pinnt, wie viele Container sie besitzt, einen Ablaufzeitstempel und ein Debug-Flag. Die IDs sind das, was jeder deployment-bezogene Befehl entgegennimmt — deployment containers, backend undeploy --deployment und so weiter.
Warum die 1:1-Einschränkung wichtig ist
Verwende diese Rahmung immer dann, wenn jemand vorschlägt, "lass uns dasselbe backend zweimal deployen".
Ein backend mit zwei gleichzeitigen deployments hätte keine eindeutige Antwort auf "welches ist die Wahrheit?" — das Operationslog auf dem backend würde von mindestens einem der beiden runtimes abweichen, Observability-Tooling müsste runtime-Zustand gegen Graph-Zustand pro deployment sortieren, und die Frage "was ist in Produktion" bräuchte stets eine Einschränkung.
Das Fork-dann-deploy-Muster hält jedes deployment mit einem backend gepaart, dessen Zustand exakt der ausgeführte Zustand ist. Staging ist ein anderes backend; Produktion ist ein anderes backend; eine Debug-Kopie des Vorfalls letzter Woche ist ein anderes backend. Jedes hat sein eigenes Operationslog, seine eigenen forward-URLs, seinen eigenen Audit-Trail. Der Preis ist, Geschwister-backends explizit zu erstellen; das Ergebnis ist, dass das runtime-Modell stets widerspiegelt, welcher Code wo läuft.
Die 1:1-Verknüpfung ist auch das, was "redeploy" zu einer sinnvollen Operation macht. Es gibt ein deployment pro backend; ein Redeploy ersetzt die Container dieses einen deployment durch frische, die den aktuellen backend-Zustand widerspiegeln. Die Forwarding-URLs (an backend + vertex + endpoint gebunden, nicht an das deployment) überleben den Austausch, sodass Aufrufer eine kurze Lücke statt einer URL-Rotation sehen.
Lebenszyklus
deploy ─▶ deploying ─▶ running ─┬─▶ tearing_down ─▶ (gone)
└─▶ failed
Ein deployment durchläuft einen kleinen Lebenszyklus. Deploying bedeutet, die Zeile existiert und die Plattform fährt Container hoch; die endpoint-URLs des backend lösen bereits auf, antworten aber mit 404, bis Container lauschen. Running bedeutet, jeder Container ist oben und die URLs bedienen Traffic — der einzige Zustand, in dem das deployment "live" ist in dem Sinne, den Aufrufer erwarten. Tearing down bedeutet, ein explizites undeploy, ein Commit-oder-Rollback eines besitzenden lease oder ein Ablauf hat das runtime zurückgefordert; endpoints fallen auf 404 zurück. Failed ist der terminale Zustand, in dem ein Container sein Crashloop-Budget aufgebraucht hat, der Transport nicht aufgebaut werden konnte oder eine Startvorbedingung nicht erfüllt war; endpoints bleiben auf 404, bis das Team eingreift.
Ein deploy kann auch abgelehnt werden, bevor irgendein Container startet: Wenn das einzige verfügbare runtime voll ist oder seine runtime-Klasse nicht mit dem übereinstimmt, was der Graph benötigt, lehnt die Plattform das deploy vorab ab, statt ein partielles runtime zu landen. Das ist beabsichtigt — ein deploy, das seine Platzierungsbedingungen nicht erfüllen kann, schlägt schnell fehl, statt Container zu erzeugen, die nicht laufen können.
Alles außer running ist aus Sicht eines Aufrufers "nicht bereit". Die Forwarding-URLs mögen durchgehend existieren, aber der Vertrag besagt, dass echter Traffic erst eintreffen sollte, wenn das deployment running ist. Der wait-Schritt des Flows "Test mit einem live backend" gated "Beginne, Fixtures zu senden" an diesem Übergang.
endpoint-URLs gehören dem backend
Verwende diese Rahmung immer dann, wenn die URL eines Aufrufers ein Redeploy überleben muss.
Das Forwarding-URL-Muster bindet Tokens an (backend, vertex, endpoint) — nicht an (deployment, vertex, endpoint). Genau diese Bindungsform ist der Grund, warum Aufrufer URLs nicht jedes Mal neu abrufen, wenn das deployment wechselt. Baue das deployment ab, stelle ein neues gegen dasselbe backend auf, und dieselbe URL bedient denselben endpoint. Das deployment ist ersetzbares runtime; die URL ist Teil des öffentlichen Vertrags des backend.
Die Kehrseite ist, dass endpoint-URLs existieren, ob ein deployment gerade live ist oder nicht. Das backend kann seine Aliase in dem Moment veröffentlichen, in dem sie deklariert werden; die URLs sind routbar; sie antworten mit 404, solange kein deployment running dahinter steht. Das lässt Aufrufer mit URLs konfigurieren, bevor das deployment existiert, und macht die Lücke zwischen "deployment abgebaut" und "neues deployment oben" zu einem kurzen 404 statt zu einem URL-Rotationsereignis.
Siehe Solutions für das Alias-Modell und Deploy und Monitoring für den Forwarding-Token-Vertrag im Detail.
Was sich an einem live backend ändern kann
Verwende diese Rahmung immer dann, wenn du dich fragst, ob eine backend-Änderung ein Redeploy benötigt.
Ein deploytes backend akzeptiert eine eng umrissene Menge von In-Place-Änderungen: Parameterwerte auf Slots, die in ihrer Komponente als mutable: true deklariert sind, Dateiwerte auf Slots, die als mutable: true deklariert sind, und ähnliche runtime-sichere Werte, für die sich der Komponentenautor entschieden hat. Die Plattform pusht den neuen Wert in den laufenden Container und die Komponente nimmt ihn über ihren subscribe-config-Hook beim nächsten Aufruf auf. Kein Redeploy; kein Container-Neustart.
Topologie-Änderungen sind anders. Einen vertex hinzufügen, einen vertex entfernen, ein Komponenten-Release tauschen, eine Kante ändern, einen endpoint-Alias ändern, eine andere Datei an einen nicht-mutable-Slot binden — all das wird abgelehnt, solange ein deployment live ist. Das deployment ist die Materialisierung genau dieses Graphen, mit dem Operationslog als Eingabe; den Graphen zu ändern, würde die Materialisierung mit dem Operationslog in Widerspruch bringen und die laufenden Container nicht mehr mit dem aufgezeichneten backend-Zustand synchron halten. Die Plattform lehnt die Änderung stattdessen ab.
Für eine Topologie-Änderung an einem backend, das bereits ein live deployment hat, lautet der Workflow: das backend forken, den Fork bearbeiten, den Fork als separates deployment deployen. Das ursprüngliche backend läuft mit seinem aktuellen Graphen weiter; der Fork trägt die Topologie-Änderung. Sobald der Fork nachgewiesen ist, zieht das Team das ursprüngliche deployment zurück oder promotet den Fork als neues Produktions-backend, je nach Workflow. Das ist dasselbe Muster, das parallele Umgebungen funktionieren lässt — der Weg, den Graphen zu ändern, ohne die Produktion zu beeinträchtigen, ist, ein neues zu deployen, statt den laufenden Graphen zu bearbeiten.
Betriebsmodi
Verwende diese als die kleine Menge von Stellschrauben, die ändern, wie ein deployment läuft.
Debug-deployments. --debug aktiviert eine reichhaltigere Log-Erfassung aus jedem Container. Der Start ist langsamer, also reserviere es für die Verfolgung konkreter Probleme statt als Standard. Die deployment-Zeile trägt debug: true, sodass Debug-Läufe auf einen Blick zu unterscheiden sind.
Fixierte Lebensdauer. Standardmäßig verlängert sich ein deployment automatisch bis zur Obergrenze des runtime. Die Übergabe von --fixed-duration <go-duration> zur deploy-Zeit fixiert eine harte Frist — die Auto-Verlängerung wird deaktiviert und die Plattform fordert das runtime planmäßig zurück. Das passt zu bekannten Wall-Clock-Budgets wie einem Demo-Fenster oder einem geplanten Batch und ist nicht die Wahl für die Produktion.
Lease-besessene deployments. Ein deployment, das innerhalb eines lease erstellt wird, gehört diesem lease und wird zurückgefordert, wenn das lease schließt. Das ist die Standardform für kurzlebige Testläufe und für Batch-Berechnungen, die ihren Job nicht überleben sollen — siehe Leases und Der lease-Lebenszyklus.
Was "gesund" bedeutet
Ein running-deployment bestätigt, dass jeder Container hochgefahren ist. Es bestätigt nicht, ob der Workflow korrekte Ausgaben erzeugt, ob das Modell die richtigen Gewichte geladen hat oder ob die typisierten Werte, die über Kanten fließen, semantisch richtig sind. Gesundheit ist runtime-Bereitschaft; Verhaltenskorrektheit ist eine separate Frage, beantwortet durch die Nachweis-Schleife.
Die nützliche Disziplin ist, Traffic an running zu gaten (das runtime ist bereit) und Promotion an die Nachweis-Schleife zu gaten (das runtime erzeugt die richtigen Ergebnisse). Beide zu vermengen erzeugt beide Arten von Fehlern — Traffic zu senden, bevor das runtime bereit ist, und ein deployment zu promoten, das läuft, ohne die richtigen Ergebnisse zu erzeugen.
Siehe Verhalten nachweisen für die Nachweis-Schleife-Seite dieses Vertrags.
Wo das hineinpasst
Ein deployment ist die runtime-Seite der Plattform: Die Bedienoberfläche ist eine kleine Menge von Verben, der Lebenszyklus sind vier Zustände plus die vorgelagerte Platzierungsprüfung, und der endpoint-Vertrag ist ein Alias-Modell auf dem backend. Die Graph-Definition im backend und die UI in der Application zu halten, ist das, was das deployment fokussiert lässt auf das Ausführen und Beobachten der Container, selbst wenn die Workflows, die es ausführt, reichhaltig werden.
Verwandt
- Solutions — die vollständige Schichtentorte; das deployment sitzt zwischen backend und Application.
- Backends — der typisierte Graph, den das deployment ausführt.
- Applications — UIs, die Alias-URLs aus einem deployment auflösen.
- Runtimes und Nodes — das Rechen-Fabric, auf dem das deployment landet.
- Leases — kurzlebige, lease-besessene deployments.
- Deploy und Monitoring — die Bedienschleife im Detail.
- Verhalten nachweisen — semantischer Nachweis über die runtime-Gesundheit hinaus.