Exposing a UDP Service
Overview
This guide walks through deploying a simple Service that listens for UDP datagrams, and exposes this service outside of the cluster using Kong Gateway.
For this example, you will:
- Deploy a UDP test application.
- Route UDP traffic to it using UDPIngress or UDPRoute.
Installation
Please follow the deployment documentation to install the Kubernetes Ingress Controller onto your Kubernetes cluster.
Installing the Gateway APIs
If you wish to use the Gateway APIs examples, follow the supplemental Gateway APIs installation instructions.
Testing connectivity to Kong Gateway
This guide assumes that PROXY_IP
environment variable is
set to contain the IP address or URL pointing to Kong Gateway.
If you’ve not done so, follow one of the
deployment guides to configure this environment variable.
If everything is setup correctly, making a request to Kong Gateway should return back
a HTTP 404 Not Found
status code:
curl -i $PROXY_IP
Response:
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-Length: 48
X-Kong-Response-Latency: 0
Server: kong/3.0.0
{"message":"no Route matched with those values"}
This is expected since Kong Gateway doesn’t know how to proxy the request yet.
Create a configuration group
Ingress and Gateway APIs controllers need a configuration that indicates which set of routing configuration they should recognize. This allows multiple controllers to coexist in the same cluster. Before creating individual routes, you need to create a class configuration to associate routes with:
Kubernetes Ingress Controller recognizes the kong
IngressClass and
konghq.com/kic-gateway-controller
GatewayClass
by default. Setting the CONTROLLER_INGRESS_CLASS
or
CONTROLLER_GATEWAY_API_CONTROLLER_NAME
environment variable to
another value overrides these defaults.
Create a namespace
First, create a namespace:
Other examples in this guide will use this namespace. When you’ve completed
this guide, kubectl delete namespace udp-example
will clean those resources
up.
Adding UDP listens
Kong Gateway does not include any UDP listen configuration by default. To expose UDP listens, update the Deployment’s environment variables and port configuration:
kubectl patch deploy -n kong ingress-kong --patch '{
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "proxy",
"env": [
{
"name": "KONG_STREAM_LISTEN",
"value": "0.0.0.0:9999 udp"
}
],
"ports": [
{
"containerPort": 9999,
"name": "stream9999",
"protocol": "UDP"
}
]
}
]
}
}
}
}'
Response:
deployment.extensions/ingress-kong patched
Add a UDP proxy Service
LoadBalancer Services only support a single transport protocol in Kubernetes versions prior to 1.26. To direct UDP traffic to the proxy Service, you’ll need to create a second Service:
echo "apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: udp
service.beta.kubernetes.io/aws-load-balancer-type: nlb
name: kong-udp-proxy
namespace: kong
spec:
ports:
- name: stream9999
port: 9999
protocol: UDP
targetPort: 9999
selector:
app: ingress-kong
type: LoadBalancer
" | kubectl apply -f -
Response:
service/kong-udp-proxy created
Note that this Service is typically added via the Kong Helm chart’s udpProxy
configuration. This guide creates it manually to demonstrate the resources the
chart normally manages for you and for compatibility with non-Helm installs.
Update the Gateway
If you are using Gateway APIs (UDPRoute) option, your Gateway needs additional
configuration under listeners
. If you are using UDPIngress, skip this step.
kubectl patch --type=json gateway kong -p='[
{
"op":"add",
"path":"/spec/listeners/-",
"value":{
"name":"stream9999",
"port":9999,
"protocol":"UDP",
"allowedRoutes": {
"namespaces": {
"from": "All"
}
}
}
}
]'
Response:
gateway.gateway.networking.k8s.io/kong patched
Deploy a UDP test application
Create a test application Deployment and an associated Service:
echo "---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tftp
namespace: udp-example
labels:
app: tftp
spec:
replicas: 1
selector:
matchLabels:
app: tftp
template:
metadata:
labels:
app: tftp
spec:
containers:
- name: tftp
image: cilium/echoserver-udp:latest
args:
- --listen
- :9999
ports:
- containerPort: 9999
---
apiVersion: v1
kind: Service
metadata:
name: tftp
namespace: udp-example
spec:
ports:
- port: 9999
name: tftp
protocol: UDP
targetPort: 9999
selector:
app: tftp
type: ClusterIP
" | kubectl apply -f -
Response:
deployment.apps/tftp created
service/tftp created
echoserver-udp is a simple test server that accepts UDP TFTP requests and returns basic request information. As curl supports TFTP, it is a convenient option for testing UDP routing.
Route UDP traffic
Now that Kong Gateway is listening on 9999
and the test application
is running, you can create UDP routing configuration that proxies traffic to
the application:
This configuration routes traffic to UDP port 9999
on the
Kong Gateway proxy to port 9999
on the TFTP test server.
Test the configuration
First, retrieve the external IP address of the UDP proxy Service you created previously:
export KONG_UDP_ENDPOINT="$(kubectl -n kong get service kong-udp-proxy \
-o=go-template='{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}')"
After, use curl to send a TFTP request through the proxy: