Route
A Route defines how the gateway forwards traffic to a backend. Each route attaches to one or more Gateway CRs and may apply any number of Middleware CRs.
- API group:
gateway.jkaninda.dev - Version:
v1alpha1 - Kind:
Route
When the goma-k8s-provider sidecar is enabled (default), changes to Route resources are hot-reloaded into the gateway without a pod restart.
Minimal example
A single backend, host-based routing, attached to a Gateway named gateway:
apiVersion: gateway.jkaninda.dev/v1alpha1
kind: Route
metadata:
name: api
namespace: default
spec:
gateways:
- gateway
path: /
hosts:
- api.example.com
target: http://api-service.default.svc.cluster.local:8080
methods:
- GET
- POST
Load-balanced backends
Use backends instead of target to distribute traffic across multiple endpoints. Active health checks remove unhealthy backends from rotation.
apiVersion: gateway.jkaninda.dev/v1alpha1
kind: Route
metadata:
name: api-lb
spec:
gateways:
- gateway
path: /api
rewrite: /
hosts:
- api.example.com
backends:
# 80/20 weighted split between v1 and v2.
- endpoint: http://api-v1.default.svc.cluster.local:8080
weight: 80
- endpoint: http://api-v2.default.svc.cluster.local:8080
weight: 20
# Canary backend — only receives traffic carrying X-Canary: true.
# `exclusive: true` keeps it out of the general LB pool.
- endpoint: http://api-canary.default.svc.cluster.local:8080
exclusive: true
match:
- source: header
name: X-Canary
operator: equals
value: "true"
healthCheck:
path: /healthz
interval: 15s
timeout: 3s
healthyStatuses: [200, 204]
Backend matching
match rules pin requests to a specific backend based on request attributes. Sources: header, cookie, query, ip. Operators: equals, not_equals, contains, not_contains, starts_with, ends_with, regex, in.
When exclusive: true, the backend only receives matched traffic. When false (default), matched traffic is pinned but the backend still participates in normal load balancing.
Per-route TLS
spec.tls controls the certificate served for the route's hosts. It mirrors the gateway's route tls block: secretName supplies the certificate (rendered as tls.certificate), and provider selects automatic issuance (rendered as tls.provider).
Serve a custom certificate from a kubernetes.io/tls Secret in the Route's namespace:
spec:
hosts:
- api.example.com
tls:
secretName: api-example-com-tls
When the K8s provider sidecar is enabled, the cert/key are written to disk and hot-reloaded — no pod restart.
For ACME-managed certificates, configure certManager on the parent Gateway. With several named providers, pick one per route, or opt out with none (for example when TLS is terminated upstream):
spec:
hosts:
- internal.example.com
tls:
provider: none
tls.provider requires an operator release newer than v0.2.0.
Backend TLS / mTLS
Control how the gateway connects to backend servers (separate from the cert it serves to clients):
spec:
security:
forwardHostHeaders: true
enableExploitProtection: true # SQLi / XSS heuristics
tls:
insecureSkipVerify: false
rootCAsSecret: backend-ca # Secret with custom CA bundle
clientCertSecret: backend-client # kubernetes.io/tls secret for mTLS
The gateway reads the CA bundle from the ca.crt key of rootCAsSecret, and the client pair from tls.crt / tls.key of clientCertSecret.
The current operator renders these paths under /etc/goma/certs/<secret>/ but does not yet mount rootCAsSecret or clientCertSecret into the gateway pod.
Maintenance mode
Return a static response instead of proxying to the backend:
spec:
maintenance:
enabled: true
status: 503
body: |
{"error":"maintenance","message":"Back at 14:00 UTC."}
The operator renders these as status and body, while Goma Gateway v1.0 reads statusCode and message. Until this is aligned, the gateway ignores both and answers with its default 503 Service temporarily unavailable.
Attaching middlewares
List Middleware CR names by metadata.name. They are applied in order:
spec:
middlewares:
- api-jwt
- api-rate-limit
See the Middleware documentation for the supported types and their configuration.
Spec reference
| Field | Type | Description |
|---|---|---|
gateways | []string | Required. Names of Gateway CRs (same namespace) this route attaches to. |
path | string | Required. URL path matched by this route. |
rewrite | string | Path rewrite (e.g. /api → /). |
target | string | Single backend URL (http or https). Set either target or backends, not both. |
methods | []string | Allowed HTTP methods (e.g. GET, POST). Empty = all. |
enabled | bool | Whether the route is active. Default: true. |
priority | int | Match order — higher matches first. |
hosts | []string | Hostnames for host-based routing. |
backends | []object | Multiple backends for load balancing (see below). |
healthCheck | object | Active backend health check (see below). |
security | object | Per-route security settings. |
middlewares | []string | Middleware CR names to apply. |
disableMetrics | bool | Suppress Prometheus per-route metrics for this route. |
tls.secretName | string | kubernetes.io/tls Secret served for the route's hosts. |
tls.provider | string | Certificate provider from the Gateway's certManager.providers, or none to opt out of automatic issuance. Empty uses defaultProvider. |
maintenance | object | Maintenance mode: enabled, status (default 503), body (see above). |
spec.backends[]
| Field | Type | Description |
|---|---|---|
endpoint | string | Backend URL. |
weight | int | Load-balancing weight. |
exclusive | bool | When true, only matched requests reach this backend. |
match[].source | enum | header, cookie, query, ip. |
match[].name | string | Header / cookie / query parameter name. |
match[].operator | enum | equals, not_equals, contains, not_contains, starts_with, ends_with, regex, in. |
match[].value | string | Comparison value (comma-separated for in). |
spec.healthCheck
| Field | Type | Default | Description |
|---|---|---|---|
path | string | — | Required when healthCheck is set. Health check path. |
interval | string | 30s | Check interval. |
timeout | string | 5s | Per-check timeout. |
healthyStatuses | []int | — | HTTP statuses considered healthy. |
spec.security
| Field | Type | Default | Description |
|---|---|---|---|
forwardHostHeaders | bool | true | Forward X-Forwarded-Host and related headers. |
enableExploitProtection | bool | false | Block common SQLi / XSS patterns. |
tls.insecureSkipVerify | bool | false | Skip backend TLS verification (not recommended). |
tls.rootCAsSecret | string | — | Secret with the CA bundle (key ca.crt) for backend TLS. |
tls.clientCertSecret | string | — | kubernetes.io/tls Secret for backend mTLS. |
Status
kubectl get routes
NAME GATEWAYS PATH TARGET READY AGE
api [gateway] / http://api.default.svc.cluster.local true 2m
Ready: true means the route is valid and synced into the parent Gateway's configuration.