Clusterward
← Zurück zum Blog
ArchitekturAktualisiert Florian Apel

Von ingress-nginx zu Envoy Gateway: Controller-Wechsel ohne dunkles Fenster

Die Ingress-Klasse ändern und deployen: Der neue Controller bedient, der alte nicht mehr, und DNS zeigt noch auf den alten. Der Host antwortet 404, bis die TTL abläuft. So geht es besser.

Titelbild: Von ingress-nginx zu Envoy Gateway: Controller-Wechsel ohne dunkles Fenster

Die Kubernetes Gateway API ist der Nachfolger des Ingress-Objekts, und Envoy Gateway ist eine der reifsten Implementierungen. Wer heute nginx-Annotationen pflegt, will irgendwann dorthin: typisierte Routen, Policies statt Annotations, Timeouts und Retries als Felder. Der Weg dorthin hat eine Falle, die man erst sieht, wenn ein Host 404 antwortet.

Was passiert beim naiven Wechsel?

Ein Service hat eine Ingress-Klasse. Man ändert sie von nginx auf envoy, deployt, und der neue Controller rendert Gateway und HTTPRoute. Der alte Ingress wird aufgeräumt, weil er zum gewünschten Zustand nicht mehr gehört. Sauber.

Nur: Jeder Controller hat seinen eigenen Load Balancer mit eigener öffentlicher Adresse. DNS zeigt noch auf die alte. Besucher landen bei nginx, der den Host nicht mehr kennt, und bekommen den Default-Backend-404. Bis die DNS-TTL abgelaufen ist und alle Resolver die neue Adresse haben, ist der Host dunkel. Bei einer TTL von einer Stunde ist das eine Stunde. Wir haben das live erlebt, an einem Host mit echten Nutzern.

Der richtige Ablauf: Cutover

  1. Beide bedienen. Der Service wird für den neuen Controller gerendert, aber der alte Ingress bleibt. nginx und Envoy antworten beide für den Host, jeder über seinen Load Balancer. Egal, welche Adresse DNS liefert, der Host funktioniert.
  2. DNS umziehen. Der Record zeigt jetzt auf die Adresse des neuen Load Balancers. Während die TTL abläuft, kommen Besucher mal hier, mal dort an. Beides ist richtig.
  3. Prüfen. Jeder Host des Services löst auf die neue Adresse auf, von außen geprüft, nicht aus dem Cluster – hinter dem Cloudflare-Proxy über die API des DNS-Anbieters, weil öffentliches DNS dort nur Cloudflares Adressen zeigt.
  4. Aufräumen. Erst jetzt, und mit einer Stunde Abstand, damit zwischengespeicherte Antworten ablaufen, werden die alten Ingress-Objekte gelöscht. Der alte Load Balancer bedient den Host nicht mehr, aber es kommt auch niemand mehr dort an.

Vier Schritte, von denen der erste der ungewohnte ist: absichtlich zwei Renderings desselben Services im Cluster halten. Das ist kein Drift, das ist ein Zustand mit Namen.

Was gleich bleiben muss

Beide Controller müssen dasselbe Verhalten zeigen, sonst merkt der Nutzer den Wechsel:

  • TLS. Ein Let’s-Encrypt-Zertifikat pro Host oder ein Wildcard-Secret. Envoy Gateway braucht cert-manager mit Gateway-API-Unterstützung, was je nach cert-manager-Version ein Feature-Gate oder eine Konfigurationsoption ist; das muss vor dem ersten Gateway laufen.
  • Redirects. www auf Apex, alte Domains auf neue. Bei nginx eine Annotation, bei Envoy ein RequestRedirect-Filter. Der Statuscode sollte derselbe sein.
  • Zugriffslisten. Erlaubte Quell-Adressen als nginx-Annotation oder als SecurityPolicy bei Envoy, mit Proxy-Protokoll auf beiden Load Balancern.
  • Body-Größe. nginx begrenzt auf 1 MB, wenn niemand etwas setzt; Envoy hat keine Grenze. Wer bei nginx 64 MB erlaubt hatte, merkt bei Envoy keinen Unterschied. Umgekehrt schon.
  • Proxy-Protokoll. Der neue Load Balancer braucht dieselbe Einstellung wie der alte, sonst sieht Envoy nur Load-Balancer-Adressen.

