You are browsing documentation for an outdated version. See the latest documentation here.
UDPIngress with Kong Gateway
This guide walks you through deploying a simple Service that listens for UDP datagrams, and exposes this service outside of the cluster using Kong Gateway.
Overview
Some of the most common UDP-based services available on the internet are DNS servers. These servers are an important part of the infrastructure of the internet, and are also present by default in Kubernetes clusters to allow Pods within the cluster to look up other pods’ IP addresses by name.
For this example, you will:
- Deploy your own CoreDNS server, which is the default DNS server Kubernetes uses for internal DNS
- Deploy a CoreDNS
Pod
andService
- Route UDP traffic to it using
UDPIngress
This guide assumes that you’ve deployed the Kong Ingress Controller (KIC) using the Helm Chart. If you have deployed the KIC in a different way, you may need to make some manual adjustments to some of the provided instructions.
Installation
Follow the deployment documentation to install the Kong Ingress Controller on your Kubernetes cluster.
Note: This feature is compatible with:
- Kong Gateway versions 2.0.0 and above.
- Kong Ingress Controller versions 2.0.0 and above.
Create a namespace
First, create a namespace for testing DNS services and UDPIngress
.
You’ll be using this namespace in the upcoming sections, and when you’re done testing you can delete it.
Deploy CoreDNS
For this example, deploy a default CoreDNS server that only serves up DNS requests.
First, you need to configure CoreDNS with a Core File.
Save the following ConfigMap as corefile.yaml
:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: udpingress-example
data:
Corefile: |-
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
This simple configuration tells our CoreDNS pods to forward all DNS requests to nameservers present in /etc/resolv.conf
.
By default, /etc/resolve.conf
points to the standard kube-dns service provided by the cluster.
Next, apply the corefile.yaml
:
$ kubectl apply -f corefile.yaml
Now the cluster is ready for the Deployment manifest.
Save the following file as coredns-deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
namespace: udpingress-example
labels:
app: coredns
spec:
replicas: 1
selector:
matchLabels:
app: coredns
template:
metadata:
labels:
app: coredns
spec:
containers:
- args:
- -conf
- /etc/coredns/Corefile
image: coredns/coredns
imagePullPolicy: IfNotPresent
name: coredns
ports:
- containerPort: 53
protocol: UDP
volumeMounts:
- mountPath: /etc/coredns
name: config-volume
volumes:
- configMap:
defaultMode: 420
items:
- key: Corefile
path: Corefile
name: coredns
name: config-volume
Note that this Deployment
mounts the corefile
configuration data
we created above into the pods so that CoreDNS can load them.
Apply the Deployment
configuration file:
$ kubectl apply -f coredns-deployment.yaml
Watch the pods with kubectl -n udpingress-example get pods
. Once they are
running, you can move on to the next sections: exposing the pods through
Service
and UDPIngress
.
Expose CoreDNS through a Service
A Kubernetes Service is a fundamental network abstraction layer
that allows you to load-balance traffic to pods in the cluster. Services
are
ultimately the DNS names that the Kong Gateway will be routing our UDP traffic to.
The following manifest exposes the CoreDNS Deployment from the previous section via a service.
Save this manifest as coredns-service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: coredns
namespace: udpingress-example
spec:
ports:
- port: 53
protocol: UDP
targetPort: 53
selector:
app: coredns
type: ClusterIP
This configuration uses UDP port 53, which is the default port for DNS.
Apply the manifest:
$ kubectl apply -f coredns-service.yaml
Now that you have a Service
to expose the pods, you can expose this
DNS server outside of the cluster using Kong’s UDPIngress
resource.
Exposing UDP Ports on Kong
The Kong Ingress Controller (KIC) doesn’t have a
mechanism to automatically enable new UDP ports for exposing your
Kubernetes UDP Services
, so you need to explicitly configure Kong Gateway to expose
these ports prior to deploying any UDPIngress
resources.
If you’re maintaining a values.yaml
configuration for your Helm deployment of Kong Gateway,
add a section under udpProxy
to enable the new UDP listener:
udpProxy:
enabled: true
type: LoadBalancer
stream:
- containerPort: 9999
servicePort: 9999
protocol: UDP
Once you’ve made the necessary configurations you can apply your changes:
$ helm upgrade --namespace {NAMESPACE} --version {CHART_VERSION} -f values.yaml {RELEASE_NAME} kong/kong
Replace {NAMESPACE}
, {CHART_VERSION}
and {RELEASE_NAME}
with the values you deployed Kong Gateway with.
Alternatively, if you are using command line flags to deploy and manage Kong Gateway, the same configuration can be achieved with flags:
$ helm upgrade --namespace {NAMESPACE} --version {CHART_VERSION} {RELEASE_NAME} kong/kong \
--set "udpProxy.enabled=true" \
--set "udpProxy.type=LoadBalancer" \
--set "udpProxy.stream[0].containerPort=9999"
--set "udpProxy.stream[0].servicePort=9999"
--set "udpProxy.stream[0].protocol=UDP"
Watch the services using kubectl get services
and wait for the LoadBalancer
service to be ready for the Gateway.
Once the service up, Kong Gateway is ready to serve UDP traffic on the external port 9999
using UDPIngress
resources.
Deploying UDPIngress
Now that Kong Gateway is listening on 9999
, you can create a UDPIngress
resource which will attach
the CoreDNS service to that port so you can make DNS requests to it from outside the cluster.
Save the following file as coredns-udpingress.yaml
:
apiVersion: configuration.konghq.com/v1beta1
kind: UDPIngress
metadata:
name: minudp
namespace: udpingress-example
annotations:
kubernetes.io/ingress.class: kong
spec:
rules:
- backend:
serviceName: coredns
servicePort: 53
port: 9999
This configuration binds the Kong Gateway port 9999
to the Service
port 53
for our DNS server.
Apply the coredns-udpingress.yaml
manifests:
$ kubectl apply -f coredns-udpingress.yaml
You can now make DNS requests via Kong Gateway.
Verification
Now that setup is complete, all that’s left to do is verify that everything is working by making a DNS request to our CoreDNS server.
Note: This example assumes you have the
dig
command available on your local system. If you don’t, refer to your operating system documentation for a similar DNS lookup tool.
First, retrieve the IP address of the UDP load balancer service that we configured in previous sections:
$ export KONG_UDP_ENDPOINT="$(kubectl -n {NAMESPACE} get service {RELEASE_NAME}-kong-udp-proxy \
-o=go-template='{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}')"
Replace {NAMESPACE}
and {RELEASE_NAME}
with the values
you originally provided to helm install
in your own environment.
Now that you’ve stored the IP in the environment variable KONG_UDP_ENDPOINT
, you can use
that with dig
to do a DNS lookup through the CoreDNS server you set up and exposed
using UDPIngress
:
Verify that the {KONG_UDP_ENDPOINT}
in the SERVER
section of the response above ends
up being equal to your ${KONG_UDP_ENDPOINT}
value.
Now you’re equipped to route UDP traffic into your Kubernetes cluster with Kong Gateway!