Zero-Downtime-Deployments ohne Kubernetes: Bewährte Ansätze
Zero-Downtime-Deploys ohne Kubernetes: Die „uralten Methoden“ liefern immer noch ab
Seit Jahren ist Kubernetes der Lieblingshammer der Branche, und jedes Software-Deployment-Problem sah aus wie ein Nagel. Einer der Gründe, warum Leute danach greifen, ist einfach: Es lässt Zero-Downtime-Deployments so einfach wirken wie das Umlegen eines Schalters. Neue Version ausrollen, die alte am Leben halten, bis die neue stabil läuft, den Load Balancer den Traffic umverteilen lassen, fertig.
Aber hier ist die Sache: Leute haben schon lange vor Kubernetes' großem Auftritt Code ohne Downtime ausgeliefert, und sie tun es heute noch—oft mit weit weniger Komplexität, weniger beweglichen Teilen und einer deutlich geringeren kognitiven Last. Und wenn Sie mit Engineers abhängen, die schon eine Weile in den Schützengräben stehen, hören Sie ein wiederkehrendes Thema: Kubernetes ist bequem, aber nicht der einzige Weg. Es ist nicht mal immer der beste Weg.
In einer Welt, in der „nutz einfach Kubernetes“ zum Standardrefrain geworden ist, machen die sogenannten „uralten Methoden“ des Deployments ein Comeback. Nicht aus Nostalgie, sondern weil sie immer noch funktionieren—erschreckend gut.
Der Load Balancer: Der ursprüngliche MVP
Die häufigste Antwort erfahrener Engineers kommt mit einem Achselzucken, als würden sie eine Frage zur Schwerkraft beantworten.
Zwei Server betreiben. Den Load Balancer die Arbeit machen lassen.
Dieser Ansatz ist älter als manche Cloud-Engineers von heute. Sie ziehen zwei Instanzen hoch (oder zwanzig), richten einen Load Balancer darauf aus und aktualisieren eine Instanz nach der anderen. Solange Ihre App weiß, wie man sich höflich verabschiedet—dazu später mehr—können Sie neuen Code ausrollen, ohne dass es jemand bemerkt.
Es ist nicht spektakulär, aber es ist kugelsicher. Ein grobes Werkzeug, sicher, aber eines, dem seit Jahrzehnten vertraut wird. „Wir machen das seit über 30 Jahren so“, sagte ein Engineer, und die Runde nickte im Grunde unisono.
Wenn Sie NGINX oder HAProxy verwenden, haben Sie das Kernfeature bereits eingebaut: Health-Checks, Connection Draining und sanfte Übergabe. Ein Kommentator erinnerte sogar daran, dass NGINX Upstreams tauschen kann, ohne Pakete zu verlieren. Keine Tränen, kein Drama.
Blue-Green-Deployments: Das klassische Muster
Wenn Kubernetes-Deploys das moderne Web-Framework für Uptime sind, sind Blue-Green-Deployments das HTML 1.0 dieser Technik—einfach, direkt und immer noch bestens wirksam.
Hier ist das Playbook:
- Sie deployen die neue Version in die grüne Umgebung.
- Sie halten die blaue Umgebung mit der stabilen Version am Laufen.
- Wenn Grün alle Ihre Checks besteht, schalten Sie den Traffic um.
- Wenn alles schiefgeht, schalten Sie den Traffic zurück zu Blau.
Es ist das Deployment-Äquivalent zum Umschalten der HDMI-Ports an Ihrem Fernseher. Wenig Aufwand. Hohe Zuverlässigkeit. Null Downtime, es sei denn, Sie zählen die Millisekunden, die das Routing zum Aufholen braucht.
Engineers im Thread schwören darauf. Manche prahlen sogar damit, wie schnell sie das können. Eine Person sagte, sie hätten früher ganze Flotten—über tausend Server—in unter einer Minute umgeschaltet, einfach durch Austauschen von Symlinks. Apropos...
Symlinks: Der UNIX-Trick, der einfach nicht sterben will
Gäbe es eine Hall of Fame für einfache Deployment-Hacks, wäre das First-Ballot-Material.
Vor Containern, vor Orchestrierungsplattformen, vor modernem Config-Management deployten Leute Apps, indem sie einen Symlink namens current aktualisierten, sodass er vom alten Release-Verzeichnis auf das neue zeigte.
Der Ablauf sieht so aus:
- Neuen Code nach
/var/www/releases/version-329320hochladen - Den
current-Symlink darauf umbiegen - Bei Bedarf den Webserver neu starten (oder sanft neu laden)
- Mit etwas Koffeinhaltigem feiern
Weil das Aktualisieren eines Symlinks eine atomare Operation ist, ist der Wechsel sofort—buchstäblich. Und wenn Sie zurückrollen wollen? Zeigen Sie current einfach zurück auf das alte Verzeichnis. Kein Neubauen nötig, kein Redeploy auf eine Container-Plattform nötig, kein Augenzudrücken und Beten, dass nichts kaputtgeht.
Leute, die dieses Muster heute nutzen, kombinieren es oft mit Tools wie Ansibles deploy_helper, aber Sie brauchen kein spezielles Tooling. Es funktioniert genauso gut mit einem Bash-Skript, solange Sie hin und wieder alte Releases aufräumen.
DNS: Technisch machbar, praktisch chaotisch
Ein paar Engineers gaben zu, versucht zu haben, DNS für Zero-Downtime-Deploys einzusetzen. Die Idee ist einfach: eine niedrige TTL setzen, den A-Record auf den neuen Server umbiegen und die Propagierung den Rest erledigen lassen.
In der Praxis funktioniert das so einigermaßen.
Bis es nicht mehr funktioniert.
Caching-Verhalten ist über ISPs, Firmennetzwerke, Browser und Geräte hinweg unvorhersehbar. Ein Engineer sagte, man könne es machen, „wenn Komplexität ein Anliegen ist“, aber andere schalteten sich schnell mit Horrorgeschichten über DNS-Änderungen ein, die Minuten oder Stunden oder—ja—länger dauerten.
Es ist in Ordnung, wenn Sie in kleinem Maßstab operieren oder etwas Informelles betreiben. Aber DNS als Load Balancer zu nutzen? Das ist wie eine Mikrowelle zu benutzen, um einen Truthahn zu braten. Technisch möglich. Erschreckend inkonsistent.
Session Draining: Die Geheimzutat sanfter Shutdowns
Egal ob Sie Kubernetes, ein selbstgebautes Skript oder einen Haufen verrosteter Server im Besenschrank verwenden—die goldene Regel für Zero Downtime ist dieselbe:
Ihre App muss in der Lage sein, herunterzufahren, ohne Nutzern die Tür vor der Nase zuzuschlagen.
Der Trick ist, auf SIGTERM zu lauschen, das Signal, das Ihrem Prozess sagt, mit dem Herunterfahren zu beginnen, statt sofort zu sterben. Engineers im Thread haben es praktisch von den Dächern geschrien, dass genau das der wahre Schlüssel zu reibungslosen Deployments ist.
Hier die Grundidee:
- App empfängt SIGTERM
- Sie stoppt, neue Anfragen anzunehmen
- Sie lässt aktive Anfragen fertig laufen
- Nach einer Karenzzeit killt das System sie, falls sie noch hängt
Jedes Web-Framework, das etwas taugt, unterstützt das auf die eine oder andere Weise. Ein Engineer sagte, in Go sei es „ein Zweizeiler“, Spring Boot hat es eingebaut, und sogar Python-Frameworks unterstützen es. Wenn Ihre App SIGTERM sauber behandeln kann, können Sie Updates mit fast jeder Infrastruktur ausrollen.
Cloud-Plattformen: Zero Downtime als Service
Wenn Sie Managed Services bevorzugen: Die gute Nachricht ist, dass heutzutage so ziemlich jede Cloud herausgefunden hat, wie man Zero-Downtime-Deploys handhabt—ohne dass Sie die Feinheiten der Pod-Eviction verstehen müssen.
Google Cloud Run macht es, indem es neue Revisionen hochzieht und Traffic schrittweise umleitet.
AWS ECS und Fargate machen seit Jahren Rolling Updates mit Load Balancern.
Azure App Service lässt Sie in Staging-Slots deployen und diese wie ein Zauberer, der Becher tauscht, umschalten.
All das basiert auf denselben alten Ideen, die Leute seit Jahrzehnten nutzen: mehrere Instanzen, Load Balancing und Health-Checks.
Docker ohne Kubernetes: Immer noch völlig machbar
Viele Leute im Thread betreiben alles in Docker, machen sich aber nicht die Mühe mit Kubernetes. Sie nutzen:
- Docker Compose mit manueller Skalierung
- Traefik als Reverse Proxy
- docker-swarm für leichtgewichtige Orchestrierung
- Einfache Rolling Updates, ein Container nach dem anderen
Die Idee ist dieselbe wie beim Betreiben mehrerer Server, nur dass jeder „Server“ ein Container ist. Traefik macht es besonders einfach, indem es Traffic nur zu Containern leitet, die sich selbst als gesund melden.
Ein Engineer beschrieb einen Workflow, bei dem CI/CD eine zweite Kopie des App-Images hochfährt, wartet, bis sie gesund ist, Traffic dorthin leitet, den Rest des Dienstes aktualisiert und dann die Staging-Kopie herunterfährt. Klingt schick, aber die Grundstruktur ist sehr traditionell.
Der kniffligste Teil: Datenbank-Migrationen
Wenn es einen Bösewicht gibt, der Zero-Downtime-Deployments heimsucht, dann sind es Datenbankänderungen.
Das Problem:
Neuer Code erwartet neue Spalten oder Tabellen.
Alter Code läuft noch.
Sie können keines von beiden kaputtmachen.
Die eigentliche Antwort aus dem Thread ist derselbe Rat, den man überall von erfahrenen Teams hört:
Migrationen schreiben, die alten Code nicht kaputtmachen.
Das bedeutet üblicherweise:
- Neue Spalten hinzufügen statt umzubenennen
- Aufhören, in alte Spalten zu schreiben, bevor sie gelöscht werden
- Destruktive Änderungen im selben Deploy vermeiden
- Das Schema später aufräumen, nachdem alle alten App-Versionen weg sind
Wenn Sie das beherrschen, verschwindet die Hälfte Ihrer Deployment-Angst.
Also... brauchen Sie wirklich Kubernetes?
Wenn Sie in globalem Maßstab operieren, mit Diensten, die mit anderen Diensten über noch mehr Dienste sprechen? Sicher. Kubernetes hilft. Wenn Sie ein großes Team koordinieren, das konsistentes Tooling und Leitplanken braucht, verdient es sich sein Geld absolut.
Aber wenn Sie ein paar Web-Apps betreiben? Wenn Ihre Flotte in Servern statt in Kontinenten gemessen wird? Wenn Sie etwas wollen, das funktioniert und nicht verlangt, einen Teil Ihres Lebens YAML zu widmen?
Dann liefern die alten Methoden immer noch ab.
Load Balancer. Zwei Server. Symlinks. Reverse Proxys. SIGTERM. Blue-Green. Health-Checks.
Diese Werkzeuge sind einfach, vorhersehbar und bombenfest.
Zero-Downtime-Deployments ohne Kubernetes sind keine verlorene Kunst. Sie sind gängige Praxis für unzählige Teams—die Art von Sache, die Engineers seit Jahrzehnten still in der Produktion betreiben.
Und sie werden nirgendwo hingehen.