Skip to content
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

Merged
merged 24 commits into from
Jan 3, 2023
Merged

Ratelimiting Design #706

merged 24 commits into from
Jan 3, 2023

Conversation

arkodg
Copy link
Contributor

@arkodg arkodg commented Nov 7, 2022

Started a design doc highlighting the WHAT and WHY

Relates to #670

Signed-off-by: Arko Dasgupta [email protected]

@arkodg arkodg requested a review from a team as a code owner November 7, 2022 19:07
@arkodg arkodg added area/api API-related issues priority/high Label used to express the "high" priority level labels Nov 7, 2022
@arkodg arkodg added this to the 0.3.0-rc.1 milestone Nov 7, 2022
@arkodg
Copy link
Contributor Author

arkodg commented Nov 7, 2022

ive intentionally left the WHERE (which extension point does the Ratelimiting API get applied as) out of this document for now, will add info about it once we align on #675

@arkodg arkodg mentioned this pull request Nov 7, 2022
7 tasks
Copy link
Contributor

@danehans danehans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arkodg thanks for getting the RL work started. I think the doc provides good starting examples for an RL API but requires more detail to be considered a design.

docs/latest/design/ratelimit.md Outdated Show resolved Hide resolved
docs/latest/design/ratelimit.md Outdated Show resolved Hide resolved
docs/latest/design/ratelimit.md Show resolved Hide resolved
@arkodg
Copy link
Contributor Author

arkodg commented Nov 7, 2022

yah @danehans I'll push another commit with the exact API and kube builder annotations

@arkodg arkodg marked this pull request as draft November 7, 2022 19:46
@arkodg arkodg force-pushed the rl-api-design-intro branch from 0b21880 to 30205d9 Compare November 8, 2022 21:53
@arkodg arkodg marked this pull request as ready for review November 8, 2022 21:57
@arkodg arkodg force-pushed the rl-api-design-intro branch from 30205d9 to b2b066f Compare November 8, 2022 21:58
@arkodg arkodg changed the title Overview and examples for Ratelimiting Ratelimiting Design Nov 8, 2022
api/ratelimit/v1alpha1/ratelimit_types.go Outdated Show resolved Hide resolved
api/ratelimit/v1alpha1/ratelimit_types.go Outdated Show resolved Hide resolved
api/ratelimit/v1alpha1/ratelimit_types.go Outdated Show resolved Hide resolved
api/ratelimit/v1alpha1/ratelimit_types.go Outdated Show resolved Hide resolved
api/ratelimit/v1alpha1/ratelimit_types.go Outdated Show resolved Hide resolved
api/ratelimit/v1alpha1/ratelimit_types.go Outdated Show resolved Hide resolved
docs/latest/design/ratelimit.md Outdated Show resolved Hide resolved
docs/latest/design/ratelimit.md Outdated Show resolved Hide resolved
spec:
type: Global
rules:
- matches:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

matches is unneeded if RateLimit is applied to an HTTPRoute. For example:

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: example
spec:
  ...
  rules:
    - matches:
        headers:
          - name: x-user-tier
            value: one
      filters:
        - type: ExtensionRef
          extensionRef:
            group: gateway.envoyproxy.io
            kind: RateLimiting
            name: ratelimit-specific-requests
      backendRefs:
        - name: httpbin
          port: 80

Matching criteria can be derived from the HTTPRoute that references the RateLimiting filter and RateLimiting can define the rate limit policy, e.g. domain and descriptors (for type Global).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the matches criteria within HTTPRoute helps map a specific traffic flow to a destination backend.
Even though the RateLimit is linked to a specific HTTPRoute, the matches criteria here further maps the traffic to specific users (source ip, header etc)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels to me like this is the biggest decision here - adding an extra layer of matching inside the ratelimit filter rather than having it filter whatever is configured in the HTTPRoute is an interesting approach - it's not really what I expected when thinking about this, tbh.

@arkodg, do you think you could put some explanation in this doc (maybe in the decisions made section) as to why you've chosen this way rather than the one Daneyon suggested? I'm not saying we should change it, just that we should record the reasons we've decided this way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, ive added a section on it under Design Decisions

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with matches, I did a similar design in my personal project with another name (rules).

Signed-off-by: Arko Dasgupta <[email protected]>
Signed-off-by: Arko Dasgupta <[email protected]>
Signed-off-by: Arko Dasgupta <[email protected]>
Signed-off-by: Arko Dasgupta <[email protected]>
Signed-off-by: Arko Dasgupta <[email protected]>
Signed-off-by: Arko Dasgupta <[email protected]>
Signed-off-by: Arko Dasgupta <[email protected]>
Signed-off-by: Arko Dasgupta <[email protected]>
@arkodg arkodg force-pushed the rl-api-design-intro branch from e1e9cd5 to ef69423 Compare December 21, 2022 16:50
@arkodg arkodg requested a review from danehans December 21, 2022 16:50
// - "Exact": Use this type to match the exact value of the Value field against the value of the specified HTTP Header.
// - "RegularExpression": Use this type to match a regular expression against the value of the specified HTTP Header.
// 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.
Copy link
Contributor

