solo-io / gloo

The Feature-rich, Kubernetes-native, Next-Generation API Gateway Built on Envoy
https://docs.solo.io/
Apache License 2.0
4.06k stars 433 forks source link

dynamic routing with subset selectors #4959

Open bcollard opened 3 years ago

bcollard commented 3 years ago

The goal is to use dynamic values in subset selectors For example, a header may contain the label's key/value that will be used to route the request to a given pods subset

jannes commented 3 years ago

in terms of declaring this, a subsetHeaders field could be added to the subset field. e.g:

routes:
  - matchers:
    - headers:
      - name: subset-selector
      prefix: /example
    name: subset-route-dynamic
    routeAction:
      single:
        subset:
          subsetHeaders:
            - subset-selector
        upstream:
          name: example-upstream
          namespace: gloo-system
chrisgaun commented 3 years ago

We are looking into this to see if this is in the Envoy API

jannes commented 3 years ago

It seems to me that we can just use envoy's header_to_metadata filter to rewrite the specified header to a key/value pair in the envoy.lb namespace.

Apparently envoy will automatically select a subset without having to specify a metadata_match in the route, which is not very clear from the docs, but judging from https://github.com/envoyproxy/envoy/pull/3254 this is the case. Also: https://github.com/envoyproxy/envoy/blob/main/docs/root/configuration/http/http_filters/header_to_metadata_filter.rst.

So whereas for the subset->values config something like this is generated:

{
   "match": ....,
   "route": {
      "cluster": ....,
      "metadata_match": {
         "filter_metadata": {
            "envoy.lb": {
               "example-key": "example-value"
            }
         }
      }
   },
   ....
}

for the subset->subsetHeader we could generate instead:

{
   "match": ....,
   "route": {
      "cluster": ....
   },
   "typed_per_filter_config": [
      {
         "name": "envoy.filters.http.header_to_metadata",
         "config": {
            "request_rules": [
               {
                  "header": "example-header",
                  "on_header_present": {
                     "metadata_namespace": "envoy.lb",
                     "key": "example-key",
                     "type": "STRING"
                  },
                  "remove": false
               }
            ]
         }
      }
   ],
   ....
}

subset->values and subset->subsetHeader would need to be mutually exclusive

What do you think?

github-actions[bot] commented 2 months ago

This issue has been marked as stale because of no activity in the last 180 days. It will be closed in the next 180 days unless it is tagged "no stalebot" or other activity occurs.