Gateway API & TLS
Purpose: For application developers, shows how to configure HTTPS routing with Gateway listeners, HTTPRoutes, and cert-manager certificates.
Task Summary
This guide covers configuring HTTPS access for your application using Gateway API for routing and cert-manager for automated TLS certificates. The platform provides a shared Gateway; application teams create HTTPRoutes that attach to it.
Prerequisites
- An openCenter cluster with Gateway API CRDs installed
- cert-manager deployed as a platform service
- A shared Gateway resource in
gateway-systemnamespace (managed by the platform team) - DNS configured to point your hostname to the Gateway's external IP
Steps
1. Understand the Gateway Architecture
The platform team manages the Gateway resource. Application teams create HTTPRoutes that reference it:
2. Create an HTTPRoute
Define an HTTPRoute in your application namespace:
# httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app
namespace: my-app
spec:
parentRefs:
- name: platform-gateway
namespace: gateway-system
hostnames:
- "my-app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: my-app
port: 80
The parentRefs field attaches this route to the platform Gateway. The Gateway must have a listener that accepts routes from your namespace (configured by the platform team via allowedRoutes).
3. Request a TLS Certificate (Custom Domain)
If your application uses a hostname outside the platform's wildcard certificate, request a dedicated certificate using cert-manager:
# certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: my-app-tls
namespace: gateway-system
spec:
secretName: my-app-tls-secret
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
dnsNames:
- "my-app.custom-domain.com"
The platform team then references this secret in a Gateway listener:
# Gateway listener addition (managed by platform team)
listeners:
- name: my-app-custom
protocol: HTTPS
port: 443
hostname: "my-app.custom-domain.com"
tls:
mode: Terminate
certificateRefs:
- name: my-app-tls-secret
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-access: "true"
4. Configure Path-Based Routing
For applications with multiple backends behind a single hostname:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app-routes
namespace: my-app
spec:
parentRefs:
- name: platform-gateway
namespace: gateway-system
hostnames:
- "my-app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 8080
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: frontend-service
port: 3000
Rules are evaluated in order. Place more specific paths first.
Verification
Check the HTTPRoute is accepted by the Gateway:
kubectl get httproute -n my-app my-app -o jsonpath='{.status.parents[0].conditions}'
# Look for: type=Accepted, status=True
Test HTTPS connectivity:
curl -v https://my-app.example.com/healthz
# Verify TLS handshake succeeds and returns 200
Check certificate status (if using a custom cert):
kubectl get certificate -n gateway-system my-app-tls
# Expected: READY=True
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
HTTPRoute status shows NotAccepted | Gateway doesn't allow routes from your namespace | Ask platform team to add your namespace label to allowedRoutes |
| TLS handshake fails | Certificate not yet issued or wrong hostname | Check kubectl describe certificate for ACME errors |
| 404 on valid path | Path matching order or missing backendRef | Verify Service name and port match; check path ordering |
| Certificate stuck in "Issuing" | DNS not pointing to Gateway IP or ACME challenge failing | Verify DNS resolution: dig my-app.custom-domain.com |
Further Reading
- Deploying Applications — Full deployment tutorial
- Manifest Structure Reference — HTTPRoute field reference
- Service Mesh — When to use Istio vs. Gateway API