Skip to content

Commit 483e17a

Browse files
committed
feat: support host override policy based routing
Signed-off-by: bitliu <bitliu@tencent.com>
1 parent 3aee7a6 commit 483e17a

File tree

36 files changed

+7530
-205
lines changed

36 files changed

+7530
-205
lines changed

api/v1alpha1/loadbalancer_types.go

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1111
// +union
1212
//
1313
// +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."
14-
// +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."
15-
// +kubebuilder:validation:XValidation:rule="self.type == 'ConsistentHash' ? !has(self.zoneAware) : true ",message="Currently ZoneAware is only supported for LeastRequest, Random, and RoundRobin load balancers."
14+
// +kubebuilder:validation:XValidation:rule="self.type == 'HostOverride' ? has(self.hostOverrideSettings) : !has(self.hostOverrideSettings)",message="If LoadBalancer type is HostOverride, hostOverrideSettings field needs to be set."
15+
// +kubebuilder:validation:XValidation:rule="self.type in ['Random', 'ConsistentHash', 'HostOverride'] ? !has(self.slowStart) : true ",message="Currently SlowStart is only supported for RoundRobin and LeastRequest load balancers."
16+
// +kubebuilder:validation:XValidation:rule="self.type in ['ConsistentHash', 'HostOverride'] ? !has(self.zoneAware) : true ",message="Currently ZoneAware is only supported for LeastRequest, Random, and RoundRobin load balancers."
1617
type LoadBalancer struct {
1718
// Type decides the type of Load Balancer policy.
1819
// Valid LoadBalancerType values are
1920
// "ConsistentHash",
2021
// "LeastRequest",
2122
// "Random",
22-
// "RoundRobin".
23+
// "RoundRobin",
24+
// "HostOverride".
2325
//
2426
// +unionDiscriminator
2527
Type LoadBalancerType `json:"type"`
@@ -29,6 +31,12 @@ type LoadBalancer struct {
2931
// +optional
3032
ConsistentHash *ConsistentHash `json:"consistentHash,omitempty"`
3133

34+
// HostOverrideSettings defines the configuration when the load balancer type is
35+
// set to HostOverride
36+
//
37+
// +optional
38+
HostOverrideSettings *HostOverrideSettings `json:"hostOverrideSettings,omitempty"`
39+
3240
// SlowStart defines the configuration related to the slow start load balancer policy.
3341
// If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
3442
// Currently this is only supported for RoundRobin and LeastRequest load balancers
@@ -44,7 +52,7 @@ type LoadBalancer struct {
4452
}
4553

4654
// LoadBalancerType specifies the types of LoadBalancer.
47-
// +kubebuilder:validation:Enum=ConsistentHash;LeastRequest;Random;RoundRobin
55+
// +kubebuilder:validation:Enum=ConsistentHash;LeastRequest;Random;RoundRobin;HostOverride
4856
type LoadBalancerType string
4957

5058
const (
@@ -56,6 +64,8 @@ const (
5664
RandomLoadBalancerType LoadBalancerType = "Random"
5765
// RoundRobinLoadBalancerType load balancer policy.
5866
RoundRobinLoadBalancerType LoadBalancerType = "RoundRobin"
67+
// HostOverrideLoadBalancerType load balancer policy.
68+
HostOverrideLoadBalancerType LoadBalancerType = "HostOverride"
5969
)
6070

6171
// ConsistentHash defines the configuration related to the consistent hash
@@ -178,3 +188,68 @@ type ForceLocalZone struct {
178188
// +notImplementedHide
179189
MinEndpointsInZoneThreshold *uint32 `json:"minEndpointsInZoneThreshold,omitempty"`
180190
}
191+
192+
// HostOverrideSettings defines the configuration for the Host Override load balancer policy.
193+
// This policy allows endpoint picking to be implemented in downstream HTTP filters.
194+
// It extracts selected override hosts from a list of OverrideHostSource (request headers, metadata, etc.).
195+
// If no valid host in the override host list, then the specified fallback load balancing policy is used.
196+
type HostOverrideSettings struct {
197+
// OverrideHostSources defines a list of sources to get host addresses from.
198+
// The host sources are searched in the order specified.
199+
// The request is forwarded to the first address and subsequent addresses are used for request retries or hedging.
200+
// Note that if an overridden host address is not present in the current endpoint set, it is skipped and the next found address is used.
201+
// If there are not enough overridden addresses to satisfy all retry attempts the fallback load balancing policy is used to pick a host.
202+
//
203+
// +kubebuilder:validation:MinItems=1
204+
// +kubebuilder:validation:MaxItems=10
205+
OverrideHostSources []OverrideHostSource `json:"overrideHostSources"`
206+
207+
// FallbackPolicy defines the child LB policy to use in case neither header nor metadata with selected hosts is present.
208+
// If not specified, defaults to LeastRequest.
209+
//
210+
// +optional
211+
// +kubebuilder:default="LeastRequest"
212+
FallbackPolicy *LoadBalancerType `json:"fallbackPolicy,omitempty"`
213+
}
214+
215+
// OverrideHostSource defines a source to get override host addresses from.
216+
// +union
217+
//
218+
// +kubebuilder:validation:XValidation:rule="(has(self.header) && !has(self.metadata)) || (!has(self.header) && has(self.metadata))",message="Exactly one of header or metadata must be set."
219+
type OverrideHostSource struct {
220+
// Header defines the header to get the override host addresses.
221+
// The header value must specify at least one host in `IP:Port` format or multiple hosts in `IP:Port,IP:Port,...` format.
222+
// For example `10.0.0.5:8080` or `[2600:4040:5204::1574:24ae]:80`.
223+
// The IPv6 address is enclosed in square brackets.
224+
//
225+
// +optional
226+
Header *string `json:"header,omitempty"`
227+
228+
// Metadata defines the metadata key to get the override host addresses from the request dynamic metadata.
229+
// If set this field then it will take precedence over the header field.
230+
//
231+
// +optional
232+
Metadata *MetadataKey `json:"metadata,omitempty"`
233+
}
234+
235+
// MetadataKey defines the metadata key configuration for host override.
236+
type MetadataKey struct {
237+
// Key defines the metadata key.
238+
//
239+
// +kubebuilder:validation:MinLength=1
240+
Key string `json:"key"`
241+
242+
// Path defines the path within the metadata to extract the host addresses.
243+
// Each path element represents a key in nested metadata structure.
244+
//
245+
// +optional
246+
Path []MetadataKeyPath `json:"path,omitempty"`
247+
}
248+
249+
// MetadataKeyPath defines a path element in the metadata structure.
250+
type MetadataKeyPath struct {
251+
// Key defines the key name in the metadata structure.
252+
//
253+
// +kubebuilder:validation:MinLength=1
254+
Key string `json:"key"`
255+
}

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 92 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,81 @@ spec:
661661
- message: If consistent hash type is cookie, the cookie field
662662
must be set.
663663
rule: 'self.type == ''Cookie'' ? has(self.cookie) : !has(self.cookie)'
664+
hostOverrideSettings:
665+
description: |-
666+
HostOverrideSettings defines the configuration when the load balancer type is
667+
set to HostOverride
668+
properties:
669+
fallbackPolicy:
670+
default: LeastRequest
671+
description: |-
672+
FallbackPolicy defines the child LB policy to use in case neither header nor metadata with selected hosts is present.
673+
If not specified, defaults to LeastRequest.
674+
enum:
675+
- ConsistentHash
676+
- LeastRequest
677+
- Random
678+
- RoundRobin
679+
- HostOverride
680+
type: string
681+
overrideHostSources:
682+
description: |-
683+
OverrideHostSources defines a list of sources to get host addresses from.
684+
The host sources are searched in the order specified.
685+
The request is forwarded to the first address and subsequent addresses are used for request retries or hedging.
686+
Note that if an overridden host address is not present in the current endpoint set, it is skipped and the next found address is used.
687+
If there are not enough overridden addresses to satisfy all retry attempts the fallback load balancing policy is used to pick a host.
688+
items:
689+
description: OverrideHostSource defines a source to get
690+
override host addresses from.
691+
properties:
692+
header:
693+
description: |-
694+
Header defines the header to get the override host addresses.
695+
The header value must specify at least one host in `IP:Port` format or multiple hosts in `IP:Port,IP:Port,...` format.
696+
For example `10.0.0.5:8080` or `[2600:4040:5204::1574:24ae]:80`.
697+
The IPv6 address is enclosed in square brackets.
698+
type: string
699+
metadata:
700+
description: |-
701+
Metadata defines the metadata key to get the override host addresses from the request dynamic metadata.
702+
If set this field then it will take precedence over the header field.
703+
properties:
704+
key:
705+
description: Key defines the metadata key.
706+
minLength: 1
707+
type: string
708+
path:
709+
description: |-
710+
Path defines the path within the metadata to extract the host addresses.
711+
Each path element represents a key in nested metadata structure.
712+
items:
713+
description: MetadataKeyPath defines a path element
714+
in the metadata structure.
715+
properties:
716+
key:
717+
description: Key defines the key name in the
718+
metadata structure.
719+
minLength: 1
720+
type: string
721+
required:
722+
- key
723+
type: object
724+
type: array
725+
required:
726+
- key
727+
type: object
728+
type: object
729+
x-kubernetes-validations:
730+
- message: Exactly one of header or metadata must be set.
731+
rule: (has(self.header) && !has(self.metadata)) || (!has(self.header)
732+
&& has(self.metadata))
733+
maxItems: 10
734+
minItems: 1
735+
type: array
736+
required:
737+
- overrideHostSources
738+
type: object
664739
slowStart:
665740
description: |-
666741
SlowStart defines the configuration related to the slow start load balancer policy.
@@ -684,12 +759,14 @@ spec:
684759
"ConsistentHash",
685760
"LeastRequest",
686761
"Random",
687-
"RoundRobin".
762+
"RoundRobin",
763+
"HostOverride".
688764
enum:
689765
- ConsistentHash
690766
- LeastRequest
691767
- Random
692768
- RoundRobin
769+
- HostOverride
693770
type: string
694771
zoneAware:
695772
description: ZoneAware defines the configuration related to the
@@ -727,14 +804,18 @@ spec:
727804
field needs to be set.
728805
rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
729806
: !has(self.consistentHash)'
807+
- message: If LoadBalancer type is HostOverride, hostOverrideSettings
808+
field needs to be set.
809+
rule: 'self.type == ''HostOverride'' ? has(self.hostOverrideSettings)
810+
: !has(self.hostOverrideSettings)'
730811
- message: Currently SlowStart is only supported for RoundRobin and
731812
LeastRequest load balancers.
732-
rule: 'self.type in [''Random'', ''ConsistentHash''] ? !has(self.slowStart)
733-
: true '
813+
rule: 'self.type in [''Random'', ''ConsistentHash'', ''HostOverride'']
814+
? !has(self.slowStart) : true '
734815
- message: Currently ZoneAware is only supported for LeastRequest,
735816
Random, and RoundRobin load balancers.
736-
rule: 'self.type == ''ConsistentHash'' ? !has(self.zoneAware) :
737-
true '
817+
rule: 'self.type in [''ConsistentHash'', ''HostOverride''] ? !has(self.zoneAware)
818+
: true '
738819
mergeType:
739820
description: |-
740821
MergeType determines how this configuration is merged with existing BackendTrafficPolicy

0 commit comments

Comments
 (0)