Was macht Envoy anders als nginx?

Eine Sache, die beim Wechsel auffällt: Envoy Gateway kann mehrere Gateway-Objekte in eine Proxy-Flotte zusammenführen. Ein Gateway pro Service, alle hinter einem Load Balancer. Für Betreiber mit vielen Services ist das der eigentliche Gewinn: Policies pro Service, ein Load Balancer für alle. Bei nginx sind Einstellungen pro Ingress Annotations mit Freitext; bei Envoy sind es typisierte Objekte, die der API-Server prüft. Für neue Setups empfiehlt die Envoy-Gateway-Dokumentation statt der Zusammenführung inzwischen ListenerSet aus der Gateway API: ein zentrales Gateway, und jedes Team legt Ports, Hostnamen und Zertifikate in eigenen ListenerSets an.

Wann der Wechsel sich nicht lohnt

Wer fünf Hosts hat, keine Timeouts oder Retries braucht und mit nginx-Annotations zufrieden ist, gewinnt durch den Wechsel wenig und bezahlt vorübergehend einen zweiten Load Balancer. Die Gateway API lohnt sich, wenn Netzwerkverhalten pro Service ein Thema wird: Rate-Limits pro Kunde, Retries mit Bedingungen, Header-Manipulation, Sticky Sessions über Header.

Die Vorbereitung im Cluster

Bevor der erste Service wechseln kann, braucht der Cluster die Plattform für die Gateway API. Das sind mehr Schritte, als man denkt:

  1. Envoy Gateway installieren, als zweiten Controller neben nginx, mit eigenem Load Balancer und, wenn nginx es hat, ebenfalls mit Proxy-Protokoll.
  2. cert-manager mit Gateway-API-Unterstützung. Je nach Version ein Feature-Gate oder eine Konfigurationsoption. cert-manager muss danach neu starten, weil es die Gateway-Informer nur beim Start anlegt, wenn die CRDs schon existieren.
  3. Eine GatewayClass und eine EnvoyProxy-Konfiguration, die Gateways mehrerer Services in eine Proxy-Flotte zusammenführt.
  4. Ein geteiltes HTTP-Gateway auf Port 80, das HTTP-01-Challenges von cert-manager und die Umleitung auf HTTPS bedient.
  5. Ein zweiter ClusterIssuer mit HTTP-01-Solver über das Gateway, mit demselben Konto wie der nginx-Issuer.

Fünf Objekte, die alle stimmen müssen, bevor das erste Zertifikat über Envoy ausgestellt wird. Auf Staging zuerst.

Sechs Fehler, die wir gemacht haben

  • cert-manager mit Feature-Gate, aber ohne Neustart. Die Gateway-Unterstützung war konfiguriert, der Gateway-Shim lief trotzdem nicht, weil cert-manager vor den CRDs gestartet war. Das Zertifikat blieb auf "pending", ohne Fehlermeldung. Ein Rollout von cert-manager nach der Installation der CRDs löste es.
  • Ein einfacher Klassenwechsel in den Einstellungen. Der erste Cutover war keiner: Klasse geändert, deployt, nginx-Ingress weg, DNS zeigte noch auf nginx. Vierzig Minuten 404 auf einem Host mit Nutzern. Seitdem gibt es den einfachen Wechsel nicht mehr, nur den Cutover.
  • Der alte Controller mit der neuen Klasse. Im Cutover renderte der alte Controller seine Objekte weiter, aber schon mit der neuen Klasse. nginx fühlte sich nicht mehr zuständig und antwortete mit 404, obwohl DNS noch auf nginx zeigte. Im Cutover rendert deshalb jeder Controller mit seiner eigenen Klasse.
  • www ohne Zertifikat auf Envoy. Das Zertifikat eines Hosts gehörte noch dem nginx-Ingress, und der Gateway-Shim von cert-manager übernimmt kein Zertifikat, das einem Ingress gehört. Der Gateway nutzt im Cutover deshalb die Secrets, die nginx schon füllt; erst am Ende geht das Zertifikat an den Gateway über.
  • Fehler 525 hinter Cloudflare. Hosts ohne eigenes Zertifikat hinter Cloudflare im Modus „Full“ bekamen bei nginx dessen Platzhalter-Zertifikat, bei Envoy gab es keinen HTTPS-Listener, und Cloudflare antwortete mit 525. Solche Hosts bekommen seitdem ein selbst signiertes Origin-Zertifikat.
  • Zu früh abgeschlossen. Mit einer TTL von 3600 Sekunden hingen Besucher nach dem Abschluss noch eine Stunde am alten Load Balancer, der den Host nicht mehr kannte. Ein Cutover schließt seitdem erst eine Stunde, nachdem jeder Host auf die neue Adresse zeigt.

