Skip to content

RoutePolicy

The RoutePolicy CRD provides per-route overrides for HTTP traffic behavior, bringing nginx‑ingress annotation parity to the Gateway API model. It is a Gateway API local policy that attaches to HTTPRoute resources via targetRefs, with three‑level namespace → gateway → route inheritance.

apiVersion: gateway.nantian.dev/v1alpha1
kind: RoutePolicy
metadata:
name: large-uploads
namespace: nantian-demo
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: file-upload-route
default:
timeout:
request: 120s
backendRequest: 90s
connect: 30s
nextUpstream: 10s
bodyLimit:
maxRequestBodyBytes: 52428800
requestBodyBufferBytes: 131072
maxRequestHeaderBytes: 65536
proxy:
requestBuffering: true
responseBuffering: false
bufferSize: 4096
bufferCount: 8
connection:
keepaliveRequests: 1000
keepaliveTime: 3600s
keepaliveTimeout: 75s
upstreamKeepalivePoolSize: 320
upstreamKeepaliveIdle: 60s

RoutePolicy uses a three‑level priority system. Higher levels override lower levels:

PrioritytargetRefScope
3 (highest)kind: HTTPRouteApplies to a single HTTPRoute.
2kind: GatewayDefault for all routes attached to that Gateway.
1 (lowest)targetRefs: [] (empty)Default for all routes in the policy’s namespace.

All fields are optional. Unset fields cascade down: if a route‑level policy omits timeout.connect, the gateway‑level value is used. If no policy provides a value, the dataplane global default applies.

When two policies at the same level target the same resource, neither applies (the route falls back to the next level).

The targetRefs field specifies which resources the policy binds to:

FieldDescription
groupAPI group of the target. Must be gateway.networking.k8s.io for Gateway and HTTPRoute targets.
kindGateway for gateway‑level defaults, or HTTPRoute for per‑route overrides.
nameName of the target resource in the same namespace as the policy.

Leave targetRefs empty to create a namespace‑level default. Only one namespace‑level RoutePolicy may exist per namespace.

All fields are optional. Omit a section to let the next inheritance level or the global default apply.

Overrides the dataplane timeout defaults for requests on the targeted routes.

FieldTypeDefaultDescription
requestduration60sMaximum duration for the entire request‑response cycle. Maps to nginx.ingress.kubernetes.io/proxy-read-timeout.
backendRequestduration15sMaximum duration for a single backend request attempt. Maps to nginx.ingress.kubernetes.io/proxy-send-timeout.
connectduration5sMaximum duration to establish a TCP connection to the backend. Maps to nginx.ingress.kubernetes.io/proxy-connect-timeout.
nextUpstreamdurationMaximum duration spent finding a viable upstream during retries. Maps to nginx.ingress.kubernetes.io/proxy-next-upstream-timeout.

Restricts request body and header sizes on a per‑route basis.

FieldTypeDefaultDescription
maxRequestBodyBytesuint6410485760 (10 MiB)Maximum request body size in bytes. Requests exceeding this receive HTTP 413. Maps to nginx.ingress.kubernetes.io/proxy-body-size.
requestBodyBufferBytesuint64131072 (128 KiB)Size of the buffer used to read the request body before writing to a temporary file. Maps to nginx.ingress.kubernetes.io/client-body-buffer-size.
maxRequestHeaderBytesuint6465536 (64 KiB)Maximum combined size of all request headers. Maps to nginx.ingress.kubernetes.io/client-header-buffer-size.

Controls HTTP proxy buffering behavior.

FieldTypeDefaultDescription
requestBufferingbooltrueBuffer the entire client request body before proxying. Maps to nginx.ingress.kubernetes.io/proxy-request-buffering.
responseBufferingbooltrueBuffer the backend response before sending to the client. Maps to nginx.ingress.kubernetes.io/proxy-buffering.
bufferSizeuint644096Size of each response buffer in bytes. Maps to nginx.ingress.kubernetes.io/proxy-buffer-size.
bufferCountuint328Number of response buffers. Maps to nginx.ingress.kubernetes.io/proxy-buffers-number.

Controls keepalive behavior for client‑facing and upstream connections.

FieldTypeDefaultDescription
keepaliveRequestsuint321000Maximum number of requests allowed on a single keepalive connection. Maps to nginx.ingress.kubernetes.io/keepalive-requests.
keepaliveTimeduration3600s (1 h)Maximum lifetime of a keepalive connection.
keepaliveTimeoutduration75sMaximum idle time before closing a keepalive connection. Maps to nginx.ingress.kubernetes.io/keepalive-timeout.
upstreamKeepalivePoolSizeuint32320Maximum number of idle upstream keepalive connections to maintain. Maps to nginx.ingress.kubernetes.io/upstream-keepalive-connections.
upstreamKeepaliveIdleduration60sMaximum idle time before closing an upstream keepalive connection. Maps to nginx.ingress.kubernetes.io/upstream-keepalive-time.

If you are migrating from nginx‑ingress, the following table maps annotations to RoutePolicy fields:

nginx‑ingress annotationRoutePolicy field
nginx.ingress.kubernetes.io/proxy-body-sizedefault.bodyLimit.maxRequestBodyBytes
nginx.ingress.kubernetes.io/client-body-buffer-sizedefault.bodyLimit.requestBodyBufferBytes
nginx.ingress.kubernetes.io/client-header-buffer-sizedefault.bodyLimit.maxRequestHeaderBytes
nginx.ingress.kubernetes.io/proxy-read-timeoutdefault.timeout.request
nginx.ingress.kubernetes.io/proxy-send-timeoutdefault.timeout.backendRequest
nginx.ingress.kubernetes.io/proxy-connect-timeoutdefault.timeout.connect
nginx.ingress.kubernetes.io/proxy-next-upstream-timeoutdefault.timeout.nextUpstream
nginx.ingress.kubernetes.io/proxy-request-bufferingdefault.proxy.requestBuffering
nginx.ingress.kubernetes.io/proxy-bufferingdefault.proxy.responseBuffering
nginx.ingress.kubernetes.io/proxy-buffer-sizedefault.proxy.bufferSize
nginx.ingress.kubernetes.io/proxy-buffers-numberdefault.proxy.bufferCount
nginx.ingress.kubernetes.io/keepalive-requestsdefault.connection.keepaliveRequests
nginx.ingress.kubernetes.io/keepalive-timeoutdefault.connection.keepaliveTimeout
nginx.ingress.kubernetes.io/upstream-keepalive-connectionsdefault.connection.upstreamKeepalivePoolSize
nginx.ingress.kubernetes.io/upstream-keepalive-timedefault.connection.upstreamKeepaliveIdle

Increase the request timeout for a slow backend:

apiVersion: gateway.nantian.dev/v1alpha1
kind: RoutePolicy
metadata:
name: slow-backend-timeout
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: slow-report-route
default:
timeout:
request: 300s

Restrict upload size on a specific route:

apiVersion: gateway.nantian.dev/v1alpha1
kind: RoutePolicy
metadata:
name: upload-limit
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: upload-route
default:
bodyLimit:
maxRequestBodyBytes: 52428800 # 50 MiB

Set default timeout for all routes in a namespace:

apiVersion: gateway.nantian.dev/v1alpha1
kind: RoutePolicy
metadata:
name: ns-defaults
namespace: team-a
spec:
default:
timeout:
request: 60s
connect: 10s
connection:
keepaliveRequests: 500