Proxy UDP Traffic by Port
Route UDP traffic to an echo Service based on the incoming gateway port using either a Gateway API UDPRoute or an APISIX CRD stream route.
Prerequisite
- Complete Set Up Ingress Controller and Gateway.
Start an Example Upstream Service
Create a Kubernetes manifest for a UDP echo server that listens on port 9000:
apiVersion: apps/v1
kind: Deployment
metadata:
name: udp-echo
namespace: aic
spec:
replicas: 1
selector:
matchLabels:
app: udp-echo
template:
metadata:
labels:
app: udp-echo
spec:
containers:
- name: udp-echo
image: python:3-alpine
command: ["python", "-u", "-c"]
args:
- |
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 9000))
print("UDP echo server listening on port 9000")
while True:
data, addr = sock.recvfrom(1024)
sock.sendto(data, addr)
ports:
- containerPort: 9000
protocol: UDP
---
apiVersion: v1
kind: Service
metadata:
name: udp-echo
namespace: aic
spec:
selector:
app: udp-echo
ports:
- name: udp
port: 9000
targetPort: 9000
protocol: UDP
Apply the configuration to your cluster:
kubectl apply -f udp-echo.yaml
Enable Gateway Stream Proxy
Upgrade your gateway to enable stream mode and set UDP listening port 9300:
- APISIX Gateway
- API7 Gateway
helm upgrade -n aic apisix apisix/apisix \
--set ... \ # add other parameters
--set "service.stream.enabled=true" \
--set "service.stream.udp[0]=9300"
helm upgrade -n aic api7-ee-3-gateway api7/gateway \
--set ... \ # add other parameters
--set "gateway.stream.enabled=true" \
--set "gateway.stream.only=false" \
--set "gateway.stream.udp[0]=9300"
Configure UDP Routing
In this section, you will configure a route that listens for UDP traffic on port 9300.
- Gateway API
- APISIX CRD
Update your Gateway manifest file to define a listener for UDP traffic:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: aic
name: apisix
spec:
gatewayClassName: apisix
listeners:
- name: http
protocol: HTTP
port: 80
- name: udp
protocol: UDP
port: 9300
allowedRoutes:
kinds:
- kind: UDPRoute
infrastructure:
parametersRef:
group: apisix.apache.org
kind: GatewayProxy
name: apisix-config
Create a Kubernetes manifest for a UDPRoute:
apiVersion: gateway.networking.k8s.io/v1
kind: UDPRoute
metadata:
name: stream-route-udp
namespace: aic
spec:
parentRefs:
- name: apisix
sectionName: udp
rules:
- backendRefs:
- name: udp-echo
port: 9000
When listener_port_match_mode is explicit or auto, the sectionName: udp reference adds a server_port match for 9300. The Gateway listener port must equal the physical APISIX stream listener port. The default off mode does not add this match.
Apply the configuration to your cluster:
kubectl apply -f gateway.yaml -f udp-route.yaml
Create a Kubernetes manifest file for a stream route:
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: stream-route-udp
namespace: aic
spec:
ingressClassName: apisix
stream:
- name: stream-route-udp
protocol: UDP
match:
ingressPort: 9300
backend:
serviceName: udp-echo
servicePort: 9000
Apply the configuration to your cluster:
kubectl apply -f udp-route.yaml
Set the Upstream Transport
Set the backend scheme to udp. L4 schemes apply only to stream routes.
- Gateway API
- APISIX CRD
Attach a BackendTrafficPolicy to the backend Service:
apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: udp-echo-transport
namespace: aic
spec:
targetRefs:
- group: ""
kind: Service
name: udp-echo
sectionName: udp
scheme: udp
Apply the policy:
kubectl apply -f udp-upstream-policy.yaml
Create an ApisixUpstream with the same name as the backend Service:
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
name: udp-echo
namespace: aic
spec:
ingressClassName: apisix
scheme: udp
Apply the upstream configuration:
kubectl apply -f udp-upstream.yaml
To attach stream plugins to the UDPRoute, see Apply Plugins to L4 Routes.
Verify
kubectl port-forward supports only TCP and cannot verify UDP proxying. Run a temporary pod inside the cluster to send UDP packets to the gateway:
kubectl run -it --rm test-udp-proxy --image=busybox --namespace=aic -- /bin/sh
Once inside the pod, run the following command to send a UDP packet to the gateway:
echo "UDP Testing" | nc -u -w1 <gateway-service-name> 9300
You should see the message UDP Testing echoed back.