Wann lohnt sich der Weg zurück zu nginx?

Auch der Rückweg ist ein Cutover, in die andere Richtung. Solange nginx installiert bleibt, ist er jederzeit möglich. Erst wenn der letzte Service auf Envoy läuft und ein Quartal ohne Zwischenfall vergangen ist, lohnt es sich, nginx zu deinstallieren und den zweiten Load Balancer abzugeben.

Wie Clusterward das kapselt

„Klasse wechseln…“ im Netzwerk-Block der Service-Seite zeigt vor dem Start für jeden Host, wer den Record umzieht – Clusterward bei eigenen, übernommenen oder fehlenden Records und bei Hosts, die nur ein Wildcard beantwortet, oder Sie beim DNS-Anbieter – und was mit dem Zertifikat passiert. Der Start rollt den Service mit beiden Controllern aus, jeder mit seiner eigenen Klasse und gültigen Zertifikaten. Sobald der neue Controller bedient, zeigt Clusterward die Records in registrierten Cloudflare-Zonen auf die neue Adresse und liest sie über die Cloudflare-API zurück; so erkennt es den Umzug auch hinter dem Proxy. Eine Stunde, nachdem jeder Host auf die neue Adresse zeigt, schließt Clusterward den Cutover und rollt noch einmal aus, um die alten Objekte zu entfernen. Bis dahin lässt sich der Wechsel abbrechen; zeigt schon ein Host auf die neue Adresse, läuft der Rückweg wieder als Cutover. Ein Wechsel per einfacher Einstellung wird abgelehnt, weil er genau das dunkle Fenster erzeugt. Dasselbe gilt für die Standard-Klasse des Clusters: Solange Services ohne eigene Klasse darüber einen Host ausliefern, verweigert Clusterward die Änderung, bis diese Services auf die alte Klasse festgelegt sind. Manuell bleibt nur ein Host hinter dem Cloudflare-Proxy in einer Zone, die nicht in Clusterward registriert ist. Details unter Netzwerk & Ingress.

Fazit

Ein Controller-Wechsel ist kein Deployment, sondern ein DNS-Umzug mit zwei Servern, die währenddessen beide antworten. Wer das so plant, hat kein dunkles Fenster. Wer die Klasse einfach ändert, hat eines, so lang wie die TTL.

Einen Controller-Wechsel planen? Schreiben Sie uns, wie viele Hosts heute über ingress-nginx laufen. Wir zeigen, wie der Umzug mit zwei Load Balancern ohne Ausfall abläuft. Wechsel besprechen →

Quellen und weiterführende Links

Häufige Fragen

  • Weil jeder Controller einen eigenen Load Balancer mit eigener öffentlicher Adresse hat. Ändern Sie nur die Ingress-Klasse, wird der alte Ingress aufgeräumt, während DNS noch auf nginx zeigt. Besucher erhalten dort den Default-Backend-404, bis die DNS-TTL abgelaufen ist und alle Resolver die neue Adresse haben.