Proxy UDP traffic by port

Related Documentation
Tags
Related Resources
TL;DR

Create a UDPRoute or UDPIngress resource, which will then be converted in to a Kong Gateway Service and Route.

Prerequisites

If you don’t have a Konnect account, you can get started quickly with our onboarding wizard.

  1. The following Konnect items are required to complete this tutorial:
    • Personal access token (PAT): Create a new personal access token by opening the Konnect PAT page and selecting Generate Token.
  2. Set the personal access token as an environment variable:

    export KONNECT_TOKEN='YOUR KONNECT TOKEN'
    
  1. Install the experimental Gateway API CRDs before installing Kong Ingress Controller:

    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/experimental-install.yaml
    
  2. Create a Gateway and GatewayClass instance to use.

echo "
apiVersion: v1
kind: Namespace
metadata:
  name: kong
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: kong
  annotations:
    konghq.com/gatewayclass-unmanaged: 'true'
spec:
  controllerName: konghq.com/kic-gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: kong
spec:
  gatewayClassName: kong
  listeners:
  - name: proxy
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
         from: All
" | kubectl apply -n kong -f -

Use the Konnect API to create a new CLUSTER_TYPE_K8S_INGRESS_CONTROLLER Control Plane:

CONTROL_PLANE_DETAILS=$(curl -X POST "https://us.api.konghq.com/v2/control-planes" \
     -H "Authorization: Bearer $KONNECT_TOKEN" \
     --json '{
       "name": "My KIC CP",
       "cluster_type": "CLUSTER_TYPE_K8S_INGRESS_CONTROLLER"
     }')

We’ll need the id and telemetry_endpoint for the values.yaml file later. Save them as environment variables:

CONTROL_PLANE_ID=$(echo $CONTROL_PLANE_DETAILS | jq -r .id)
CONTROL_PLANE_TELEMETRY=$(echo $CONTROL_PLANE_DETAILS | jq -r '.config.telemetry_endpoint | sub("https://";"")')

Create mTLS certificates

Kong Ingress Controller talks to Konnect over a connected secured with TLS certificates.

Generate a new certificate using openssl:

openssl req -new -x509 -nodes -newkey rsa:2048 -subj "/CN=kongdp/C=US" -keyout ./tls.key -out ./tls.crt

The certificate needs to be a single line string to send it to the Konnect API with curl. Use awk to format the certificate:

export CERT=$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' tls.crt);

Next, upload the certificate to Konnect:

curl -X POST "https://us.api.konghq.com/v2/control-planes/$CONTROL_PLANE_ID/dp-client-certificates" \
     -H "Authorization: Bearer $KONNECT_TOKEN" \
     --json '{
       "cert": "'$CERT'"
     }'

Finally, store the certificate in a Kubernetes secret so that Kong Ingress Controller can read it:

kubectl create namespace kong -o yaml --dry-run=client | kubectl apply -f -
kubectl create secret tls konnect-client-tls -n kong --cert=./tls.crt --key=./tls.key
  1. Add the Kong Helm charts:

    helm repo add kong https://charts.konghq.com
    helm repo update
    
  2. Install Kong Ingress Controller using Helm:

    helm install kong kong/ingress -n kong --create-namespace --set controller.ingressController.env.feature_gates="GatewayAlpha=true"
    
  3. Set $PROXY_IP as an environment variable for future commands:

    export PROXY_IP=$(kubectl get svc --namespace kong kong-gateway-proxy -o jsonpath='{range .status.loadBalancer.ingress[0]}{@.ip}{@.hostname}{end}')
    echo $PROXY_IP
    

This how-to requires some Kubernetes services to be available in your cluster. These services will be used by the resources created in this how-to.

kubectl apply -f https://developer.konghq.com/manifests/kic/udp-service.yaml -n kong

Add UDP listens

Kong Gateway doesn’t include any UDP listen configuration by default. To expose UDP listens, update the Deployment’s environment variables and port configuration.

  1. Set the KONG_STREAM_LISTEN environment variable and expose port 9999 in the Deployment:

     kubectl patch deploy -n kong kong-gateway --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"
                   }
                 ]
               }
             ]
           }
         }
       }
     }'
    
  2. Update the proxy Service to indicate the new ports:

    kubectl patch service -n kong kong-gateway-proxy --patch '{
      "spec": {
        "ports": [
          {
            "name": "stream9999",
            "port": 9999,
            "protocol": "UDP",
            "targetPort": 9999
          }
        ]
      }
    }'
    

Route UDP traffic

To expose the service to the outside world, create a UDPRoute resource for Gateway APIs or a UDPIngress resource for Ingress.

This configuration routes traffic to UDP port 9999 on the Kong Gateway proxy to port 9999 on the TFTP test server.

Validate your configuration

Send a TFTP request through the proxy:

curl -s tftp://$PROXY_IP:9999/hello

The results should look like this:

Hostname: tftp-5849bfd46f-nqk9x

Request Information:
  client_address=10.244.0.1
  client_port=39364
  real path=/hello
  request_scheme=tftp

Cleanup

kubectl delete -n kong -f https://developer.konghq.com/manifests/kic/udp-service.yaml
helm uninstall kong -n kong
Something wrong?

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!