-
Notifications
You must be signed in to change notification settings - Fork 716
Ratelimiting Design #706
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ratelimiting Design #706
Changes from all commits
512bd51
601b619
354f362
60f389c
ed1668e
5e878de
d21ca73
e1eae88
ddadb3c
7bce4c5
2fd08cf
e7fde63
e935c74
439ed9e
543b1a2
e85c65d
199bf5f
7562b5b
9db2623
25e5b6c
1e33d4d
090dc02
ef69423
364b0c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,164 @@ | ||
| // Copyright Envoy Gateway Authors | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // The full text of the Apache license is available in the LICENSE file at | ||
| // the root of the repo. | ||
|
|
||
| package v1alpha1 | ||
|
|
||
| import ( | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| ) | ||
|
|
||
| // +kubebuilder:object:root=true | ||
| // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` | ||
|
|
||
| // RateLimitFilter allows the user to limit the number of incoming requests | ||
| // to a predefined value based on attributes within the traffic flow. | ||
| type RateLimitFilter struct { | ||
| metav1.TypeMeta `json:",inline"` | ||
| metav1.ObjectMeta `json:"metadata,omitempty"` | ||
|
|
||
| // Spec defines the desired state of RateLimitFilter. | ||
| Spec RateLimitFilterSpec `json:"spec"` | ||
| } | ||
|
|
||
| // +kubebuilder:object:root=true | ||
|
|
||
| // RateLimitFilterList contains a list of RateLimitFilter resources. | ||
| type RateLimitList struct { | ||
| metav1.TypeMeta `json:",inline"` | ||
| metav1.ListMeta `json:"metadata,omitempty"` | ||
| Items []RateLimitFilter `json:"items"` | ||
| } | ||
|
|
||
| // RateLimitFilterSpec defines the desired state of RateLimitFilter. | ||
| // +union | ||
| type RateLimitFilterSpec struct { | ||
| // Type decides the scope for the RateLimits. | ||
| // Valid RateLimitType values are: | ||
| // | ||
| // * "Global" - In this mode, the rate limits are applied across all Envoy proxy instances. | ||
| // | ||
| // +unionDiscriminator | ||
| Type RateLimitType `json:"type"` | ||
| // Global rate limit configuration. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should be noted in the godocs that the |
||
| // | ||
| // +optional | ||
| Global *GlobalRateLimit `json:"global,omitempty"` | ||
| } | ||
|
|
||
| // RateLimitType specifies the types of RateLimiting. | ||
| // +kubebuilder:validation:Enum=Global | ||
| type RateLimitType string | ||
|
|
||
| const ( | ||
| // GlobalRateLimitType allows the rate limits to be applied across all Envoy proxy instances. | ||
| GlobalRateLimitType RateLimitType = "Global" | ||
| ) | ||
|
|
||
| // GlobalRateLimit defines the global rate limit configuration. | ||
| type GlobalRateLimit struct { | ||
| // Rules are a list of RateLimit selectors and limits. | ||
| // Each rule and its associated limit is applied | ||
|
||
| // in a mutually exclusive way i.e. if multiple | ||
| // rules get selected, each of their associated | ||
| // limits get applied, so a single traffic request | ||
| // might increase the rate limit counters for multiple | ||
| // rules if selected. | ||
|
Comment on lines
+63
to
+67
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kflynn it would be appreciated if you can improve the godocs for this field. |
||
| // | ||
| // +kubebuilder:validation:MaxItems=16 | ||
| Rules []RateLimitRule `json:"rules"` | ||
| } | ||
|
|
||
| // RateLimitRule defines the semantics for matching attributes | ||
| // from the incoming requests, and setting limits for them. | ||
| type RateLimitRule struct { | ||
| // ClientSelectors holds the list of select conditions to select | ||
| // specific clients using attributes from the traffic flow. | ||
| // All individual select conditions must hold True for this rule | ||
| // and its limit to be applied. | ||
| // If this field is empty, it is equivalent to True, and | ||
| // the limit is applied. | ||
| // | ||
| // +optional | ||
| // +kubebuilder:validation:MaxItems=8 | ||
| ClientSelectors []RateLimitSelectCondition `json:"clientSelectors,omitempty"` | ||
| // Limit holds the rate limit values. | ||
| // This limit is applied for traffic flows when the selectors | ||
| // compute to True, causing the request to be counted towards the limit. | ||
| // The limit is enforced and the request is ratelimited, i.e. a response with | ||
| // 429 HTTP status code is sent back to the client when | ||
| // the selected requests have reached the limit. | ||
| Limit RateLimitValue `json:"limit"` | ||
| } | ||
|
|
||
| // RateLimitSelectCondition specifies the attributes within the traffic flow that can | ||
| // be used to select a subset of clients to be ratelimited. | ||
| // All the individual conditions must hold True for the overall condition to hold True. | ||
| type RateLimitSelectCondition struct { | ||
| // Headers is a list of request headers to match. Multiple header values are ANDed together, | ||
| // meaning, a request MUST match all the specified headers. | ||
| // | ||
| // +listType=map | ||
| // +listMapKey=name | ||
| // +optional | ||
| // +kubebuilder:validation:MaxItems=16 | ||
| Headers []HeaderMatch `json:"headers,omitempty"` | ||
arkodg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| // HeaderMatch defines the match attributes within the HTTP Headers of the request. | ||
| type HeaderMatch struct { | ||
arkodg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // Type specifies how to match against the value of the header. | ||
| // | ||
| // +optional | ||
| // +kubebuilder:default=Exact | ||
| Type *HeaderMatchType `json:"type,omitempty"` | ||
|
|
||
| // Name of the HTTP header. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we provide additional context to
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kflynn ^ comment is another candidate to resolve in a follow-on PR. |
||
| // +kubebuilder:validation:MinLength=1 | ||
| // +kubebuilder:validation:MaxLength=256 | ||
| Name string `json:"name"` | ||
arkodg marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // Value within the HTTP header. Due to the | ||
| // case-insensitivity of header names, "foo" and "Foo" are considered equivalent. | ||
| // Do not set this field when Type="Distinct", implying matching on any/all unique values within the header. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment can be removed if we drop the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two of the three header matching types proposed in this PR are the same as upstream Gateway API. Do you know why Gateway API doesn't support the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. its naming as well as use case has already been upvoted by reviewers, so I feel strongly to keep it, and proactively present it to the users, and get feedback for this
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
"Distinct" isn't really a matching mechanism per se, but rather denotes that each unique value for a header the RLS sees will get its own rate limiting bucket, which doesn't really fit into the idea of matching request attributes to funnel to a backend |
||
| // +optional | ||
| // +kubebuilder:validation:MaxLength=1024 | ||
| Value *string `json:"value,omitempty"` | ||
arkodg marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| // HeaderMatchType specifies the semantics of how HTTP header values should be | ||
| // compared. Valid HeaderMatchType values are: | ||
| // | ||
| // - "Exact": Use this type to match the exact value of the Value field against the value of the specified HTTP Header. | ||
arkodg marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // - "RegularExpression": Use this type to match a regular expression against the value of the specified HTTP Header. | ||
arkodg marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // The regex string must adhere to the syntax documented in https://github.com/google/re2/wiki/Syntax. | ||
| // - "Distinct": Use this type to match any and all possible unique values encountered in the specified HTTP Header. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It took me some time to understand the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as #706 (comment) |
||
| // Note that each unique value will receive its own rate limit bucket. | ||
| // | ||
| // +kubebuilder:validation:Enum=Exact;RegularExpression;Distinct | ||
| type HeaderMatchType string | ||
|
|
||
| // HeaderMatchType constants. | ||
| const ( | ||
| HeaderMatchExact HeaderMatchType = "Exact" | ||
| HeaderMatchRegularExpression HeaderMatchType = "RegularExpression" | ||
| HeaderMatchDistinct HeaderMatchType = "Distinct" | ||
| ) | ||
|
|
||
| // RateLimitValue defines the limits for rate limiting. | ||
| type RateLimitValue struct { | ||
| Requests uint `json:"requests"` | ||
| Unit RateLimitUnit `json:"unit"` | ||
| } | ||
|
|
||
| // RateLimitUnit specifies the intervals for setting rate limits. | ||
| // Valid RateLimitUnit values are: | ||
| // | ||
| // * "Second" | ||
| // * "Minute" | ||
| // * "Hour" | ||
| // * "Day" | ||
| // | ||
| // +kubebuilder:validation:Enum=Second;Minute;Hour;Day | ||
| type RateLimitUnit string | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.