TCP passthrough

Set up a TCP listener on the gateway that serves one or more hosts and passes TCP traffic through to a destination. Because TCP traffic is directly forwarded to the destination, the destination must be capable of handling incoming TLS traffic.

TCP listener setup

Before you begin

To follow the example that is outlined on this page, you must set up Gloo Gateway must in a single cluster as described in the getting started guide. You do not need to deploy sample apps or set up routing, as you create the TCP helloworld sample app as part of this example.

Open the TCP port on the ingress gateway

When you followed the get started guide, the ingress gateway is set up without a TCP port. To configure a TCP listener on your gateway, you must first open up a TCP port on the ingress gateway.

  1. Get the details of the ingress gateway service and check if port 9000 with the name tcp is open on your ingress gateway.

    kubectl get service istio-ingressgateway -n gloo-mesh-gateways -o yaml
    

    Example output if the TCP port is open on the gateway:

    ...
    spec:
      ports:
      - name: tcp
        nodePort: 30358
        port: 9000
        protocol: TCP
        targetPort: 9000
    
  2. If the port is not yet open on your ingress gateway, perform an upgrade of your Istio ingress gateway to open up the TCP port.

    1. Follow the steps to perform a test or canary upgrade of your managed gateway proxies.
    2. Add the following section to your Helm values file, and use these updated values during the upgrade.
      istioInstallations:
        controlPlane:
          enabled: true
          installations:
          - clusters: null
            istioOperatorSpec: {}
            revision: auto
        eastWestGateways: null
        enabled: true
        northSouthGateways:
        - enabled: true
          installations:
          - clusters: null
            gatewayRevision: auto
            istioOperatorSpec:
              components:
                ingressGateways:
                - enabled: true
                  name: istio-ingressgateway
                  namespace: gloo-mesh-gateways
                  k8s:
                    service:
                      type: LoadBalancer 
                      ports:
                      - name: status-port
                        port: 15021
                        targetPort: 15021
                      - name: http2
                        port: 80
                        targetPort: 8080
                      - name: https
                        port: 443
                        targetPort: 8443
                      - name: tls
                        port: 15443
                        targetPort: 15443
                      - name: tcp
                        port: 9000
                        targetPort: 9000
          name: istio-ingressgateway
          namespace: gloo-mesh-gateways
      
  3. After the upgrade, verify that the TCP port is now open on your ingress gateway.

    kubectl get service istio-ingressgateway -n gloo-mesh-gateways -o yaml
    

Deploy the helloworld TCP sample app

The helloworld sample app is a simple way to test responses for different app versions. The following examples install four versions of helloworld in your cluster.

  1. Create a helloworld namespace.

    kubectl create ns helloworld
    
  2. Deploy helloworld v1, v2, v3, and v4 to your cluster.

    kubectl -n helloworld apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/helloworld.yaml 
    
  3. Verify that the helloworld apps are running.

    kubectl -n helloworld get pods
    

Set up a TCP listener on your gateway

To route TCP traffic to the TCP app directly without originating a TLS connection at the gateway, you create a virtual gateway and configure a TCP listener.

  1. Create the virtual gateway and configure your TCP listener. Note that the tcp section of your virtual gateway config must remain empty so that the gateway is instructed to directly forward the traffic to the TCP workload in the cluster.

    kubectl apply -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: VirtualGateway
    metadata:
      annotations:
        cluster.solo.io/cluster: ""
      name: istio-ingressgateway-tcp
      namespace: helloworld
    spec:
      listeners:
      - port:
          number: 9000
        tcp: {}
      workloads:
      - selector:
          labels:
            istio: ingressgateway
    EOF
    
  2. Create a route table to route incoming requests on any host to the helloworld TCP app that you created.

    kubectl apply -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: RouteTable
    metadata:
      annotations:
        cluster.solo.io/cluster: ""
      name: tcp-route
      namespace: helloworld
    spec:
      hosts:
      - '*'
      tcp:
      - forwardTo:
          destinations:
          - port:
              number: 9000
            ref:
              cluster: $CLUSTER_NAME
              name: helloworld
              namespace: helloworld
        matchers:
        - port: 9000
      virtualGateways:
      - name: istio-ingressgateway-tcp
    EOF
    
  3. Get the IP address of your ingress gateway.

    export INGRESS_GW_IP=$(kubectl get svc -n gloo-mesh-gateways istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    echo $INGRESS_GW_IP
    
  4. Send a request to the nginx.example.com domain.

    echo "Hello" | nc -v $INGRESS_GW_IP 9000
    

    Example output:

    Connection to 35.241.2.123 port 9000 [tcp/cslistener] succeeded!
    hello-v1 Hello
    

Cleanup

You can optionally remove the resources that you set up as part of this guide.
kubectl delete routetable tcp-route -n helloworld
kubectl delete virtualgateway istio-ingressgateway-tcp -n helloworld
kubectl delete deployment helloworld-v1 -n helloworld
kubectl delete deployment helloworld-v2 -n helloworld
kubectl delete deployment helloworld-v3 -n helloworld
kubectl delete deployment helloworld-v4 -n helloworld
kubectl delete service helloworld -n helloworld
kubectl delete namespace helloworld