Delegate requests to child route tables

Delegate incoming requests through one parent route table to other child route tables (also called sub-tables).

As your environment grows, your gateways manage traffic for more and more routes. You might also have more ways of routing to a particular path for an app. To organize all your routes, you can use route table delegation. Delegation means that the routing decision for a route in one table instead gets made by another table.

This approach gives you the flexibility to manage a large number of routes in several ways, such as with label and matcher inheritance.

Label inheritance: Routes can inherit labels of their own route table, as well as their parent route table. This way, you can apply the same labels to many routes at once. Then, you can use these labels to select the routes in other resources, such as to apply security policies. For more information, see Route label inheritance.

Matcher inheritance: Routes also inherit matchers from the parent route table. This way, you can route to specific subpaths that share a common element. For more information, see Route matcher inheritance.

For more information, review the following documentation:

Delegate to child route tables based on weight

Delegate routing to sub-tables based on an assigned order. Individual routes are kept in the order that they appear relative to their tables, but tables are sorted by the weight that you assign to them. When an incoming request arrives at the ingress gateway, the gateway attempts to match the request against the routes in the highest-weighted route table first. If the request doesn't match a route in the first sub-table, the gateway attempts to match against the routes in the second-highest-weighted table, and so on.
  1. Follow the guides in Forward requests to a destination to set up each route table that you want to include in this sub-table set, and apply the route tables to your Gloo Gateway environment.

  2. For each route table, include the following additional settings for delegation:

    • In the spec section, do not include the hosts or virtualGateways fields. The parent route table dictates these fields instead.
    • In the spec section, add the weight field that the ingress gateway uses when choosing a route table to delegate to. Higher integer values indicate a higher priority in the list of sub-tables. Note that tables of the same weight stay in the same order that you list them in the main route table, which is the list order when you specify sub-tables by name, or the creation timestamp when you select sub-tables by label.
    • Optional: If you want to refer to the sub-tables by label rather than by table name, add a label in the metadata section. Be sure to use the same label for each sub-table. For example, say that you are testing multiple types of request matching for myapp. You define two different route tables, one for each type of matching, and label them as table: myapp. You assign a higher weight to the table that uses prefix matching to test that matching method now, and a lower weight to the table that uses query parameters to focus on that later.
    • Your sub-tables might look like the following configurations:
      apiVersion: networking.gloo.solo.io/v2
      kind: RouteTable
      metadata:
        name: prefix-match
        namespace: global
        # Label for the sub-table set
        labels:
          table: myapp
      spec:
        # Higher weight means first priority in the sub-table order
        weight: 100
        http:
        # Table routes any requests to 'one.solo.io/myapp/.*'
        - matchers:
          - uri:
              prefix: /myapp
              ignoreCase: true
          forwardTo:
            destinations:
            - ref:
                name: myapp
                namespace: global
                cluster: ${CLUSTER_NAME}
              port:
                number: 8090
              kind: SERVICE
      
      apiVersion: networking.gloo.solo.io/v2
      kind: RouteTable
      metadata:
        name: query-parameters-match
        namespace: global
        # Label for the sub-table set
        labels:
          table: myapp
      spec:
        # Lower weight means second priority in the sub-table order
        weight: 90
        http:
        # Table routes any requests to 'one.solo.io/myapp/.*?version=stage'
        - matchers:
          - uri:
              prefix: /myapp
          - queryParameters:
            - name: version
              value: stage
          forwardTo:
            destinations:
            - ref:
                name: myapp
                namespace: global
                cluster: ${CLUSTER_NAME}
              port:
                number: 8090
              kind: SERVICE
      
  3. Create the main route table to delegate requests based on sub-table weight. In this example main table, the ingress gateway delegates all requests to the one.solo.io host to sub-tables with the table: myapp label, based on the order created by table weights. Note that you can also specify the sub-table names instead of the label by using the routeTables.name field.

    kubectl apply -n global -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: RouteTable
    metadata:
      name: delegate-weight
      namespace: global
    spec:
      hosts:
        - 'one.solo.io'
      virtualGateways:
        - name: istio-ingressgateway
          namespace: bookinfo
          cluster: ${CLUSTER_NAME}
      http:
      - delegate:
          # Selects tables based on label
          routeTables:
            - labels:
                table: myapp
          # Delegates based on order of weights
          sortMethod: TABLE_WEIGHT
    EOF
    
  4. Test route table delegation by accessing the host and any necessary request-matching criteria.

    • For example, curl or navigate to one.solo.io/myapp/foo to verify that the ingress gateway correctly delegates to the prefix-matching route in the prefix-match sub-table.
    • You might also change the weights for the sub-tables to test that order instead, such as putting the query-parameters-match sub-table higher in the order. Then, you can send a request to one.solo.io/myapp/foo?version=stage to verify that the ingress gateway correctly delegates to the query parameter-matching route in the query-parameters-match sub table.

