In een Kubernetes-cluster kun je HTTP- en HTTPS-verkeer routeren met de Kubernetes Gateway API. Een Gateway vervangt de traditionele Ingress Controller en geeft je een centrale plek voor SSL (TLS) terminatie, routingregels en beveiliging.
In deze handleiding configureer je stap-voor-stap een Kubernetes Gateway voor een eenvoudige demo-applicatie. Eerst deploy je een app en Service, daarna configureer je een Gateway en HTTPRoute en voeg je SSL-beveiliging toe met een TLS-certificaat (bijvoorbeeld via Cert-manager en Let’s Encrypt). Aan het eind test je of HTTPS correct werkt.
Voor deze handleiding heb je nodig:
- Een Kubernetes-cluster.
- Een Gateway-controller zoals Traefik of Cilium. Doorloop bijvoorbeeld eerst onze Traefik-handleiding.
- Cert-manager: Gateway API HTTPS listeners verwijzen naar TLS-certificaten via Kubernetes Secrets (niet via .json-bestanden); Cert-manager maakt gebruik van secrets, Traefik van .json. Om deze reden heb je voor het genereren van SSL-certificaten in deze setup Cert-manager nodig.
- Kubectl
- Een domeinnaam waarvan de DNS naar de gateway verwijst (Traefik of Cilium).
Wat is een Kubernetes Gateway?
De Kubernetes Gateway API introduceert nieuwe resource types, zoals GatewayClass, Gateway en HTTPRoute. Deze resources beschrijven hoe verkeer van buiten naar binnen je cluster loopt en welke services het verkeer mogen ontvangen. In tegenstelling tot een klassieke Ingress scheidt de Gateway API duidelijk de rol van infrastructuurbeheer (GatewayClass/Gateway) en applicatierouting (HTTPRoute).
Heel grof ziet een Gateway setup er als volgt uit:
- Een GatewayClass beschrijft welk type gateway-controller je gebruikt (bijvoorbeeld Traefik, NGINX of Cilium).
- Een Gateway definieert één of meer listeners (bijvoorbeeld HTTP op poort 8000 en HTTPS op poort 8443) met (sub)domeinen (hostnames) en TLS-instellingen.
- Een HTTPRoute koppelt (sub)domeinen en paden aan Services in een namespace.
In deze tutorial maak je een eigen Gateway in een aparte namespace, configureer je een HTTPRoute en voeg je SSL-terminatie toe aan de Gateway. Zo hoef je TLS-certificaten niet per app te beheren, maar centraal op de Gateway.
Demo-applicatie deployen achter de Gateway
TL;DR: de snelste copy-paste
Maak een bestand aan, bijvoorbeeld gateway-demo.yaml met de inhoud hieronder.
- Vervang in ieder geval demo.voorbeeld.nl door een eigen (sub)domein en pas desgewenst ook de namespace-naam aan:
apiVersion: v1
kind: Namespace
metadata:
name: demo-gateway
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
namespace: demo-gateway
spec:
replicas: 2
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: demo-app
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: demo-app
namespace: demo-gateway
spec:
selector:
app: demo-app
ports:
- port: 80
targetPort: 80
protocol: TCP
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: demo-gateway
namespace: demo-gateway
spec:
gatewayClassName: traefik
listeners:
- name: web
protocol: HTTP
port: 8000
hostname: demo.voorbeeld.nl
allowedRoutes:
namespaces:
from: Same
- name: websecure
protocol: HTTPS
port: 8443
hostname: demo.voorbeeld.nl
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: demo-gateway-tls
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: demo-route-redirect
namespace: demo-gateway
spec:
parentRefs:
- name: demo-gateway
sectionName: web
hostnames:
- demo.voorbeeld.nl
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: demo-route
namespace: demo-gateway
spec:
parentRefs:
- name: demo-gateway
sectionName: websecure
hostnames:
- demo.voorbeeld.nl
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: demo-app
port: 80
Maak vervolgens een namespace voor je gateway en pas het .yaml-bestand toe:
kubectl create namespace demo-gateway
kubectl apply -f gateway-demo.yaml
Je hebt een applicatie nodig achter de Gateway om je configuratie te testen. In dit voorbeeld gebruik je een eenvoudige HTTP ‘whoami’-service op poort 80 met een Deployment en Service. De app draait als container in het cluster; lees voor meer achtergrond onze uitleg over wat een container image is.
Stap 1
Maak een aparte namespace aan voor de demo-app en de Gateway-resources:
kubectl create namespace demo-gatewayDe namespace demo-gateway helpt om de demo-resources logisch te scheiden van de rest van je cluster.
Stap 2
Maak het bestand demo-app.yaml op je computer/laptop met de volgende inhoud:
apiVersion: v1
kind: Namespace
metadata:
name: demo-gateway
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
namespace: demo-gateway
spec:
replicas: 2
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: demo-app
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: demo-app
namespace: demo-gateway
spec:
selector:
app: demo-app
ports:
- port: 80
targetPort: 80
protocol: TCPDe Deployment start twee replicas van de traefik/whoami-container (een kleine HTTP-dienst die request-informatie teruggeeft) en de Service maakt deze pods bereikbaar op poort 80 binnen de namespace.
Stap 3
Deploy de demo-applicatie:
kubectl apply -f demo-app.yamlControleer daarna of de pods draaien:
kubectl get pods -n demo-gatewayZodra de pods in de status Running staan, is je backend klaar om via de Gateway bereikbaar te worden.
Stap 4
Nu de backend draait, configureer je eerst een GatewayClass (meestal al aanwezig). We gaan in dit voorbeeld uit van een Gateway-controller zoals Traefik, die de Gateway API ondersteunt.
Bekijk of er al GatewayClasses aanwezig zijn in je cluster, en zo ja welke:
kubectl get gatewayclassAls je provider of gateway-controller al een GatewayClass heeft aangemaakt (bijvoorbeeld traefik), gebruik je die naam in je Gateway en ga je door naar stap 5.
Staat er nog geen GatewayClass tussen? Voeg er dan zelf één toe. Als je bijvoorbeeld een GatewayClass wilt definëren voor Traefik, maak dan een bestand gatewayclass.yaml met de volgende inhoud:
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: traefik
spec:
controllerName: traefik.io/gateway-controllerPas de naam aan als je controller een andere GatewayClass verwacht (zie de documentatie van de GatewayClass die je gebruikt). De waarde controllerName identificeert welke controller Gateways van dit type beheert; in dit voorbeeld is dat de Traefik Gateway-controller.
kubectl apply -f gatewayclass.yamlMet deze stap koppel je de Gateway API aan jouw gekozen gateway-controller.
Stap 5
Maak een .yaml-bestand met de definitie van de daadwerkelijke Gateway voor HTTP- en HTTPS-verkeer, bijvoorbeeld demo-gateway-listener.yaml en de inhoud hieronder.
Gebruik je eigen domein in plaats van demo.voorbeeld.nl, de juiste namespace (hier demo-gateway) en GatewayClass-naam (traefik in het voorbeeld):
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: demo-gateway
namespace: demo-gateway
spec:
gatewayClassName: traefik
listeners:
- name: web
protocol: HTTP
port: 8000
hostname: demo.voorbeeld.nl
allowedRoutes:
namespaces:
from: Same
- name: websecure
protocol: HTTPS
port: 8443
hostname: demo.voorbeeld.nl
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: demo-gateway-tls
allowedRoutes:
namespaces:
from: Same
Stap 6
Deploy de Gateway:
kubectl apply -f demo-gateway-listener.yamlDeze Gateway luistert op poort 8000 voor HTTP-verkeer naar demo.voorbeeld.nl en op poort 8443 voor HTTPS-verkeer. De instelling allowedRoutes.namespaces.from: Same beperkt routes tot dezelfde namespace als de Gateway (demo-gateway), wat veiliger is in multi-tenant omgevingen.
Stap 7
Maak een HTTPRoute die het (sub)domein/de hostname en het pad koppelt aan de demo-Service. Maak bijvoorbeeld het bestand httproute.yaml met de volgende inhoud:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: demo-route
namespace: demo-gateway
spec:
parentRefs:
- name: demo-gateway
sectionName: websecure
hostnames:
- demo.voorbeeld.nl
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: demo-app
port: 80De parentRefs koppelt de route aan de Gateway demo-gateway. Alle paden onder / worden naar de Service demo-app op poort 80 gestuurd.
Stap 8
Pas de HTTP-route toe op je Kubernetes-cluster:
kubectl apply -f httproute.yamlControleer vervolgens of de Gateway en HTTPRoute ‘Ready’ zijn:
kubectl get gateway -n demo-gateway
kubectl get httproute -n demo-gatewayGebruik kubectl describe voor meer details als de status niet ‘Programmed’ of ‘Accepted’ is. Eventuele meldingen bij de conditions geven een hint waar het misgaat (bijvoorbeeld een onbekende GatewayClass of (sub)domein/hostname).
Stap 9
Nu HTTP werkt, voeg je SSL-beveiliging toe. In Kubernetes betekent dat meestal TLS-terminatie op de Gateway (via de met Cert-manager aangemaakte ClusterIssuer): de Gateway presenteert het certificaat aan de client en stuurt het verkeer als plain HTTP door naar de backend. Het certificaat staat in een Secret in dezelfde namespace als de Gateway.
Maak een Certificate-resource aan zodat Cert-manager automatisch een certificaat voor je domein aanvraagt. Gebruik de naam van je (Cluster)Issuer, bijvoorbeeld letsencrypt-issuer. Maak het bestand certificate.yaml met de volgende inhoud:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: demo-cert
namespace: demo-gateway
spec:
secretName: demo-gateway-tls
issuerRef:
name: letsencrypt-issuer
kind: ClusterIssuer
dnsNames:
- demo.voorbeeld.nlDe velden dnsNames en secretName moeten overeenkomen met je (sub)domein/hostname en de naam die je straks in de Gateway gebruikt. Cert-manager slaat het uitgegeven certificaat en de private key op in de Secret demo-gateway-tls.
Stap 10
Pas het zojuist aangemaakte certificate.yaml toe op je Kubernetes-cluster:
kubectl apply -f certificate.yamlControleer voor de zekerheid of het certificaat succesvol is aangemaakt:
kubectl describe certificate demo-cert -n demo-gatewayLet op de conditions; als de status Ready is en er geen fouten over DNS of HTTP-challenges staan, is de Secret met het certificaat beschikbaar. Met -n demo-gateway geef je aan in welke namespace het Certificate staat.
Stap 11
Test tot slot of HTTPS werkt met bijvoorbeeld een curl-commando, of navigeer naar het gebruikte (sub)domein in je browser:
curl -v https://demo.voorbeeld.nlJe zou een TLS-handshake moeten zien gevolgd door de output van de whoami-service. Als je browser geen waarschuwingen meer geeft over een onveilig certificaat, is je SSL-beveiliging correct ingesteld.
Troubleshooting: veelgemaakte fouten
Lukt het nog niet om je applicatie via HTTPS te bereiken? De volgende checks helpen je de meest voorkomende problemen op te lossen.
Stap 1
Verifieer dat de backend-Service en pods werken:
kubectl get svc -n demo-gateway
kubectl get pods -n demo-gateway
kubectl logs -l app=demo-app -n demo-gatewayAls de pods crashen of geen verkeer ontvangen, los je dit eerst op voordat je verder kijkt naar de Gateway-configuratie.
Stap 2
Controleer DNS en bereikbaarheid:
nslookup demo.voorbeeld.nl
ping demo.voorbeeld.nlAls het (sub)domein/de hostname niet naar het juiste IP-adres verwijst of een foutmelding geeft, controleer dan de DNS-instellingen van je domein en je nameservers.
Stap 3
Controleer de status van de Gateway en HTTPRoute:
kubectl describe gateway demo-gateway -n demo-gateway
kubectl describe httproute demo-route -n demo-gatewayLet op conditions zoals Programmed, Accepted en eventuele error-berichten (bijvoorbeeld een onbekende GatewayClass, foutieve (sub)domein/hostname of ontbrekende listener). Deze velden geven meestal direct aan waar de configuratie wringt.
Stap 4
Controleer of het TLS-certificaat en de Secret aanwezig zijn en ‘Ready’ zijn:
kubectl get certificate -n demo-gateway
kubectl get secret demo-gateway-tls -n demo-gatewayAls de Secret ontbreekt of het certificaat niet Ready is, bekijk je de events van Cert-manager met kubectl describe certificate en los je eventuele HTTP- of DNS-challenge problemen op (bijvoorbeeld verkeerde DNS-records of firewallregels).
In deze handleiding heb je een Kubernetes Gateway opgezet voor een demo-applicatie, HTTP- en HTTPS-listeners geconfigureerd, een TLS-certificaat via Cert-manager gekoppeld en een HTTP->HTTPS redirect toegevoegd. Door deze aanpak centraliseer je je SSL-beveiliging, maak je routingregels beter beheersbaar en ben je klaar om meer geavanceerde features van de Kubernetes Gateway API te gebruiken, zoals meerdere hostnames, mappen per omgeving en extra beveiligingsfilters.