github.com/projectcontour/contour@v1.28.2/site/content/docs/v1.14.0/config/rate-limiting.md (about)

     1  # Rate Limiting
     2  
     3  - [Overview](#overview)
     4  - [Local Rate Limiting](#local-rate-limiting)
     5  - [Global Rate Limiting](#global-rate-limiting)
     6  
     7  ## Overview
     8  
     9  Rate limiting is a means of protecting backend services against unwanted traffic.
    10  This can be useful for a variety of different scenarios:
    11  
    12  - Protecting against denial-of-service (DoS) attacks by malicious actors
    13  - Protecting against DoS incidents due to bugs in client applications/services
    14  - Enforcing usage quotas for different classes of clients, e.g. free vs. paid tiers
    15  - Controlling resource consumption/cost
    16  
    17  Envoy supports two forms of HTTP rate limiting: **local** and **global**.
    18  
    19  In local rate limiting, rate limits are enforced by each Envoy instance, without any communication with other Envoys or any external service.
    20  
    21  In global rate limiting, an external rate limit service (RLS) is queried by each Envoy via gRPC for rate limit decisions.
    22  
    23  Contour supports both forms of Envoy's rate limiting.
    24  
    25  ## Local Rate Limiting
    26  
    27  The `HTTPProxy` API supports defining local rate limit policies that can be applied to either individual routes or entire virtual hosts.
    28  Local rate limit policies define a maximum number of requests per unit of time that an Envoy should proxy to the upstream service.
    29  Requests beyond the defined limit will receive a `429 (Too Many Requests)` response by default.
    30  Local rate limit policies program Envoy's [HTTP local rate limit filter][1].
    31  
    32  It's important to note that local rate limit policies apply *per Envoy pod*.
    33  For example, a local rate limit policy of 100 requests per second for a given route will result in *each Envoy pod* allowing up to 100 requests per second for that route.
    34  
    35  ### Defining a local rate limit
    36  
    37  Local rate limit policies can be defined for either routes or virtual hosts. A local rate limit policy requires a `requests` and a `units` field, defining the *number of requests per unit of time* that are allowed. `Requests` must be a positive integer, and `units` can be `second`, `minute`, or `hour`. Optionally, a `burst` parameter can also be provided, defining the number of requests above the baseline rate that are allowed in a short period of time. This would allow occasional larger bursts of traffic not to be rate limited.
    38  
    39  Local rate limiting for the virtual host:
    40  ```yaml
    41  apiVersion: projectcontour.io/v1
    42  kind: HTTPProxy
    43  metadata:
    44    namespace: default
    45    name: ratelimited-vhost
    46  spec:
    47    virtualhost:
    48      fqdn: local.projectcontour.io
    49      rateLimitPolicy:
    50        local:
    51          requests: 100
    52          unit: hour
    53          burst: 20
    54    routes:
    55    - conditions:
    56      - prefix: /s1
    57      services:
    58      - name: s1
    59        port: 80
    60    - conditions:
    61      - prefix: /s2
    62      services:
    63      - name: s2
    64        port: 80
    65  ```
    66  
    67  Local rate limiting for the route:
    68  ```yaml
    69  apiVersion: projectcontour.io/v1
    70  kind: HTTPProxy
    71  metadata:
    72    namespace: default
    73    name: ratelimited-route
    74  spec:
    75    virtualhost:
    76      fqdn: local.projectcontour.io
    77    routes:
    78    - conditions:
    79      - prefix: /s1
    80      services:
    81      - name: s1
    82        port: 80
    83      rateLimitPolicy:
    84        local:
    85          requests: 20
    86          unit: minute
    87    - conditions:
    88      - prefix: /s2
    89      services:
    90      - name: s2
    91        port: 80
    92  ```
    93  
    94  ### Customizing the response
    95  
    96  #### Response code
    97  
    98  By default, Envoy returns a `429 (Too Many Requests)` when a request is rate limited.
    99  A non-default response code can optionally be configured as part of the local rate limit policy, in the `responseStatusCode` field.
   100  The value must be in the 400-599 range.
   101  
   102  ```yaml
   103  apiVersion: projectcontour.io/v1
   104  kind: HTTPProxy
   105  metadata:
   106    namespace: default
   107    name: custom-ratelimit-response
   108  spec:
   109    virtualhost:
   110      fqdn: local.projectcontour.io
   111    routes:
   112    - conditions:
   113      - prefix: /s1
   114      services:
   115      - name: s1
   116        port: 80
   117      rateLimitPolicy:
   118        local:
   119          requests: 20
   120          unit: minute
   121          responseStatusCode: 503 # Service Unavailable 
   122  ```
   123  
   124  #### Headers
   125  
   126  Headers can optionally be added to rate limited responses, by configuring the `responseHeadersToAdd` field.
   127  
   128  ```yaml
   129  apiVersion: projectcontour.io/v1
   130  kind: HTTPProxy
   131  metadata:
   132    namespace: default
   133    name: custom-ratelimit-response
   134  spec:
   135    virtualhost:
   136      fqdn: local.projectcontour.io
   137    routes:
   138    - conditions:
   139      - prefix: /s1
   140      services:
   141      - name: s1
   142        port: 80
   143      rateLimitPolicy:
   144        local:
   145          requests: 20
   146          unit: minute
   147          responseHeadersToAdd:
   148          - name: x-contour-ratelimited
   149            value: "true"
   150  ```
   151  
   152  ## Global Rate Limiting
   153  
   154  The `HTTPProxy` API also supports defining global rate limit policies on routes and virtual hosts.
   155  
   156  In order to use global rate limiting, you must first select and deploy an external rate limit service (RLS).
   157  There is an [Envoy rate limit service implementation][2], but any service that implements the [RateLimitService gRPC interface][3] is supported.
   158  
   159  ### Configuring an external RLS with Contour
   160  
   161  Once you have deployed your RLS, you must configure it with Contour.
   162  
   163  Define an extension service for it (substituting values as appropriate):
   164  ```yaml
   165  apiVersion: projectcontour.io/v1alpha1
   166  kind: ExtensionService
   167  metadata:
   168    namespace: projectcontour
   169    name: ratelimit
   170  spec:
   171    protocol: h2
   172    services:
   173      - name: ratelimit
   174        port: 8081
   175  ```
   176  
   177  Now add a reference to it in the Contour config file:
   178  ```yaml
   179  rateLimitService:
   180    # The namespace/name of the extension service.
   181    extensionService: projectcontour/ratelimit
   182    # The domain value to pass to the RLS for all rate limit
   183    # requests. Acts as a container for a set of rate limit
   184    # definitions within the RLS.
   185    domain: contour
   186    # Whether to allow requests to proceed when the rate limit
   187    # service fails to respond with a valid rate limit decision
   188    # within the timeout defined on the extension service.
   189    failOpen: true
   190  ```
   191  
   192  ### Defining a global rate limit policy
   193  
   194  Global rate limit policies can be defined for either routes or virtual hosts. Unlike local rate limit policies, global rate limit policies do not directly define a rate limit. Instead, they define a set of request descriptors that will be generated and sent to the external RLS for each request. The external RLS then makes the rate limit decision based on the descriptors and returns a response to Envoy.
   195  
   196  A global rate limit policy for the virtual host:
   197  ```yaml
   198  apiVersion: projectcontour.io/v1
   199  kind: HTTPProxy
   200  metadata:
   201    namespace: default
   202    name: ratelimited-vhost
   203  spec:
   204    virtualhost:
   205      fqdn: local.projectcontour.io
   206      rateLimitPolicy:
   207        global:
   208          descriptors:
   209            # the first descriptor has a single key-value pair:
   210            # [ remote_address=<client IP> ].
   211            - entries:
   212                - remoteAddress: {}
   213            # the second descriptor has two key-value pairs:
   214            # [ remote_address=<client IP>, vhost=local.projectcontour.io ].
   215            - entries:
   216                - remoteAddress: {}
   217                - genericKey:
   218                    key: vhost
   219                    value: local.projectcontour.io
   220    routes:
   221    - conditions:
   222      - prefix: /s1
   223      services:
   224      - name: s1
   225        port: 80
   226    - conditions:
   227      - prefix: /s2
   228      services:
   229      - name: s2
   230        port: 80
   231  ```
   232  
   233  A global rate limit policy for the route:
   234  ```yaml
   235  apiVersion: projectcontour.io/v1
   236  kind: HTTPProxy
   237  metadata:
   238    namespace: default
   239    name: ratelimited-route
   240  spec:
   241    virtualhost:
   242      fqdn: local.projectcontour.io
   243    routes:
   244    - conditions:
   245      - prefix: /s1
   246      services:
   247      - name: s1
   248        port: 80
   249      rateLimitPolicy:
   250        global:
   251          descriptors:
   252            # the first descriptor has a single key-value pair:
   253            # [ remote_address=<client IP> ].
   254            - entries:
   255                - remoteAddress: {}
   256            # the second descriptor has two key-value pairs:
   257            # [ remote_address=<client IP>, prefix=/s1 ].
   258            - entries:
   259                - remoteAddress: {}
   260                - genericKey:
   261                    key: prefix
   262                    value: /s1
   263    - conditions:
   264      - prefix: /s2
   265      services:
   266      - name: s2
   267        port: 80
   268  ```
   269  
   270  [1]: https://www.envoyproxy.io/docs/envoy/v1.17.0/configuration/http/http_filters/local_rate_limit_filter#config-http-filters-local-rate-limit
   271  [2]: https://github.com/envoyproxy/ratelimit
   272  [3]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/ratelimit/v3/rls.proto