Route across clusters

You can easily set up intelligent multicluster routing for active-active and active-passive workloads in your environment by using virtual destinations. With virtual destinations, you can define unique internal hostnames for apps that are spread across multiple clusters, and route to these apps via these hostnames.

Figure: Multicluster routing with Gloo Gateway.

For more information, see the following resources:

When Gloo Gateway routes requests across clusters through the east-west gateway, the communication to the east-west gateway is secured with mTLS. However, when your app is deployed without Istio sidecars, the east-west gateway uses plaintext to route the request to your app. To secure communications to your apps with mTLS instead, consider using Gloo Mesh Enterprise alongside Gloo Gateway to set up an Istio service mesh for your workloads. You can additionally use Gloo Mesh to route from service-to-service within your cluster environment by using mTLS.

Before you begin

  1. Install Gloo Gateway.
  2. Configure an HTTP or HTTPS listener on your ingress gateway.
  3. Follow the other guides in this routing section to plan your routing table setup. For example, you might check out the path matching guide to decide how to match the incoming requests to your service paths, the redirect guide to set up any path or host rewrites, or the sub-table delegation guide to nest and sort multiple route tables. Note: Be sure that each route for one host is unique, such as by using prefix matching to determine which requests to the host should be forwarded to which destinations.

Set up multicluster routing for north-south traffic

To route incoming requests from your ingress gateway to an app that is spread across clusters based on locality, you create a virtual destination for your multicluster app, and a route table that forwards traffic to that virtual destination.

  1. In each cluster where you deployed an instance of your global app, ensure that the app is exposed by a Kubernetes service. Make sure that you use the same label for your services as this label serves as the selector to later identify all the services across your clusters that make up your global app. In this example, the label app: global-app is used. The service listens on port 3456 and forwards requests to port 9080.

    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: global-app
      name: global-app
      namespace: global
    spec:
      ports:
      - name: http
        port: 3456
        protocol: TCP
        targetPort: 9080
      type: ClusterIP
    
  2. Create a virtual destination resource and define a unique hostname that the virtual gateway can use to send requests to. This virtual destination is configured to listen for incoming traffic on the internal-only, arbitrary hostname app.internal.com:8080. Incoming requests can then be routed to any service instances with the label app: global-app on port 9080. Note that because virtual destinations are dynamic, the ingress gateway load balances the request across healthy app instance.

    kubectl apply --context $REMOTE_CONTEXT1 -n global -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: VirtualDestination
    metadata:
      name: global-app-vd
      namespace: global
    spec:
      hosts:
      # Arbitrary, internal-only hostname assigned to the endpoint
      - app.internal.com
      ports:
      - number: 8080
        protocol: HTTP
        targetPort:
          number: 9080
      services:
        - labels:
            app: global-app
    EOF
    
  3. Create a route table to route requests to your services. A route table allows you to define how requests to endpoints should be routed. In this example route table, all requests to the /global-app path are routed to the global-app virtual destination.

    kubectl apply --context $REMOTE_CONTEXT1 -n global -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: RouteTable
    metadata:
      name: global-app-routes
      namespace: global
    spec:
      # Applies to any host; can indicate a specific domain, like example.com
      hosts:
        - '*'
      # Selects the virtual gateway you previously created
      virtualGateways:
        - name: istio-ingressgateway
          namespace: bookinfo
          cluster: ${REMOTE_CLUSTER1}
      http:
        # Route for the global-app service
        - name: global-app
          # Prefix matching
          matchers:
          - uri:
              prefix: /global-app
          # Forwarding directive
          forwardTo:
            destinations:
              # Reference to the virtual destination for the global-app svcs
              - ref:
                  name: global-app-vd
                kind: VIRTUAL_DESTINATION
                port:
                  number: 8080
    EOF
    
  4. Save the external address of the ingress gateway.

    
       export INGRESS_GW_IP=$(kubectl get svc --context $REMOTE_CONTEXT1 -n gloo-mesh-gateways istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
       echo $INGRESS_GW_IP
       
    
       export INGRESS_GW_IP=$(kubectl get svc --context $REMOTE_CONTEXT1 -n gloo-mesh-gateways istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
       echo $INGRESS_GW_IP
       

  5. Test the route to your app by curling the ingress gateway address and app path. For example, the following command appends /global-app for the sample app.

    curl http://$INGRESS_GW_IP/global-app
    

Next steps