Gateway API
Eingehender HTTP-Verkehr läuft über die Gateway API, nicht über Ingress. Du legst in deinem Namespace eine HTTPRoute an und hängst sie an das gemeinsam genutzte Gateway.
An welches Gateway du dich hängst
Es gibt genau ein Gateway: default im Namespace nginx-gateway. Jede HTTPRoute referenziert es über parentRefs.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: myapp
annotations:
cert-manager.io/cluster-issuer: "auto"
spec:
parentRefs:
- name: default
namespace: nginx-gateway
sectionName: https-myapp-dein-namespace-itsh-dev
hostnames:
- myapp.<dein-namespace>.itsh.dev
rules:
- backendRefs:
- name: myapp
port: 8080Welche Hostnamen du verwenden darfst
Dein Namespace hat eine eigene Subdomain. Jeder Name darunter gehört dir und ist ohne Rückfrage nutzbar:
| Tarif | Erlaubte Hostnamen |
|---|---|
| Bezahlt und Pay-as-you-go | *.<dein-namespace>.itsh.dev |
| Free Tier | *.<dein-namespace>.itsh-apps.dev |
Ein Namespace tenant-7 kann also sofort myapp.tenant-7.itsh.dev, api.tenant-7.itsh.dev und alles Weitere auf dieser Ebene ausliefern.
Alles andere wird beim Anlegen der Route abgelehnt:
Hostname is not allowed in namespace 'tenant-7'. Tenant namespaces may only use
*.tenant-7.itsh.dev (paid) or *.tenant-7.itsh-apps.dev (free) subdomains or
hostnames listed in the itsh.dev/allowed-hostnames namespace annotation.Eine Route muss außerdem mindestens einen Hostnamen angeben. Eine Route ohne Hostnamen wird ebenfalls abgelehnt, weil sie sich sonst als Catch-all an das gemeinsame Gateway hängen würde.
Eigene Domain verwenden
Um eine eigene Domain auszuliefern, trägst du sie zuerst im Portal ein. Du weist per TXT-Eintrag nach, dass sie dir gehört. Nach der Prüfung wird sie in die Liste der für deinen Namespace erlaubten Hostnamen aufgenommen, und du kannst sie danach wie jeden anderen Hostnamen in einer HTTPRoute verwenden.
Eine bei uns registrierte Domain braucht keine Prüfung
Ist die Domain bereits über ITSH registriert, ist sie sofort nach dem Eintragen freigeschaltet. Wir sehen, dass sie zu deinem Konto gehört, es gibt also keinen TXT-Eintrag anzulegen und nichts abzuwarten.
Eigene Domains gibt es im Free Tier nicht
Ein Free-Tier-Namespace kann nur Namen unterhalb seiner itsh-apps.dev-Subdomain ausliefern. Für eine eigene Domain brauchst du einen bezahlten oder Pay-as-you-go-Tarif.
HTTPS-Listener entstehen automatisch
Du musst am Gateway nichts konfigurieren. Trägt deine HTTPRoute die Annotation cert-manager.io/cluster-issuer, wird der passende HTTPS-Listener samt Zertifikat automatisch angelegt.
Der Wert der Annotation wählt keinen Issuer aus
Es zählt allein, dass die Annotation vorhanden ist. Welcher Issuer verwendet wird, gibt die Plattform vor. Ein anderer Wert in deiner HTTPRoute ändert daran nichts.
Namensschema der Listener
Der Listener heißt https-<Hostname, Punkte durch Bindestriche ersetzt>:
| Hostname | sectionName |
|---|---|
myapp.tenant-7.itsh.dev | https-myapp-tenant-7-itsh-dev |
shop.example.com | https-shop-example-com |
*.example.com | https-wildcard-example-com |
sectionName ist optional, aber du solltest ihn setzen
Der Listener wird auch ohne sectionName angelegt. Ohne die Angabe bindet deine Route jedoch zusätzlich an den Port-80-Listener http und liefert deine Anwendung damit im Klartext aus. Setz den sectionName also immer auf den HTTPS-Listener.
Weiterleitung von HTTP auf HTTPS
Die Weiterleitung ist eine eigene Route, die sich mit sectionName: http an den Port-80-Listener hängt:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: myapp-redirect
spec:
parentRefs:
- name: default
namespace: nginx-gateway
sectionName: http
hostnames:
- myapp.<dein-namespace>.itsh.dev
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301DNS
Für einen Hostnamen unter deiner Namespace-Subdomain musst du nichts tun. Die Subdomain zeigt bereits auf das Gateway, myapp.<dein-namespace>.itsh.dev ist also erreichbar, sobald deine Route existiert.
DNS wird erst dann deine Aufgabe, wenn du eine eigene Domain mitbringst.
Auto-DNS pflegt die Einträge für dich
Liegt die DNS-Verwaltung der Domain bei uns, schalt im Portal daneben Auto-DNS ein. Die Einträge entstehen dann aus deinen HTTPRoutes und bleiben aktuell, wenn du Hostnamen hinzufügst oder entfernst. Die Tabelle unten brauchst du also nur für Domains, die woanders liegen.
Auto-DNS lässt sich einschalten, sobald die Domain geprüft ist.
Für eine woanders gehostete Domain zeigst du sie selbst auf diese Adressen:
| Typ | Wert |
|---|---|
A | 91.98.6.3 |
AAAA | 2a01:4f8:1c1f:7bfa::1 |
gRPC
gRPC-Backends nutzen GRPCRoute statt HTTPRoute. Alles andere ist gleich: dasselbe Gateway, dieselben Hostnamen-Regeln, dasselbe Listener-Namensschema.
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: myapp-grpc
annotations:
cert-manager.io/cluster-issuer: "auto"
spec:
parentRefs:
- name: default
namespace: nginx-gateway
sectionName: https-grpc-dein-namespace-itsh-dev
hostnames:
- grpc.<dein-namespace>.itsh.dev
rules:
- backendRefs:
- name: myapp-grpc
port: 9000Setz sectionName auch hier. Ohne die Angabe bindet die Route den Klartext-Listener, und gRPC im Klartext willst du selten.
gRPC lässt sich nicht mit Scale-to-Zero kombinieren, solche Services müssen durchlaufen.
Client-IP und Forwarded-Header
Das Gateway setzt X-Forwarded-For und X-Real-IP. Deine Anwendung sollte diese Header nur akzeptieren, wenn die Verbindung vom Gateway kommt, also von einer privaten Adresse innerhalb des Clusters, und nie von beliebigen Absendern. Vertraut deine Anwendung den Headern von jedem, kann jeder seine eigene Client-IP behaupten und damit Logging, Rate-Limiting und IP-basierte Zugriffsregeln aushebeln.
Wie es weitergeht
- Scale-to-Zero, damit ein idler Service schläft
- Deine App ist nicht erreichbar, wenn kein Traffic ankommt