You are browsing documentation for an outdated version. See the latest documentation here.
Exposing a TCP Service
Overview
This guide walks through creating TCP routing configuration for Kong Gateway in Kubernetes using either the TCPIngress custom resource or TCPRoute and TLSRoute Gateway APIs resource.
TCP-based Ingress means that Kong Gateway simply forwards the TCP stream to a Pod of a Service that’s running inside Kubernetes. Kong Gateway will not perform any sort of transformations.
There are two modes available:
- Port based routing: In this mode, Kong Gateway simply proxies all traffic it receives on a specific port to the Kubernetes Service. TCP connections are load balanced across all the available pods of the Service.
-
SNI based routing: In this mode, Kong Gateway accepts a TLS-encrypted stream
at the specified port and can route traffic to different services based on
the
SNI
present in the TLS handshake. Kong Gateway will also terminate the TLS handshake and forward the TCP stream to the Kubernetes Service.
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.
Add TLS configuration
The routing configuration can include a certificate to present when clients connect over HTTPS. This is not required, as Kong Gateway will serve a default certificate if it cannot find another, but including TLS configuration along with routing configuration is typical.
First, create a test certificate for the tls9443.kong.example
hostname using one of the following commands:
Then, create a Secret containing the certificate:
kubectl create secret tls tls9443.kong.example --cert=./server.crt --key=./server.key
Response:
secret/tls9443.kong.example created
Adding TCP listens
Kong Gateway does not include any TCP listen configuration by default. To expose TCP 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:9000, 0.0.0.0:9443 ssl"
}
],
"ports": [
{
"containerPort": 9000,
"name": "stream9000",
"protocol": "TCP"
},
{
"containerPort": 9443,
"name": "stream9443",
"protocol": "TCP"
}
]
}
]
}
}
}
}'
Response:
deployment.extensions/ingress-kong patched
The ssl
parameter after the 9443 listen instructs Kong Gateway to
expect TLS-encrypted TCP traffic on that port. The 9000 listen has no
parameters, and expects plain TCP traffic.
Update the proxy Service
The proxy Service also needs to indicate the new ports:
kubectl patch service -n kong kong-proxy --patch '{
"spec": {
"ports": [
{
"name": "stream9000",
"port": 9000,
"protocol": "TCP",
"targetPort": 9000
},
{
"name": "stream9443",
"port": 9443,
"protocol": "TCP",
"targetPort": 9443
}
]
}
}'
Response:
service/kong-proxy patched
Update the Gateway
If you are using the Gateway APIs (TCPRoute) option, your Gateway needs additional
configuration under listeners
. If you are using TCPIngress, skip this step.
kubectl patch --type=json gateway kong -p='[
{
"op":"add",
"path":"/spec/listeners/-",
"value":{
"name":"stream9000",
"port":9000,
"protocol":"TCP"
}
},
{
"op":"add",
"path":"/spec/listeners/-",
"value":{
"name":"stream9443",
"port":9443,
"protocol":"TLS",
"hostname":"tls9443.kong.example",
"tls": {
"certificateRefs":[{
"group":"",
"kind":"Secret",
"name":"tls9443.kong.example"
}]
}
}
}
]'
Response:
gateway.gateway.networking.k8s.io/kong patched
Install TCP echo service
Next, install an example TCP service:
kubectl apply -f https://docs.konghq.com/assets/kubernetes-ingress-controller/examples/tcp-echo-service.yaml
Response:
deployment.apps/tcp-echo created
service/tcp-echo created
Route TCP traffic by port
To expose the service to the outside world, create the following TCPIngress resource:
This configuration instructs Kong Gateway to forward all traffic it
receives on port 9000 to tcp-echo
service on port 2701.
Test the configuration
Status will populate with an IP or Accepted condition once the route is ready:
Connect to this service using telnet
:
$ telnet $PROXY_IP 9000
Trying 35.247.39.83...
Connected to 35.247.39.83.
Escape character is '^]'.
Welcome, you are connected to node gke-harry-k8s-dev-pool-1-e9ebab5e-c4gw.
Running on Pod tcp-echo-844545646c-gvmkd.
In namespace default.
With IP address 10.60.1.17.
This text will be echoed back.
This text will be echoed back.
^]
telnet> Connection closed.
We can see here that the tcp-echo
service is now available outside the
Kubernetes cluster via Kong Gateway.
Route TLS traffic by SNI
Next, we will demonstrate how Kong Gateway can route TLS-encrypted
traffic to the tcp-echo
service.
Create the following TCPIngress resource:
Test the configuration
You can now access the tcp-echo
service on port 9443 with SNI
tls9443.kong.example
.
In real-world usage, you would create a DNS record for tls9443.kong.example
pointing to your proxy Service’s public IP address, which causes TLS clients to
add SNI automatically. For this demo, you’ll add it manually using the OpenSSL
CLI:
echo "hello" | openssl s_client -connect $PROXY_IP:9443 -servername tls9443.kong.example -quiet 2>/dev/null
Press Ctrl+C to exit after. Response:
Welcome, you are connected to node kind-control-plane.
Running on Pod tcp-echo-5f44d4c6f9-krnhk.
In namespace default.
With IP address 10.244.0.26.
hello