@danehans danehans Dec 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me some time to understand the Distinct type. I have a feeling others will feel the same. What if we only supported Exact and RegularExpression? If Value is unspecified for Exact, then all values of name are selected.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as #706 (comment)

// +kubebuilder:default=Exact
Type *HeaderMatchType `json:"type,omitempty"`

// Name of the HTTP header.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we provide additional context to Name as Gateway API does, e.g. multiple rules with the same header name?

xref: https://github.com/kubernetes-sigs/gateway-api/blob/v0.6.0/apis/v1alpha2/grpcroute_types.go#L385-L389

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kflynn ^ comment is another candidate to resolve in a follow-on PR.


// 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment can be removed if we drop the Distinct type. See https://github.com/envoyproxy/gateway/pull/706/files#r1054657720 for additional details.

Copy link
Contributor

Choose a reason for hiding this comment

The 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 Distinct type? If not, it could be valuable to share our use case and get feedback.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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 v1alpha1 version.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know why Gateway API doesn't support the Distinct type?

"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

Signed-off-by: Arko Dasgupta <[email protected]>
Copy link
Member

@sunjayBhatia sunjayBhatia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a couple more questions on UX for a client:

  • Do we want to make the status code or headers a client sees when they are rate limited configurable? (Seems like there might be space as the API is today to leave this alone and add it later)
  • If the RLS is down/not responding, what behavior is expected, requests allowed to proceed or rejected? Should this be configurable per filter or globally? (I would err on globally if we do make it configurable but no real preference, depends on what users really need)

@arkodg
Copy link
Contributor Author

arkodg commented Dec 21, 2022

thanks for the reviews everyone, this PR has been commented on over 200 times highlighting a healthy debate.
Unfortunately even after addressing multiple suggestions, im unsure how to move this alpha API forward to completion that addresses the use cases outlined in the design doc.
ccing @danehans since you've commented with the requested changes option

@arkodg arkodg requested a review from danehans December 21, 2022 22:49
@danehans
Copy link
Contributor

@arkodg thanks for your patients while we work through this design. I think the design is very close but enough questions exist to warrant a discussion during the next community meeting. I added this to the agenda and I feel confident that we'll get this PR merged afterward.

@arkodg
Copy link
Contributor Author

arkodg commented Jan 3, 2023

@arkodg thanks for your patients while we work through this design. I think the design is very close but enough questions exist to warrant a discussion during the next community meeting. I added this to the agenda and I feel confident that we'll get this PR merged afterward.

sure @danehans, will answer your queries in the next community meeting if you prefer to raise them there instead of in this PR

Copy link
Contributor

@kflynn kflynn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After discussion in the 3 January meeting, let's merge this one and do some further doc cleanup after. Thanks for the patience, @arkodg!

Copy link
Contributor

@danehans danehans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arkodg thanks for all your work on the design and API! Please make sure to create an Issue/PR for the existing non-blocking review comments.

//
// +unionDiscriminator
Type RateLimitType `json:"type"`
// Global rate limit configuration.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be noted in the godocs that the global field is only applicable for type Global. I understand that Global is the only type currently supported but this will prevent confusion when other types, e.g. Local, are supported in the future. @arkodg please note this in the follow-on issue or @kflynn please resolve this in your PR.

Comment on lines +63 to +67
// 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.
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

api/v1alpha1/ratelimitfilter_types.go Show resolved Hide resolved
// +kubebuilder:default=Exact
Type *HeaderMatchType `json:"type,omitempty"`

// Name of the HTTP header.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kflynn ^ comment is another candidate to resolve in a follow-on PR.

// * "Day"
//
// +kubebuilder:validation:Enum=Second;Minute;Hour;Day
type RateLimitUnit string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arkodg constants should be defined for the ^ enums. For example:

const (
	// SecondRateLimitUnit defines the "Second" rate limit unit.
	SecondRateLimitUnit RateLimitUnit = "Second"

	...
)

cc: @kflynn

@danehans danehans merged commit 4fdbb22 into envoyproxy:main Jan 3, 2023
@arkodg arkodg deleted the rl-api-design-intro branch April 20, 2023 16:31
@arkodg arkodg mentioned this pull request Dec 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/api API-related issues priority/high Label used to express the "high" priority level
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants