-
Notifications
You must be signed in to change notification settings - Fork 665
feat(loadbalancer): Add LoadBalancerType Client Side Weighted Round Robin #7407
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
base: main
Are you sure you want to change the base?
Changes from all commits
971c3f1
a9d01f0
63e8b2f
522534b
4512f9d
dd5d285
1101c1d
14d1d59
8bce886
0d65b01
a479e67
777a1c1
b88903c
234cffa
d012b11
44bfe7b
7edc401
84a0942
afb690d
3785264
6321ec4
05016c4
7d7528f
870c52c
1fa3ff3
c3e06cb
9c9dc20
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 |
|---|---|---|
|
|
@@ -11,15 +11,17 @@ import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" | |
| // +union | ||
| // | ||
| // +kubebuilder:validation:XValidation:rule="self.type == 'ConsistentHash' ? has(self.consistentHash) : !has(self.consistentHash)",message="If LoadBalancer type is consistentHash, consistentHash field needs to be set." | ||
| // +kubebuilder:validation:XValidation:rule="self.type in ['Random', 'ConsistentHash'] ? !has(self.slowStart) : true ",message="Currently SlowStart is only supported for RoundRobin and LeastRequest load balancers." | ||
| // +kubebuilder:validation:XValidation:rule="self.type == 'ConsistentHash' ? !has(self.zoneAware) : true ",message="Currently ZoneAware is only supported for LeastRequest, Random, and RoundRobin load balancers." | ||
| // +kubebuilder:validation:XValidation:rule="self.type == 'BackendUtilization' ? has(self.backendUtilization) : !has(self.backendUtilization)",message="If LoadBalancer type is BackendUtilization, backendUtilization field needs to be set." | ||
| // +kubebuilder:validation:XValidation:rule="self.type in ['Random', 'ConsistentHash'] ? !has(self.slowStart) : true ",message="Currently SlowStart is only supported for RoundRobin, LeastRequest, and BackendUtilization load balancers." | ||
| // +kubebuilder:validation:XValidation:rule="self.type in ['ConsistentHash', 'BackendUtilization'] ? !has(self.zoneAware) : true ",message="Currently ZoneAware is only supported for LeastRequest, Random, and RoundRobin load balancers." | ||
| type LoadBalancer struct { | ||
| // Type decides the type of Load Balancer policy. | ||
| // Valid LoadBalancerType values are | ||
| // "ConsistentHash", | ||
| // "LeastRequest", | ||
| // "Random", | ||
| // "RoundRobin". | ||
| // "RoundRobin", | ||
| // "BackendUtilization". | ||
| // | ||
| // +unionDiscriminator | ||
| Type LoadBalancerType `json:"type"` | ||
|
|
@@ -29,6 +31,12 @@ type LoadBalancer struct { | |
| // +optional | ||
| ConsistentHash *ConsistentHash `json:"consistentHash,omitempty"` | ||
|
|
||
| // BackendUtilization defines the configuration when the load balancer type is | ||
| // set to BackendUtilization. | ||
| // | ||
| // +optional | ||
| BackendUtilization *BackendUtilization `json:"backendUtilization,omitempty"` | ||
|
|
||
| // EndpointOverride defines the configuration for endpoint override. | ||
| // When specified, the load balancer will attempt to route requests to endpoints | ||
| // based on the override information extracted from request headers or metadata. | ||
|
|
@@ -39,7 +47,7 @@ type LoadBalancer struct { | |
|
|
||
| // SlowStart defines the configuration related to the slow start load balancer policy. | ||
| // If set, during slow start window, traffic sent to the newly added hosts will gradually increase. | ||
| // Currently this is only supported for RoundRobin and LeastRequest load balancers | ||
| // Supported for RoundRobin, LeastRequest, and BackendUtilization load balancers. | ||
| // | ||
| // +optional | ||
| SlowStart *SlowStart `json:"slowStart,omitempty"` | ||
|
|
@@ -51,7 +59,7 @@ type LoadBalancer struct { | |
| } | ||
|
|
||
| // LoadBalancerType specifies the types of LoadBalancer. | ||
| // +kubebuilder:validation:Enum=ConsistentHash;LeastRequest;Random;RoundRobin | ||
| // +kubebuilder:validation:Enum=ConsistentHash;LeastRequest;Random;RoundRobin;BackendUtilization | ||
| type LoadBalancerType string | ||
|
|
||
| const ( | ||
|
|
@@ -63,6 +71,8 @@ const ( | |
| RandomLoadBalancerType LoadBalancerType = "Random" | ||
| // RoundRobinLoadBalancerType load balancer policy. | ||
| RoundRobinLoadBalancerType LoadBalancerType = "RoundRobin" | ||
| // BackendUtilizationLoadBalancerType load balancer policy. | ||
| BackendUtilizationLoadBalancerType LoadBalancerType = "BackendUtilization" | ||
| ) | ||
|
|
||
| // ConsistentHash defines the configuration related to the consistent hash | ||
|
|
@@ -148,6 +158,63 @@ type Cookie struct { | |
| Attributes map[string]string `json:"attributes,omitempty"` | ||
| } | ||
|
|
||
| // BackendUtilization defines configuration for Envoy's Backend Utilization policy. | ||
| // It uses Open Resource Cost Application (ORCA) load metrics reported by endpoints to make load balancing decisions. | ||
| // These metrics are typically sent by the backend service in response headers or trailers. | ||
| // | ||
| // The backend should report these metrics in header/trailer as one of the following formats: | ||
| // - Binary: `endpoint-load-metrics-bin` with base64-encoded serialized `OrcaLoadReport` proto. | ||
| // - JSON: `endpoint-load-metrics` with JSON-encoded `OrcaLoadReport` proto, e.g., `JSON {"cpu_utilization": 0.3}`. | ||
| // - TEXT: `endpoint-load-metrics` with comma-separated key-value pairs, e.g., `TEXT cpu=0.3,mem=0.8`. | ||
| // | ||
| // By default, Envoy will forward these ORCA response headers/trailers from the upstream service to the downstream client. | ||
| // If the downstream client also uses this information for load balancing, it might lead to unexpected behavior. | ||
| // To avoid this, you can use the `HTTPRoute` or `BackendTrafficPolicy` to remove the load report headers before sending the response to the client. | ||
altaiezior marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // | ||
| // See Envoy proto: envoy.extensions.load_balancing_policies.client_side_weighted_round_robin.v3.ClientSideWeightedRoundRobin | ||
|
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. tbh https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.proto is not descriptive enough, and doesnt mention how this needs to be instrumented in the upstream, are there other links than can be used
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. Yeah the docs aren't great... for example out-of-band reporting isn't supported at all yet reading the docs would indicate otherwise. We could contribute some docs changes upstream but agreed that including a reference to how
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. @arkodg what changes would you suggest me to add here? This is a bit more elaborative document https://docs.cloud.google.com/load-balancing/docs/https/applb-custom-metrics although this can also be confusing and gcp specific.
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. do any docs exist that explain how a backend / server should be enhanced to send the appropriate trailors in the response ?
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. There is a google doc I will have to find it though but nothing stated officially as far I am aware of
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. we should consider adding one if it doesnt exist 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. Ack, this is good feedback on the docs gaps. I'll work with @efimki on this.
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. thanks @AndresGuedez ! Happy to be the beta tester
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 is specific to google but some of their descriptions on ORCA/custom metrics may be helpful for the EG API fields - https://docs.cloud.google.com/load-balancing/docs/https/applb-custom-metrics#configure-custom-metrics That's not an explicit ask to make changes but give this a read. |
||
| // See ORCA Load Report proto: xds.data.orca.v3.orca_load_report.proto | ||
| type BackendUtilization struct { | ||
| // A given endpoint must report load metrics continuously for at least this long before the endpoint weight will be used. | ||
altaiezior marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // Default is 10s. | ||
| // +optional | ||
| BlackoutPeriod *gwapiv1.Duration `json:"blackoutPeriod,omitempty"` | ||
|
|
||
| // If a given endpoint has not reported load metrics in this long, stop using the reported weight. Defaults to 3m. | ||
| // +optional | ||
| WeightExpirationPeriod *gwapiv1.Duration `json:"weightExpirationPeriod,omitempty"` | ||
|
|
||
| // How often endpoint weights are recalculated. Values less than 100ms are capped at 100ms. Default 1s. | ||
| // +optional | ||
| WeightUpdatePeriod *gwapiv1.Duration `json:"weightUpdatePeriod,omitempty"` | ||
|
|
||
| // ErrorUtilizationPenaltyPercent adjusts endpoint weights based on the error rate (eps/qps). | ||
| // This is expressed as a percentage-based integer where 100 represents 1.0, 150 represents 1.5, etc. | ||
| // | ||
| // For example: | ||
| // - 100 => 1.0x | ||
| // - 120 => 1.2x | ||
| // - 200 => 2.0x | ||
| // | ||
| // Note: In the internal IR/XDS configuration this value is converted back to a | ||
| // floating point multiplier (value / 100.0). | ||
| // | ||
| // Must be non-negative. | ||
| // +kubebuilder:validation:Minimum=0 | ||
| // +optional | ||
| ErrorUtilizationPenaltyPercent *uint32 `json:"errorUtilizationPenaltyPercent,omitempty"` | ||
|
|
||
| // Metric names used to compute utilization if application_utilization is not set. | ||
| // For map fields in ORCA proto, use the form "<map_field>.<key>", e.g., "named_metrics.foo". | ||
| // +optional | ||
| MetricNamesForComputingUtilization []string `json:"metricNamesForComputingUtilization,omitempty"` | ||
|
|
||
| // RemoveResponseHeaders removes the ORCA load report headers/trailers before sending the response to the client. | ||
|
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. if we are removing by default, should we change the field name to
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. Sure let me know if I have to make the changes, I also forgot to reframe the documentation here
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. yeah prefer |
||
| // Defaults to true. | ||
| // +optional | ||
| // +kubebuilder:default=true | ||
| RemoveResponseHeaders *bool `json:"removeResponseHeaders,omitempty"` | ||
| } | ||
|
|
||
| // ConsistentHashType defines the type of input to hash on. | ||
| // +kubebuilder:validation:Enum=SourceIP;Header;Headers;Cookie;QueryParams | ||
| type ConsistentHashType string | ||
|
|
||
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.