Kubernetes ~4 Min.

Gateway API statt Ingress

HTTPRoute, GatewayClass und schrittweise Migration.

von PlatPrep

Es fängt meistens mit einer kleinen Anforderung an. “Wir brauchen Header-basiertes Routing für unseren A/B-Test.” Du schaust in die Docs deines Ingress-Controllers und findest eine proprietäre Annotation. Funktioniert — bis die nächste Version des Controllers die Syntax ändert. Oder die Annotation existiert bei einem anderen Controller gar nicht.

Das ist das strukturelle Problem mit Ingress: ein minimalistisches API, das fast vollständig über Annotations erweitert wird. Jeder Controller hat seine eigene Annotations-Sprache. Portabilität ist eine Illusion.

Gateway API löst das durch ein durchdachteres Ressourcenmodell mit drei Ebenen: GatewayClass definiert, welche Controller-Implementierung zuständig ist. Gateway ist die konkrete Instanz — Listener, Ports, TLS-Konfiguration, und Regeln, welche Namespaces Routes anbinden dürfen. HTTPRoute beschreibt das eigentliche Routing und gehört den Anwendungsteams:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: checkout
  namespace: team-checkout
spec:
  parentRefs:
    - name: shared-gateway
      namespace: infra
  hostnames:
    - "shop.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /checkout
      backendRefs:
        - name: checkout
          port: 8080
          weight: 90
        - name: checkout-canary
          port: 8080
          weight: 10

Hier stecken gleich zwei Dinge drin, die mit Ingress mühsam waren. Erstens das Ownership-Modell: Das Infra-Team betreibt den shared-gateway im infra-Namespace, das Checkout-Team pflegt seine Route im eigenen Namespace und hängt sie per parentRefs an. Kein zentrales Ingress-YAML mehr, an dem zehn Teams gleichzeitig herumeditieren. Der Gateway kontrolliert über allowedRoutes in der Listener-Konfiguration, wer andocken darf — etwa nur Namespaces mit einem bestimmten Label. Zweitens gewichtetes Traffic-Splitting als First-Class-Feature: 90/10 für ein Canary-Deployment, deklarativ, portabel über Implementierungen hinweg, ohne Controller-spezifische Annotations.

Header- und Query-Matching, URL-Rewrites, Request-Mirroring — was bei Ingress Annotation-Folklore war, ist in der HTTPRoute-Spec typisiert und validierbar. Falsch geschriebene Annotations scheitern leise; ein falsches Feld in einer HTTPRoute lehnt der API-Server ab. Das klingt nach einer Kleinigkeit, ist aber genau der Unterschied zwischen einem Tippfehler, der im Review auffällt, und einem, der erst im Produktions-Traffic auffällt.

Sicherheit über Namespace-Grenzen

Cross-Namespace-Referenzen sind in Gateway API bewusst nicht implizit erlaubt. Will eine Route auf einen Service in einem fremden Namespace zeigen, muss der Ziel-Namespace das per ReferenceGrant ausdrücklich gestatten — eine Ressource, die im Ziel-Namespace liegt und sagt: “HTTPRoutes aus Namespace X dürfen Services bei mir referenzieren.” Die Richtung ist entscheidend: Der Besitzer der Ressource erteilt die Erlaubnis, nicht der, der zugreifen will. Ohne Grant schlägt die Referenz fehl. Das klingt nach Bürokratie, verhindert aber eine reale Angriffsklasse: dass ein Team Traffic auf Services umbiegt, die ihm nicht gehören.

Beim Debugging hilft, dass Gateway API konsequent mit Status-Conditions arbeitet. Eine Route, die nicht greift, hat eine Accepted- oder ResolvedRefs-Condition mit Begründung — fehlende Permission, nicht auflösbarer Backend-Service, Hostname-Konflikt mit dem Listener. kubectl describe httproute beantwortet damit Fragen, für die man bei Ingress die Controller-Logs durchsuchen musste.

Auch TLS profitiert vom Schichtenmodell: Zertifikate hängen am Gateway-Listener und damit beim Infra-Team — Anwendungsteams müssen nie wieder Zertifikats-Secrets in ihre Namespaces kopieren. In Kombination mit cert-manager, der die Listener-Zertifikate automatisch ausstellt und rotiert, ist der gesamte TLS-Lebenszyklus aus den Team-Workflows verschwunden.

Migration: parallel statt Big Bang

Gateway API ist seit Version 1.0 GA; GatewayClass, Gateway und HTTPRoute sind stabile v1-Ressourcen. Wichtig zu verstehen: Die API wird als CRDs ausgeliefert und unabhängig vom Kubernetes-Release versioniert — die Implementierung liefert der Controller deiner Wahl, und nginx, Istio, Contour, Envoy Gateway und Cilium unterstützen Gateway API parallel zum klassischen Ingress. Genau das ermöglicht eine unaufgeregte Migration: beides gleichzeitig betreiben, unkritische Services zuerst umziehen, Erfahrungen sammeln, dann die kritischen. Für die mechanische Übersetzung bestehender Ingress-Ressourcen gibt es mit ingress2gateway ein offizielles Werkzeug — die Annotations-Spezialfälle muss man trotzdem von Hand prüfen, denn genau die waren ja nie portabel.

Zwei ehrliche Einschränkungen. Erstens unterscheiden sich Implementierungen darin, welche optionalen Features sie unterstützen — die Spec kennt Support-Level (Core, Extended, Implementation-specific), und ein weight-Split funktioniert überall, exotischere Filter nicht zwingend. Vor der Festlegung lohnt der Blick in die Conformance-Reports der Implementierung. Zweitens sind Nicht-HTTP-Routen (TCPRoute, UDPRoute, TLSRoute) noch nicht auf demselben Reifegrad — wer heute hauptsächlich rohe TCP-Passthroughs braucht, gewinnt durch die Migration wenig.

Für neue Cluster ist die Empfehlung trotzdem eindeutig: direkt mit Gateway API anfangen. Kein Annotation-Lock-in, klares Ownership-Modell, und Features wie Traffic-Splitting, die man früher dem Service Mesh überlassen musste — wobei für mTLS und feingranulare Traffic-Steuerung zwischen Services weiterhin ein Mesh wie Istio seinen Platz hat. Die Kubernetes-Networking-Grundlagen dazu vertieft der Kubernetes-Lernpfad.