|
| 1 | +# GEP-2645: UDPRoute |
| 2 | + |
| 3 | +- Issue: [#2645](https://github.com/kubernetes-sigs/gateway-api/issues/2645) |
| 4 | +- Status: Provisional |
| 5 | + |
| 6 | +(See definitions in [GEP States](../overview.md#gep-states).) |
| 7 | + |
| 8 | +## TLDR |
| 9 | + |
| 10 | +Gateway API needs a first-class Route type for UDP because a meaningful class of Kubernetes workloads cannot be represented by the standard Gateway API routing model without it. |
| 11 | +Without UDPRoute, these UDP based workloads must either fall back to Service-based exposure or rely on implementation-specific APIs, |
| 12 | +which prevents Gateway API from serving as a common and portable configuration model for them. |
| 13 | +UDPRoute standardizes the minimal interoperable API surface for exposing UDP workloads through Gateway API. |
| 14 | + |
| 15 | +This GEP retroactively documents the rationale, scope, and design constraints of the existing UDPRoute resource. |
| 16 | + |
| 17 | +## Goals |
| 18 | + |
| 19 | +- Define a standard Gateway API Route resource that matches UDP traffic based off the inbound port and forwards it to a UDP based backend. |
| 20 | +- Standardize the minimal interoperable forwarding model for UDP traffic: listener attachment and backend forwarding. |
| 21 | +- Support forwarding to one or more backends, including weighted backend selection where implemented. |
| 22 | +- Provide a stable baseline for evaluating future UDPRoute enhancements. |
| 23 | + |
| 24 | +## Non-Goals |
| 25 | + |
| 26 | +- Define rich UDP-specific matching semantics such as address matching or payload inspection. |
| 27 | +- Require stateful UDP session tracking or connection management semantics. Implementations are expected to document how they implement such semantics. |
| 28 | +- Define DTLS termination behavior at the Gateway. |
| 29 | +- Define HTTP/3 or QUIC-specific behavior. |
| 30 | + |
| 31 | +## Introduction |
| 32 | + |
| 33 | +This GEP proposes a standard resource for UDP traffic routing. Presently, the Gateway API lacks a way to describe how |
| 34 | +to route UDP traffic meaning that it's hard (or impossible) to natively define such applications using the Gateway API: |
| 35 | + |
| 36 | +- DNS (Domain Name System) |
| 37 | +- VoIP and real-time communications |
| 38 | +- Gaming protocols |
| 39 | +- Streaming media (RTP/RTCP) |
| 40 | +- IoT and telemetry protocols |
| 41 | + |
| 42 | +Without UDPRoute, users must rely on implementation-specific extensions or fall back to traditional Kubernetes Service resources. |
| 43 | +UDPRoute allows for consistent network configuration management using the Gateway API. Another benefit is that |
| 44 | +organizations may consolidate their load balancing infrastructure under one Gateway, instead of having one physical |
| 45 | +load balancer per Service. |
| 46 | + |
| 47 | +## API |
| 48 | + |
| 49 | +### UDPRoute Resource |
| 50 | + |
| 51 | +These resources follow the same pattern as other route types. Notably, as UDP doesn't have traffic control options, |
| 52 | +the route rule only includes backends to forward UDP traffic to. |
| 53 | + |
| 54 | +```go |
| 55 | +// UDPRoute provides a way to route UDP traffic. When combined with a Gateway |
| 56 | +// listener, it can be used to forward traffic on the port specified by the |
| 57 | +// listener to a set of backends specified by the UDPRoute. |
| 58 | +type UDPRoute struct { |
| 59 | + metav1.TypeMeta `json:",inline"` |
| 60 | + // +optional |
| 61 | + metav1.ObjectMeta `json:"metadata,omitempty"` |
| 62 | + |
| 63 | + // Spec defines the desired state of UDPRoute. |
| 64 | + // +required |
| 65 | + Spec UDPRouteSpec `json:"spec"` |
| 66 | + |
| 67 | + // Status defines the current state of UDPRoute. |
| 68 | + // +optional |
| 69 | + Status UDPRouteStatus `json:"status,omitempty"` |
| 70 | +} |
| 71 | + |
| 72 | +// UDPRouteSpec defines the desired state of UDPRoute. |
| 73 | +type UDPRouteSpec struct { |
| 74 | + CommonRouteSpec `json:",inline"` |
| 75 | + |
| 76 | + // Rules are a list of UDP matchers and actions. |
| 77 | + // |
| 78 | + // +required |
| 79 | + // +listType=atomic |
| 80 | + // +kubebuilder:validation:MinItems=1 |
| 81 | + // +kubebuilder:validation:MaxItems=1 |
| 82 | + // <gateway:experimental:validation:XValidation:message="Rule name must be unique within the route",rule="self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))"> |
| 83 | + Rules []UDPRouteRule `json:"rules"` |
| 84 | +} |
| 85 | + |
| 86 | +// UDPRouteRule is the configuration for a given rule. |
| 87 | +type UDPRouteRule struct { |
| 88 | + // Name is the name of the route rule. This name MUST be unique within a Route if it is set. |
| 89 | + // |
| 90 | + // Support: Extended |
| 91 | + // +optional |
| 92 | + Name *SectionName `json:"name,omitempty"` |
| 93 | + |
| 94 | + // BackendRefs defines the backend(s) where matching requests should be |
| 95 | + // sent. If unspecified or invalid (refers to a nonexistent resource or a |
| 96 | + // Service with no endpoints), the underlying implementation MUST actively |
| 97 | + // reject connection attempts to this backend. Packet drops must |
| 98 | + // respect weight; if an invalid backend is requested to have 80% of |
| 99 | + // the packets, then 80% of packets must be dropped instead. |
| 100 | + // |
| 101 | + // Support: Core for Kubernetes Service |
| 102 | + // |
| 103 | + // Support: Extended for Kubernetes ServiceImport |
| 104 | + // |
| 105 | + // Support: Implementation-specific for any other resource |
| 106 | + // |
| 107 | + // Support for weight: Extended |
| 108 | + // |
| 109 | + // +required |
| 110 | + // +listType=atomic |
| 111 | + // +kubebuilder:validation:MinItems=1 |
| 112 | + // +kubebuilder:validation:MaxItems=16 |
| 113 | + BackendRefs []BackendRef `json:"backendRefs,omitempty"` |
| 114 | +} |
| 115 | + |
| 116 | +// UDPRouteStatus defines the observed state of UDPRoute. |
| 117 | +type UDPRouteStatus struct { |
| 118 | + RouteStatus `json:",inline"` |
| 119 | +} |
| 120 | +``` |
| 121 | + |
| 122 | +### Example Usage |
| 123 | + |
| 124 | +#### Basic UDP Service Routing (DNS) |
| 125 | + |
| 126 | +```yaml |
| 127 | +apiVersion: gateway.networking.k8s.io/v1 |
| 128 | +kind: Gateway |
| 129 | +metadata: |
| 130 | + name: udp-gateway |
| 131 | + namespace: gateway-conformance-infra |
| 132 | +spec: |
| 133 | + gatewayClassName: example-gateway-class |
| 134 | + listeners: |
| 135 | + - name: coredns |
| 136 | + protocol: UDP |
| 137 | + port: 5300 |
| 138 | + allowedRoutes: |
| 139 | + kinds: |
| 140 | + - kind: UDPRoute |
| 141 | +--- |
| 142 | +apiVersion: gateway.networking.k8s.io/v1alpha2 |
| 143 | +kind: UDPRoute |
| 144 | +metadata: |
| 145 | + name: udp-coredns |
| 146 | + namespace: gateway-conformance-infra |
| 147 | +spec: |
| 148 | + parentRefs: |
| 149 | + - name: udp-gateway |
| 150 | + sectionName: coredns |
| 151 | + rules: |
| 152 | + - backendRefs: |
| 153 | + - name: coredns |
| 154 | + port: 53 |
| 155 | +``` |
| 156 | +
|
| 157 | +#### Multiple Backend Distribution |
| 158 | +
|
| 159 | +```yaml |
| 160 | +apiVersion: gateway.networking.k8s.io/v1alpha2 |
| 161 | +kind: UDPRoute |
| 162 | +metadata: |
| 163 | + name: game-server-route |
| 164 | +spec: |
| 165 | + parentRefs: |
| 166 | + - name: udp-gateway |
| 167 | + sectionName: gaming |
| 168 | + rules: |
| 169 | + - backendRefs: |
| 170 | + - name: game-server-1 |
| 171 | + port: 7777 |
| 172 | + weight: 70 |
| 173 | + - name: game-server-2 |
| 174 | + port: 7777 |
| 175 | + weight: 30 |
| 176 | +``` |
| 177 | +
|
| 178 | +### Mixing Protocols |
| 179 | +
|
| 180 | +A common use-case is to expose the same service over UDP and TCP. An Implementation MAY listen for both UDP and TCP traffic |
| 181 | +utilizing the same Listener port. In this example, all UDP traffic MUST be routed to the UDP route and all TCP traffic |
| 182 | +must be routed to the TCP route. |
| 183 | +
|
| 184 | +```yaml |
| 185 | +apiVersion: gateway.networking.k8s.io/v1 |
| 186 | +kind: Gateway |
| 187 | +metadata: |
| 188 | + name: dns-gateway |
| 189 | + namespace: default |
| 190 | +spec: |
| 191 | + gatewayClassName: example-gatewayclass |
| 192 | + listeners: |
| 193 | + - name: dns-tcp |
| 194 | + protocol: TCP |
| 195 | + port: 53 |
| 196 | + allowedRoutes: |
| 197 | + kinds: |
| 198 | + - kind: TCPRoute |
| 199 | + group: gateway.networking.k8s.io |
| 200 | + |
| 201 | + - name: dns-udp |
| 202 | + protocol: UDP |
| 203 | + port: 53 |
| 204 | + allowedRoutes: |
| 205 | + kinds: |
| 206 | + - kind: UDPRoute |
| 207 | + group: gateway.networking.k8s.io |
| 208 | +--- |
| 209 | +apiVersion: gateway.networking.k8s.io/v1alpha2 |
| 210 | +kind: TCPRoute |
| 211 | +metadata: |
| 212 | + name: dns-tcp-route |
| 213 | + namespace: default |
| 214 | +spec: |
| 215 | + parentRefs: |
| 216 | + - name: dns-gateway |
| 217 | + sectionName: dns-tcp |
| 218 | + rules: |
| 219 | + - backendRefs: |
| 220 | + - name: dns-tcp-service |
| 221 | + port: 53 |
| 222 | +--- |
| 223 | +apiVersion: gateway.networking.k8s.io/v1alpha2 |
| 224 | +kind: UDPRoute |
| 225 | +metadata: |
| 226 | + name: dns-udp-route |
| 227 | + namespace: default |
| 228 | +spec: |
| 229 | + parentRefs: |
| 230 | + - name: dns-gateway |
| 231 | + sectionName: dns-udp |
| 232 | + rules: |
| 233 | + - backendRefs: |
| 234 | + - name: dns-udp-service |
| 235 | + port: 53 |
| 236 | +``` |
| 237 | +
|
| 238 | +## Conformance |
| 239 | +
|
| 240 | +UDPRoute will be part of the Gateway API conformance suite with the following requirements: |
| 241 | +
|
| 242 | +- Implementations MUST support routing UDP traffic to Kubernetes Service backends |
| 243 | +- Implementations MUST respect backend weights for traffic distribution |
| 244 | +- Implementations MUST properly handle invalid backend references |
| 245 | +- Implementations MUST update route status conditions appropriately |
| 246 | +
|
| 247 | +Conformance Level: **Core** |
| 248 | +
|
| 249 | +## References |
| 250 | +
|
| 251 | +- [TCPRoute Specification](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute) |
| 252 | +- [GEP-735: TCP and UDP addresses matching](../gep-735/index.md) (Declined, but relevant context) |
| 253 | +- [Gateway API Use Cases](https://gateway-api.sigs.k8s.io/concepts/use-cases/) |
0 commit comments