From d5ca7c81fca2e5057a41258460e40bbc2eca17fe Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Mon, 20 May 2024 17:24:46 -0700 Subject: [PATCH] api: cookie based consistent hashing Relates to https://github.com/envoyproxy/gateway/issues/2624 Signed-off-by: Arko Dasgupta --- api/v1alpha1/loadbalancer_types.go | 31 +++++++++++++++++- api/v1alpha1/zz_generated.deepcopy.go | 32 +++++++++++++++++++ ....envoyproxy.io_backendtrafficpolicies.yaml | 29 +++++++++++++++++ site/content/en/latest/api/extension_types.md | 17 +++++++++- 4 files changed, 107 insertions(+), 2 deletions(-) diff --git a/api/v1alpha1/loadbalancer_types.go b/api/v1alpha1/loadbalancer_types.go index d4912aebd4a..eea3abe46ab 100644 --- a/api/v1alpha1/loadbalancer_types.go +++ b/api/v1alpha1/loadbalancer_types.go @@ -56,6 +56,7 @@ const ( // +union // // +kubebuilder:validation:XValidation:rule="self.type == 'Header' ? has(self.header) : !has(self.header)",message="If consistent hash type is header, the header field must be set." +// +kubebuilder:validation:XValidation:rule="self.type == 'Cookie' ? has(self.cookie) : !has(self.cookie)",message="If consistent hash type is cookie, the cookie field must be set." type ConsistentHash struct { // ConsistentHashType defines the type of input to hash on. Valid Type values are "SourceIP" or "Header". // @@ -67,6 +68,12 @@ type ConsistentHash struct { // +optional Header *Header `json:"header,omitempty"` + // Cookie configures the cookie hash policy when the consistent hash type is set to Cookie. + // + // +optional + // +notImplementedHide + Cookie *Cookie `json:"cookie,omitempty"` + // The table size for consistent hashing, must be prime number limited to 5000011. // // +kubebuilder:validation:Minimum=2 @@ -84,6 +91,28 @@ type Header struct { Name string `json:"name"` } +// Cookie defines the cookie hashing configuration for consistent hash based +// load balancing. +type Cookie struct { + // Name of the cookie to hash. + // If this cookie doesnt exist in the request, Envoy will generate a cookie and set + // the TTL on the response back to the client based on Layer 4 + // attributes of the backend endpoint, to ensure that these future requests + // go to the same backend endpoint. Make sure to set the TTL field for this case. + Name string `json:"name"` + // TTL of the generated cookie if the cookie is not present. This value sets the + // Max-Age attribute value. + // + // +optional + // +notImplementedHide + TTL *metav1.Duration `json:"ttl,omitempty"` + // Additional Attributes to set for the generated cookie. + // + // +optional + // +notImplementedHide + Attributes map[string]string `json:"attributes,omitempty"` +} + // ConsistentHashType defines the type of input to hash on. // +kubebuilder:validation:Enum=SourceIP;Header type ConsistentHashType string @@ -91,7 +120,7 @@ type ConsistentHashType string const ( // SourceIPConsistentHashType hashes based on the source IP address. SourceIPConsistentHashType ConsistentHashType = "SourceIP" - // HeaderConsistentHashType hashes based on a request header. + // HeaderConsistentHas`hType hashes based on a request header. HeaderConsistentHashType ConsistentHashType = "Header" ) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 37ae123f6cd..607b32ad71d 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -926,6 +926,11 @@ func (in *ConsistentHash) DeepCopyInto(out *ConsistentHash) { *out = new(Header) **out = **in } + if in.Cookie != nil { + in, out := &in.Cookie, &out.Cookie + *out = new(Cookie) + (*in).DeepCopyInto(*out) + } if in.TableSize != nil { in, out := &in.TableSize, &out.TableSize *out = new(uint64) @@ -943,6 +948,33 @@ func (in *ConsistentHash) DeepCopy() *ConsistentHash { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Cookie) DeepCopyInto(out *Cookie) { + *out = *in + if in.TTL != nil { + in, out := &in.TTL, &out.TTL + *out = new(v1.Duration) + **out = **in + } + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cookie. +func (in *Cookie) DeepCopy() *Cookie { + if in == nil { + return nil + } + out := new(Cookie) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CustomHeaderExtensionSettings) DeepCopyInto(out *CustomHeaderExtensionSettings) { *out = *in diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 37aabbbefc1..ab088c82e9a 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -412,6 +412,32 @@ spec: ConsistentHash defines the configuration when the load balancer type is set to ConsistentHash properties: + cookie: + description: Cookie configures the cookie hash policy when + the consistent hash type is set to Cookie. + properties: + attributes: + additionalProperties: + type: string + description: Additional Attributes to set for the generated + cookie. + type: object + name: + description: |- + Name of the cookie to hash. + If this cookie doesnt exist in the request, Envoy will generate a cookie and set + the TTL on the response back to the client based on Layer 4 + attributes of the backend endpoint, to ensure that these future requests + go to the same backend endpoint. Make sure to set the TTL field for this case. + type: string + ttl: + description: |- + TTL of the generated cookie if the cookie is not present. This value sets the + Max-Age attribute value. + type: string + required: + - name + type: object header: description: Header configures the header hash policy when the consistent hash type is set to Header. @@ -444,6 +470,9 @@ spec: - message: If consistent hash type is header, the header field must be set. rule: 'self.type == ''Header'' ? has(self.header) : !has(self.header)' + - message: If consistent hash type is cookie, the cookie field + must be set. + rule: 'self.type == ''Cookie'' ? has(self.cookie) : !has(self.cookie)' slowStart: description: |- SlowStart defines the configuration related to the slow start load balancer policy. diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 40f6a28d294..a58d85c4a79 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -703,7 +703,22 @@ _Appears in:_ | Value | Description | | ----- | ----------- | | `SourceIP` | SourceIPConsistentHashType hashes based on the source IP address.
| -| `Header` | HeaderConsistentHashType hashes based on a request header.
| +| `Header` | HeaderConsistentHas`hType hashes based on a request header.
| + + +#### Cookie + + + +Cookie defines the cookie hashing configuration for consistent hash based +load balancing. + +_Appears in:_ +- [ConsistentHash](#consistenthash) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `name` | _string_ | true | Name of the cookie to hash.
If this cookie doesnt exist in the request, Envoy will generate a cookie and set
the TTL on the response back to the client based on Layer 4
attributes of the backend endpoint, to ensure that these future requests
go to the same backend endpoint. Make sure to set the TTL field for this case. | #### CustomHeaderExtensionSettings