Delegate to child route tables based on route specificity

When an incoming request to a host arrives at the ingress gateway, the gateway processes all routes in each sub-table that you select.

By default, routes are sorted by table weight. However, you can change the sorting method to sort by specificity instead.

Then, the resulting routes are sorted by specificity to reduce the chance that a general route short-circuits a more specific route.

The following specificity rules apply:

For example, consider the following two sub-tables that are sorted by specificity and the resulting route list.

The resulting routes are sorted in this order:

Example setup steps

  1. Follow the guides in Forward requests to a destination to set up each route table that you want to include in this sub-table set, and apply the route tables to your Gloo Gateway environment.

  2. For each route table, include the following additional settings for delegation:

    • In the spec section, do not include the hosts, virtualGateways, or workloadSelectors fields. The parent route table dictates these fields instead.
    • Optional: If you want to refer to the sub-tables by label rather than by table name, add a label in the metadata section. Be sure to use the same label for each sub-table.

    For example, say that you are testing multiple types of request matching for myapp. You define two different route tables, one for exact and one for prefix matching, and label them as table: myapp.

    • Your sub-tables might look like the following configurations:
      kubectl apply -n global -f- <<EOF
      apiVersion: networking.gloo.solo.io/v2
      kind: RouteTable
      metadata:
        name: exact-match
        namespace: global
        # Label for the sub-table set
        labels:
          table: myapp
      spec:
        http:
        # Match only requests to exactly 'one.solo.io/myapp/foo'
        - matchers:
          - uri:
              exact: /myapp/foo
          forwardTo:
            destinations:
            - ref:
                name: myapp
                namespace: global
                cluster: ${CLUSTER_NAME}
              port:
                number: 8090
              kind: SERVICE
      EOF
      
      kubectl apply -n global -f- <<EOF
      apiVersion: networking.gloo.solo.io/v2
      kind: RouteTable
      metadata:
        name: prefix-match
        namespace: global
        # Label for the sub-table set
        labels:
          table: myapp
      spec:
        http:
        # Match any requests to 'one.solo.io/myapp/.*'
        - matchers:
          - uri:
              prefix: /myapp
              ignoreCase: true
          forwardTo:
            destinations:
            - ref:
                name: myapp
                namespace: global
                cluster: ${CLUSTER_NAME}
              port:
                number: 8090
              kind: SERVICE
      EOF
      
  3. Create the main route table to delegate requests based individual route specificity. In this example main table, the ingress gateway first processes all routes in sub-tables with the table: myapp label. Then, the gateway delegates any requests to the one.solo.io host to the most specifically matched route. Note that you can also specify the sub-table names instead of the label by using the routeTables.name field.

    kubectl apply -n global -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: RouteTable
    metadata:
      name: delegate-specificity
      namespace: global
    spec:
      hosts:
        - 'one.solo.io'
      virtualGateways:
        - name: istio-ingressgateway
          namespace: bookinfo
          cluster: ${CLUSTER_NAME}
      http:
      - delegate:
          # Selects tables based on label
          routeTables:
            - labels:
                table: myapp
          # Delegates based on route specificity
          sortMethod: ROUTE_SPECIFICITY
    EOF