github.com/projectcontour/contour@v1.28.2/site/content/docs/1.24/config/request-routing.md (about)

     1  # Request Routing
     2  
     3  A HTTPProxy object must have at least one route or include defined.
     4  In this example, any requests to `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*` will be routed to the Service `s2`.
     5  All other requests to the host `multi-path.bar.com` will be routed to the Service `s1`.
     6  
     7  ```yaml
     8  # httpproxy-multiple-paths.yaml
     9  apiVersion: projectcontour.io/v1
    10  kind: HTTPProxy
    11  metadata:
    12    name: multiple-paths
    13    namespace: default
    14  spec:
    15    virtualhost:
    16      fqdn: multi-path.bar.com
    17    routes:
    18      - conditions:
    19        - prefix: / # matches everything else
    20        services:
    21          - name: s1
    22            port: 80
    23      - conditions:
    24        - prefix: /blog # matches `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*`
    25        services:
    26          - name: s2
    27            port: 80
    28  ```
    29  
    30  In the following example, we match on headers and send to different services, with a default route if those do not match.
    31  
    32  ```yaml
    33  # httpproxy-multiple-headers.yaml
    34  apiVersion: projectcontour.io/v1
    35  kind: HTTPProxy
    36  metadata:
    37    name: multiple-paths
    38    namespace: default
    39  spec:
    40    virtualhost:
    41      fqdn: multi-path.bar.com
    42    routes:
    43      - conditions:
    44        - header:
    45            name: x-os
    46            contains: ios
    47        services:
    48          - name: s1
    49            port: 80
    50      - conditions:
    51        - header:
    52            name: x-os
    53            contains: android
    54        services:
    55          - name: s2
    56            port: 80
    57      - services:
    58          - name: s3
    59            port: 80
    60  ```
    61  
    62  ## Conditions
    63  
    64  Each Route entry in a HTTPProxy **may** contain one or more conditions.
    65  These conditions are combined with an AND operator on the route passed to Envoy.
    66  Conditions can be either a `prefix` or a `header` condition.
    67  
    68  #### Prefix conditions
    69  
    70  Paths defined are matched using prefix conditions.
    71  Up to one prefix condition may be present in any condition block.
    72  
    73  Prefix conditions **must** start with a `/` if they are present.
    74  
    75  #### Header conditions
    76  
    77  For `header` conditions there is one required field, `name`, and six operator fields: `present`, `notpresent`, `contains`, `notcontains`, `exact`, and `notexact`.
    78  
    79  - `present` is a boolean and checks that the header is present. The value will not be checked.
    80  
    81  - `notpresent` similarly checks that the header is *not* present.
    82  
    83  - `contains` is a string, and checks that the header contains the string. `notcontains` similarly checks that the header does *not* contain the string.
    84  
    85  - `exact` is a string, and checks that the header exactly matches the whole string. `notexact` checks that the header does *not* exactly match the whole string.
    86  
    87  ## Request Redirection
    88  
    89  HTTP redirects can be implemented in HTTPProxy using `requestRedirectPolicy` on a route.
    90  In the following basic example, requests to `example.com` are redirected to `www.example.com`.
    91  We configure a root HTTPProxy for `example.com` that contains redirect configuration.
    92  We also configure a root HTTPProxy for `www.example.com` that represents the destination of the redirect.
    93  
    94  ```yaml
    95  apiVersion: projectcontour.io/v1
    96  kind: HTTPProxy
    97  metadata:
    98    name: example-com
    99  spec:
   100    virtualhost:
   101      fqdn: example.com
   102    routes:
   103      - conditions:
   104        - prefix: /
   105        requestRedirectPolicy:
   106          hostname: www.example.com
   107  ```
   108  
   109  ```yaml
   110  apiVersion: projectcontour.io/v1
   111  kind: HTTPProxy
   112  metadata:
   113    name: www-example-com
   114  spec:
   115    virtualhost:
   116      fqdn: www.example.com
   117    routes:
   118      - conditions:
   119        - prefix: /
   120        services:
   121          - name: s1
   122            port: 80
   123  ```
   124  
   125  In addition to specifying the hostname to set in the `location` header, the scheme, port, and returned status code of the redirect response can be configured.
   126  Configuration of the path or a path prefix replacement to modify the path of the returned `location` can be included as well.
   127  See [the API specification][3] for more detail.
   128  
   129  ## Multiple Upstreams
   130  
   131  One of the key HTTPProxy features is the ability to support multiple services for a given path:
   132  
   133  ```yaml
   134  # httpproxy-multiple-upstreams.yaml
   135  apiVersion: projectcontour.io/v1
   136  kind: HTTPProxy
   137  metadata:
   138    name: multiple-upstreams
   139    namespace: default
   140  spec:
   141    virtualhost:
   142      fqdn: multi.bar.com
   143    routes:
   144      - services:
   145          - name: s1
   146            port: 80
   147          - name: s2
   148            port: 80
   149  ```
   150  
   151  In this example, requests for `multi.bar.com/` will be load balanced across two Kubernetes Services, `s1`, and `s2`.
   152  This is helpful when you need to split traffic for a given URL across two different versions of an application.
   153  
   154  ### Upstream Weighting
   155  
   156  Building on multiple upstreams is the ability to define relative weights for upstream Services.
   157  This is commonly used for canary testing of new versions of an application when you want to send a small fraction of traffic to a specific Service.
   158  
   159  ```yaml
   160  # httpproxy-weight-shifting.yaml
   161  apiVersion: projectcontour.io/v1
   162  kind: HTTPProxy
   163  metadata:
   164    name: weight-shifting
   165    namespace: default
   166  spec:
   167    virtualhost:
   168      fqdn: weights.bar.com
   169    routes:
   170      - services:
   171          - name: s1
   172            port: 80
   173            weight: 10
   174          - name: s2
   175            port: 80
   176            weight: 90
   177  ```
   178  
   179  In this example, we are sending 10% of the traffic to Service `s1`, while Service `s2` receives the remaining 90% of traffic.
   180  
   181  HTTPProxy weighting follows some specific rules:
   182  
   183  - If no weights are specified for a given route, it's assumed even distribution across the Services.
   184  - Weights are relative and do not need to add up to 100. If all weights for a route are specified, then the "total" weight is the sum of those specified. As an example, if weights are 20, 30, 20 for three upstreams, the total weight would be 70. In this example, a weight of 30 would receive approximately 42.9% of traffic (30/70 = .4285).
   185  - If some weights are specified but others are not, then it's assumed that upstreams without weights have an implicit weight of zero, and thus will not receive traffic.
   186  
   187  ### Traffic mirroring
   188  
   189  Per route,  a service can be nominated as a mirror.
   190  The mirror service will receive a copy of the read traffic sent to any non mirror service.
   191  The mirror traffic is considered _read only_, any response by the mirror will be discarded.
   192  
   193  This service can be useful for recording traffic for later replay or for smoke testing new deployments.
   194  
   195  ```yaml
   196  apiVersion: projectcontour.io/v1
   197  kind: HTTPProxy
   198  metadata:
   199    name: traffic-mirror
   200    namespace: default
   201  spec:
   202    virtualhost:
   203      fqdn: www.example.com
   204    routes:
   205      - conditions:
   206        - prefix: /
   207        services:
   208          - name: www
   209            port: 80
   210          - name: www-mirror
   211            port: 80
   212            mirror: true
   213  ```
   214  
   215  ## Response Timeouts
   216  
   217  Each Route can be configured to have a timeout policy and a retry policy as shown:
   218  
   219  ```yaml
   220  # httpproxy-response-timeout.yaml
   221  apiVersion: projectcontour.io/v1
   222  kind: HTTPProxy
   223  metadata:
   224    name: response-timeout
   225    namespace: default
   226  spec:
   227    virtualhost:
   228      fqdn: timeout.bar.com
   229    routes:
   230    - timeoutPolicy:
   231        response: 1s
   232        idle: 10s
   233        idleConnection: 60s
   234      retryPolicy:
   235        count: 3
   236        perTryTimeout: 150ms
   237      services:
   238      - name: s1
   239        port: 80
   240  ```
   241  
   242  In this example, requests to `timeout.bar.com/` will have a response timeout policy of 1s.
   243  This refers to the time that spans between the point at which complete client request has been processed by the proxy, and when the response from the server has been completely processed.
   244  
   245  - `timeoutPolicy.response` Timeout for receiving a response from the server after processing a request from client.
   246  If not supplied, Envoy's default value of 15s applies.
   247  More information can be found in [Envoy's documentation][4].
   248  - `timeoutPolicy.idle` Timeout for how long the proxy should wait while there is no activity during single request/response (for HTTP/1.1) or stream (for HTTP/2).
   249  Timeout will not trigger while HTTP/1.1 connection is idle between two consecutive requests.
   250  If not specified, there is no per-route idle timeout, though a connection manager-wide stream idle timeout default of 5m still applies.
   251  More information can be found in [Envoy's documentation][6].
   252  - `timeoutPolicy.idleConnection` Timeout for how long connection from the proxy to the upstream service is kept when there are no active requests.
   253  If not supplied, Envoy’s default value of 1h applies.
   254  More information can be found in [Envoy's documentation][8].
   255  
   256  TimeoutPolicy durations are expressed in the Go [Duration format][5].
   257  Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
   258  The string "infinity" is also a valid input and specifies no timeout.
   259  A value of "0s" will be treated as if the field were not set, i.e. by using Envoy's default behavior.
   260  Example input values: "300ms", "5s", "1m".
   261  
   262  - `retryPolicy`: A retry will be attempted if the server returns an error code in the 5xx range, or if the server takes more than `retryPolicy.perTryTimeout` to process a request.
   263  
   264  - `retryPolicy.count` specifies the maximum number of retries allowed. This parameter is optional and defaults to 1. Set to -1 to disable. If set to 0, the Envoy default of 1 is used.
   265  
   266  - `retryPolicy.perTryTimeout` specifies the timeout per retry. If this field is greater than the request timeout, it is ignored. This parameter is optional.
   267    If left unspecified, `timeoutPolicy.request` will be used.
   268  
   269  ## Load Balancing Strategy
   270  
   271  Each route can have a load balancing strategy applied to determine which of its Endpoints is selected for the request.
   272  The following list are the options available to choose from:
   273  
   274  - `RoundRobin`: Each healthy upstream Endpoint is selected in round-robin order (Default strategy if none selected).
   275  - `WeightedLeastRequest`:  The least request load balancer uses different algorithms depending on whether hosts have the same or different weights in an attempt to route traffic based upon the number of active requests or the load at the time of selection. 
   276  - `Random`: The random strategy selects a random healthy Endpoints.
   277  - `RequestHash`: The request hashing strategy allows for load balancing based on request attributes. An upstream Endpoint is selected based on the hash of an element of a request. For example, requests that contain a consistent value in an HTTP request header will be routed to the same upstream Endpoint. Currently, only hashing of HTTP request headers, query parameters and the source IP of a request is supported.
   278  - `Cookie`: The cookie load balancing strategy is similar to the request hash strategy and is a convenience feature to implement session affinity, as described below.
   279  
   280  More information on the load balancing strategy can be found in [Envoy's documentation][7].
   281  
   282  The following example defines the strategy for the route `/` as `WeightedLeastRequest`.
   283  
   284  ```yaml
   285  # httpproxy-lb-strategy.yaml
   286  apiVersion: projectcontour.io/v1
   287  kind: HTTPProxy
   288  metadata:
   289    name: lb-strategy
   290    namespace: default
   291  spec:
   292    virtualhost:
   293      fqdn: strategy.bar.com
   294    routes:
   295      - conditions:
   296        - prefix: /
   297        services:
   298          - name: s1-strategy
   299            port: 80
   300          - name: s2-strategy
   301            port: 80
   302        loadBalancerPolicy:
   303          strategy: WeightedLeastRequest
   304  ```
   305  
   306  The below example demonstrates how request hash load balancing policies can be configured:
   307  
   308  Request hash headers
   309  ```yaml
   310  # httpproxy-lb-request-hash.yaml
   311  apiVersion: projectcontour.io/v1
   312  kind: HTTPProxy
   313  metadata:
   314    name: lb-request-hash
   315    namespace: default
   316  spec:
   317    virtualhost:
   318      fqdn: request-hash.bar.com
   319    routes:
   320    - conditions:
   321      - prefix: /
   322      services:
   323      - name: httpbin
   324        port: 8080
   325      loadBalancerPolicy:
   326        strategy: RequestHash
   327        requestHashPolicies:
   328        - headerHashOptions:
   329            headerName: X-Some-Header
   330          terminal: true
   331        - headerHashOptions:
   332            headerName: User-Agent
   333        - hashSourceIP: true
   334  ```
   335  In this example, if a client request contains the `X-Some-Header` header, the value of the header will be hashed and used to route to an upstream Endpoint. This could be used to implement a similar workflow to cookie-based session affinity by passing a consistent value for this header. If it is present, because it is set as a `terminal` hash option, Envoy will not continue on to process to `User-Agent` header or source IP to calculate a hash. If `X-Some-Header` is not present, Envoy will use the `User-Agent` header value to make a routing decision along with the source IP of the client making the request. These policies can be used alone or as shown for an advanced routing decision.
   336  
   337  
   338  Request hash source ip
   339  ```yaml
   340  # httpproxy-lb-request-hash-ip.yaml
   341  apiVersion: projectcontour.io/v1
   342  kind: HTTPProxy
   343  metadata:
   344    name: lb-request-hash 
   345    namespace: default
   346  spec:
   347    virtualhost:
   348      fqdn: request-hash.bar.com
   349    routes:
   350    - conditions:
   351      - prefix: /
   352      services:
   353      - name: httpbin
   354        port: 8080
   355      loadBalancerPolicy:
   356        strategy: RequestHash
   357        requestHashPolicies:
   358        - hashSourceIP: true
   359  ```
   360  
   361  Request hash query parameters
   362  ```yaml
   363  # httpproxy-lb-request-hash.yaml
   364  apiVersion: projectcontour.io/v1
   365  kind: HTTPProxy
   366  metadata:
   367    name: lb-request-hash 
   368    namespace: default
   369  spec:
   370    virtualhost:
   371      fqdn: request-hash.bar.com
   372    routes:
   373    - conditions:
   374      - prefix: /
   375      services:
   376      - name: httpbin
   377        port: 8080
   378      loadBalancerPolicy:
   379        strategy: RequestHash
   380        requestHashPolicies:
   381        - queryParameterHashOptions:
   382            prameterName: param1
   383          terminal: true
   384        - queryParameterHashOptions:
   385            parameterName: param2
   386  ```
   387  
   388  ## Session Affinity
   389  
   390  Session affinity, also known as _sticky sessions_, is a load balancing strategy whereby a sequence of requests from a single client are consistently routed to the same application backend.
   391  Contour supports session affinity on a per-route basis with `loadBalancerPolicy` `strategy: Cookie`.
   392  
   393  ```yaml
   394  # httpproxy-sticky-sessions.yaml
   395  apiVersion: projectcontour.io/v1
   396  kind: HTTPProxy
   397  metadata:
   398    name: httpbin
   399    namespace: default
   400  spec:
   401    virtualhost:
   402      fqdn: httpbin.davecheney.com
   403    routes:
   404    - services:
   405      - name: httpbin
   406        port: 8080
   407      loadBalancerPolicy:
   408        strategy: Cookie
   409  ```
   410  
   411  Session affinity is based on the premise that the backend servers are robust, do not change ordering, or grow and shrink according to load.
   412  None of these properties are guaranteed by a Kubernetes cluster and will be visible to applications that rely heavily on session affinity.
   413  
   414  Any perturbation in the set of pods backing a service risks redistributing backends around the hash ring.
   415  
   416  [3]: /docs/{{< param version >}}/config/api/#projectcontour.io/v1.HTTPRequestRedirectPolicy
   417  [4]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-timeout
   418  [5]: https://godoc.org/time#ParseDuration
   419  [6]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-idle-timeout
   420  [7]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/overview
   421  [8]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout