TCP
Set up a TCP listener on your API gateway.
The following guide deploys a sample TCP echo app, sets up a TCP listener on the gateway, and creates a TCPRoute to the sample app.
Before you begin
Follow the Get started guide to install Gloo Gateway.
Install the experimental channel of the Kubernetes Gateway API so that you can use TCPRoutes and optionally ListenerSets.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/experimental-install.yamlDeploy the sample TCP echo app.
kubectl apply -f- <<EOF apiVersion: v1 kind: Pod metadata: labels: app: tcp-echo name: tcp-echo namespace: default spec: containers: - image: soloio/tcp-echo:latest imagePullPolicy: IfNotPresent name: tcp-echo restartPolicy: Always --- apiVersion: v1 kind: Service metadata: labels: app: tcp-echo name: tcp-echo namespace: default spec: ports: - name: http port: 1025 protocol: TCP targetPort: 1025 selector: app: tcp-echo EOFCreate a ReferenceGrant to allow TCPRoutes to refer to the TCP echo service.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: allow-gw-to-default-service namespace: default spec: from: - group: gateway.networking.k8s.io kind: TCPRoute namespace: gloo-system to: - group: "" # core API group kind: Service name: tcp-echo # Optionally remove this name field to allow any service EOFDecide whether to set up an HTTP listener inline on the Gateway resource or as a separate ListenerSet resource. Note that ListenerSets are an experimental feature in the upstream Kubernetes Gateway API project, and subject to change. For more information, see the Listener overview.
Set up the Gateway for TCP routes
Create a TCP listener so that the gateway can route TCP traffic. In the following example, all TCP streams on port 8000 of the gateway are forwarded to port 1025 of the example TCP echo service.
Create a Gateway resource with a TCP listener.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: tcp-gateway namespace: gloo-system labels: app: tcp-echo spec: gatewayClassName: gloo-gateway listeners: - protocol: TCP port: 8000 name: tcp allowedRoutes: kinds: - kind: TCPRoute EOFReview the following table to understand this configuration.
Setting Description spec.gatewayClassNameThe name of the Kubernetes gateway class that you want to use to configure the gateway. When you set up Gloo Gateway, a default gateway class is set up for you. To view the gateway class configuration, see Gateway classes and types. spec.listenersConfigure the listeners for this gateway. In this example, you configure a TCP gateway that listens for incoming traffic on port 8000. The gateway can serve TCPRoutes from any namespace. Create a Gateway that enables the attachment of ListenerSets.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: tcp-gateway namespace: gloo-system labels: app: tcp-echo spec: gatewayClassName: gloo-gateway allowedListeners: namespaces: from: All listeners: - protocol: HTTP port: 80 name: http allowedRoutes: namespaces: from: All EOFReview the following table to understand this configuration.
Setting Description spec.gatewayClassNameThe name of the Kubernetes gateway class that you want to use to configure the gateway. When you set up Gloo Gateway, a default gateway class is set up for you. To view the gateway class configuration, see Gateway classes and types. spec.allowedListenersEnable the attachment of ListenerSets to this Gateway. The example allows listeners from any namespace, which is helpful in multitenant environments. You can also limit the allowed listeners. To limit to listeners in the same namespace as the Gateway, set this value to Same. To limit to listeners with a particular label, set this value toSelector.spec.listenersOptionally, you can configure a listener that is specific to the Gateway. Note that due to a Gateway API limitation, you must configure at least one listener on the Gateway resource, even if the listener is not used and is a “dummy” listener. This dummy listener cannot conflict with the listener that you configure in the ListenerSet, such as using the same port or name. In this example, the dummy listener is configured on HTTP port 80, which differs from TCP port 8000 in the ListenerSet that you create later. Create a ListenerSet that configures an HTTPS listener for the Gateway.
kubectl apply -f- <<EOF apiVersion: gateway.networking.x-k8s.io/v1alpha1 kind: XListenerSet metadata: name: tcp-listenerset namespace: gloo-system labels: app: tcp-echo spec: parentRef: name: tcp-gateway namespace: gloo-system kind: Gateway group: gateway.networking.k8s.io listeners: - protocol: TCP port: 8000 name: tcp allowedRoutes: kinds: - kind: TCPRoute EOFReview the following table to understand this configuration.
Setting Description spec.parentRefThe name of the Gateway to attach the ListenerSet to. spec.listenersConfigure the listeners for this gateway. In this example, you configure a TCP gateway that listens for incoming traffic on port 8000. The gateway can serve TCPRoutes from any namespace.
Check the status of the gateway to make sure that your configuration is accepted and no conflicts exist in your cluster.
kubectl get gateway tcp-gateway -n gloo-system -o yamlExample output:
status: addresses: - type: IPAddress value: ${INGRESS_GW_ADDRESS} conditions: - lastTransitionTime: "2024-11-20T16:01:25Z" message: "" observedGeneration: 2 reason: Accepted status: "True" type: Accepted - lastTransitionTime: "2024-11-20T16:01:25Z" message: "" observedGeneration: 2 reason: Programmed status: "True" type: ProgrammedCreate a TCPRoute resource for the TCP echo app that is served by the gateway that you created.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1alpha2 kind: TCPRoute metadata: name: tcp-route-echo namespace: gloo-system labels: app: tcp-echo spec: parentRefs: - name: tcp-gateway namespace: gloo-system sectionName: tcp rules: - backendRefs: - name: tcp-echo namespace: default kind: Service port: 1025 EOFkubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1alpha2 kind: TCPRoute metadata: name: tcp-route-echo namespace: gloo-system labels: app: tcp-echo spec: parentRefs: - name: tcp-listenerset namespace: gloo-system sectionName: tcp kind: XListenerSet group: gateway.networking.x-k8s.io rules: - backendRefs: - name: tcp-echo namespace: default kind: Service port: 1025 EOFVerify that the TCPRoute is applied successfully.
kubectl get tcproute/tcp-route-echo -n gloo-system -o yamlExample output: Notice in the
statussection that the parentRef is either the Gateway or the ListenerSet, depending on how you attached the HTTPRoute.status: parents: - conditions: - lastTransitionTime: "2024-11-21T16:22:52Z" message: "" observedGeneration: 1 reason: Accepted status: "True" type: Accepted - lastTransitionTime: "2024-11-21T16:22:52Z" message: "" observedGeneration: 1 reason: ResolvedRefs status: "True" type: ResolvedRefs controllerName: solo.io/gloo-gateway parentRef: group: gateway.networking.k8s.io kind: Gateway name: tcp-gateway sectionName: tcpVerify that the listener now has a route attached.
kubectl get gateway -n gloo-system tcp-gateway -o yamlExample output:
... listeners: - attachedRoutes: 1kubectl get xlistenerset -n gloo-system tcp-listenerset -o yamlExample output:
... listeners: - attachedRoutes: 1Note that because the HTTPRoute is attached to the ListenerSet, the Gateway does not show the route in its status.
kubectl get gateway -n gloo-system tcp-gateway -o yamlExample output:
... listeners: - attachedRoutes: 0If you create another HTTPRoute that attaches to the Gateway and uses the same listener as the ListenerSet, then the route is reported in the status of both the Gateway (attachedRoutes: 1) and the ListenerSet (attachedRoutes: 2).
Get the external address of the gateway and save it in an environment variable.
export INGRESS_GW_ADDRESS=$(kubectl get svc -n gloo-system gloo-proxy-tcp-gateway -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESSkubectl port-forward deployment/gloo-proxy-tcp-gateway -n gloo-system 8080:8080Send a TCP request to the external address of the TCP gateway on port 8000. You might use a tool such as telnet or netcat as in the following example.
nc -v $INGRESS_GW_ADDRESS 8000nc -v localhost 8080Example output:
Connection to ${INGRESS_GW_ADDRESS} port 8000 [tcp/irdmi] succeeded!Enter any string to verify that the TCP echo service “echoes,” returning the same string back.
helloExample output:
hello hello
Cleanup
You can optionally remove the resources that you set up as part of this guide.kubectl delete -A gateways,tcproutes,pod,svc -l app=tcp-echokubectl delete -A gateways,xlistenersets,tcproutes,pod,svc -l app=tcp-echo