Proxy TCP traffic using TCPRoute

Deployment Platform
Related Documentation
Minimum Version
Kong Operator - 2.3
TL;DR

Add a TCP listener to your Gateway, then create a TCPRoute resource. Kong Operator converts the TCPRoute into 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. Add the Kong Helm charts:

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

    helm upgrade --install kong-operator kong/kong-operator -n kong-system \
      --create-namespace \
      --set image.tag=2.3 \
      --set env.ENABLE_CONTROLLER_KONNECT=true
    helm upgrade --install kong-operator kong/kong-operator -n kong-system \
      --create-namespace \
      --set image.tag=2.3 \

    If you want cert-manager to issue and rotate the admission and conversion webhook certificates, install cert-manager to your cluster and enable cert-manager integration by passing the following argument while installing, in the next step:

    --set global.webhooks.options.certManager.enabled=true

    If you do not enable this, the chart will generate and inject self-signed certificates automatically. We recommend enabling cert-manager to manage the lifecycle of these certificates. Kong Operator needs a certificate authority to sign the certificate for mTLS communication between the control plane and the data plane. This is handled automatically by the Helm chart. If you need to provide a custom CA certificate, refer to the certificateAuthority section in the values.yaml of the Helm chart to learn how to create and reference your own CA certificate.

Apply a KongLicense. This assumes that your license is available in ./license.json

echo "
apiVersion: configuration.konghq.com/v1alpha1
kind: KongLicense
metadata:
 name: kong-license
rawLicenseString: '$(cat ./license.json)'
" | kubectl apply -f -
kubectl create namespace kong --dry-run=client -o yaml | kubectl apply -f -
echo '
kind: KonnectAPIAuthConfiguration
apiVersion: konnect.konghq.com/v1alpha1
metadata:
  name: konnect-api-auth
  namespace: kong
spec:
  type: token
  token: "'$KONNECT_TOKEN'"
  serverURL: us.api.konghq.com
' | kubectl apply -f -
echo '
kind: KonnectGatewayControlPlane
apiVersion: konnect.konghq.com/v1alpha2
metadata:
  name: gateway-control-plane
  namespace: kong
spec:
  createControlPlaneRequest:
    name: gateway-control-plane
  konnect:
    authRef:
      name: konnect-api-auth
' | kubectl apply -f -

telnet is a CLI that lets you open raw TCP connections to a host and port. This tutorial requires telnet for validation.

macOS doesn’t ship telnet. Install it with Homebrew:

brew install telnet

On Debian and Ubuntu, install the telnet package:

sudo apt-get install telnet

TCPRoute is a Kubernetes Gateway API resource for routing raw TCP traffic by port, without any TLS or L7 awareness. This guide shows how to configure Kong Operator to proxy TCP traffic to a backend Service.

Create the kong namespace

Create the kong namespace in your Kubernetes cluster, which is where the demo will run:

kubectl create namespace kong

Configure the Gateway

Create a GatewayConfiguration, GatewayClass, and Gateway with an HTTP listener:

echo '
apiVersion: gateway-operator.konghq.com/v2beta1
kind: GatewayConfiguration
metadata:
  name: kong-gateway-configuration
  namespace: kong
spec:
  dataPlaneOptions:
    deployment:
      podTemplateSpec:
        spec:
          containers:
            - image: kong/kong-gateway:3.15
              name: proxy
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: kong-tcp
spec:
  controllerName: konghq.com/gateway-operator
  parametersRef:
    group: gateway-operator.konghq.com
    kind: GatewayConfiguration
    name: kong-gateway-configuration
    namespace: kong
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: kong-tcp-gateway
  namespace: kong
spec:
  gatewayClassName: kong-tcp
  listeners:
    - name: http
      port: 80
      protocol: HTTP' | kubectl apply -f -

Deploy a TCP backend

Install the echo Service, which accepts plain TCP connections on port 1025 and echoes back anything it receives:

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

Route TCP traffic

  1. Re-apply the kong-tcp-gateway Gateway with an additional TCP listener:

    Warning: Applying this Gateway replaces the listener list. Include every listener you want to keep.

    echo 'apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: kong-tcp-gateway
      namespace: kong
    spec:
      gatewayClassName: kong-tcp
      listeners:
        - name: http
          port: 80
          protocol: HTTP
        - name: stream9000
          port: 9000
          protocol: TCP' | kubectl apply -f -
  2. Create a TCPRoute:

    echo "apiVersion: gateway.networking.k8s.io/v1
    kind: TCPRoute
    metadata:
      name: echo-plaintext
      namespace: kong
    spec:
      parentRefs:
        - name: kong-tcp-gateway
          sectionName: stream9000
      rules:
        - backendRefs:
            - name: echo
              port: 1025
    " | kubectl apply -f -

This configuration instructs Kong Gateway to forward all traffic it receives on port 9000 to the echo Service on port 1025.

Validate

  1. Wait for the Gateway to be programmed:

    kubectl wait gateway/kong-tcp-gateway -n kong \
      --for=condition=Programmed=True \
      --timeout=5m
  2. Get the Gateway’s external IP:

    export PROXY_IP=$(kubectl get gateway kong-tcp-gateway -n kong -o jsonpath='{.status.addresses[0].value}')
    echo $PROXY_IP
  3. Test the Route using telnet:

    telnet -e '^X' $PROXY_IP 9000

    The -e '^X' flag allows you to chose an escape key to exit telnet.

    After you connect, type some text that you want as a response from the echo Service:

    Telnet escape character is '^X'.
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^X'.
    Welcome, you are connected to node orbstack.
    Running on Pod echo-bcf7f965b-m5mnv.
    In namespace kong.
    With IP address 127.0.0.1.
    Hello
    Hello
  4. Press Ctrl+X and enter quit to exit.

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!