You can use an egress gateway to route and capture traffic to TCP services that are outside your service mesh. The egress gateway can forward traffic as follows:

  • Send TCP traffic to an external service: When an app inside your service mesh sends a request to an external TCP service, the app uses mTLS to send the request to the egress gateway first. The egress gateway terminates the TLS connection and forwards TCP traffic to the external service.
  • Originate a TLS connection to the TCP service: The app inside the service mesh uses mTLS to send the request to the egress gateway. The egress gateway terminates the TLS connection and then originates a new simple TLS connection to the external TCP service.

Limitations

Consider the following limitations when routing to external TCP services:

  • Wildcard hosts are not supported for TCP routes when using an egress gateway.
  • The appProtocol on the gateway listener must be set to TLS, even if the external service uses TCP. This way, TLS traffic from the sidecar to the egress gateway can be terminated at the egress gateway. You can then decide if you want to forward the unencrypted TCP traffic or originate a new TLS connection the external service.

Before you begin

Follow the steps to create an egress gateway.

Open TCP ports on the egress gateway

  1. Get the details of the egress gateway service and check if ports 4242 and 4243 are open on your egress gateway.

      kubectl get service istio-egressgateway -n istio-egress -o yaml
      
  2. If the ports are not yet open, perform an upgrade of your egress gateway to open up the TCP ports. Add the following snippet to your egress gateway configuration.

      ...
    service:
      type: ClusterIP
      ports:
      - name: tcp
        port: 4242
        protocol: TCP
        targetPort: 4242
      - name: tcp-tls
        port: 4243
        protocol: TCP
        targetPort: 4243
    ...
      
  3. After the upgrade, verify that the TCP ports are now open on your egress gateway.

      kubectl get service istio-egressgateway -n istio-egress -o yaml
      
  4. Set up TCP routing. Decide on the following configuration options:

    • Send TCP traffic to an external service: When an app inside your service mesh sends a request to an external TCP service, the app uses mTLS to send the request to the egress gateway first. The egress gateway terminates the TLS connection and forwards TCP traffic to the external service.
    • Originate a TLS connection to the TCP service: The app inside the service mesh uses mTLS to send the request to the egress gateway. The egress gateway terminates the TLS connection and then originates a new simple TLS connection to the external TCP service.

Send TCP traffic to an external service

  1. Create a VirtualGateway to configure your egress gateway to route traffic to the tcpbin.com external service that you configure in the next step. The gateway is configured to terminate mTLS traffic in the service mesh and to forward TCP traffic to the external service.

      kubectl apply -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: VirtualGateway
    metadata:
      name: egress-tcp
      namespace: istio-egress
    spec:
      workloads:
        - selector:
            labels:
              app: istio-egressgateway
              istio: egressgateway
      listeners:
        - appProtocol: TLS
          exposedExternalServices:
          - host: tcpbin.com
          port:
            number: 4242
          tls:
            mode: ISTIO_MUTUAL
    EOF
      
  2. Create an ExternalService for the tcpbin.com external service. In the spec.ports section, reference the TCP port that you opened on egress gateway. This way, traffic to the TCP app is automatically routed through the egress gateway. Make sure that the name of the TCP port matches the name of the TCP port that you opened on your egress gateway.

      kubectl apply -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: ExternalService
    metadata:
      name: tcpbin-plain
      namespace: bookinfo
    spec:
      hosts:
      - tcpbin.com
      ports:
      - egressGatewayRoutes:
          portMatch: 5242
          virtualGatewayRefs:
          - name: egress-tcp
            namespace: istio-egress
        name: tcp
        number: 4242
        protocol: TCP
    EOF
      
  3. Log in to the productpage pod that you deployed as part of the getting started tutorial. You use this app to establish a TCP connection from within the service mesh to your external TCP service.

      kubectl -n bookinfo exec -it deploy/productpage-v1 -c curl -- sh    
      
  4. Use netcat to establish a TCP connection to your external service.

      nc tcpbin.com 5242
      
  5. Enter any string, such as Hello world, and verify that the string is echoed in your CLI output.

      Hello world
      

    Example output:

      $ nc tcpbin.com 5242
    Hello world
    Hello world
      

Originate a TLS connection to the TCP service

  1. Create a VirtualGateway to configure your egress gateway to route traffic to the tcpbin.com external service that you configure in the next step. The gateway is configured to terminate mTLS traffic at the gateway.

      kubectl apply -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: VirtualGateway
    metadata:
      name: egress-tcp
      namespace: istio-egress
    spec:
      workloads:
        - selector:
            labels:
              app: istio-egressgateway
              istio: egressgateway
      listeners:
        - appProtocol: TLS
          exposedExternalServices:
          - host: tcpbin.com
          port:
            number: 4243
          tls:
            mode: ISTIO_MUTUAL
    EOF
      
  2. Create an ExternalService for the tcpbin.com external service. In the spec.ports section, reference the TCP TLS port that you opened on egress gateway. This way, traffic to the TCP app is automatically routed through the egress gateway. To terminate TLS traffic at the egress gateway and originate a new TLS connection to the external service, include the clientsideTls.mode=SIMPLE setting. Make sure that the name of the TCP port matches the name of the TCP port that you opened on your egress gateway.

      kubectl apply -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: ExternalService
    metadata:
      name: tcpbin-plain
      namespace: bookinfo
    spec:
      hosts:
      - tcpbin.com
      ports:
      - egressGatewayRoutes:
          portMatch: 5243
          virtualGatewayRefs:
          - name: egress-tcp
            namespace: istio-egress
        name: tcp-tls
        number: 4243
        protocol: TCP
        clientsideTls:
          mode: SIMPLE
    EOF
      
  3. Log in to the productpage pod that you deployed as part of the getting started tutorial. You use this app to establish a TCP connection from within the service mesh to your external TCP service.

      kubectl -n bookinfo exec -it deploy/productpage-v1 -c curl -- sh    
      
  4. Use netcat to establish a TCP connection to your external service.

      nc tcpbin.com 5243
      
  5. Enter any string, such as Hello world, and verify that the string is echoed in your CLI output.

      Hello world
      

    Example output:

      $ nc tcpbin.com 5243
    Hello world
    Hello world
      

Cleanup

You can optionally remove the resources that you created in this guide.

  kubectl delete virtualgateway egress-tcp -n istio-egress
kubectl delete externalservice tcpbin -n bookinfo