Skip to content

Commit

Permalink
feat(translator): Implement consistent hash table size in BackendTraf…
Browse files Browse the repository at this point in the history
…ficPolicy (#3440)

* Implement consistent hash table size api

Signed-off-by: Dingkang Li <dingkang1743@gmail.com>

* Use function in go/math to judge prime number

Signed-off-by: Dingkang Li <dingkang1743@gmail.com>

* Fix error handling

Signed-off-by: Dingkang Li <dingkang1743@gmail.com>

---------

Signed-off-by: Dingkang Li <dingkang1743@gmail.com>
  • Loading branch information
aoledk authored May 24, 2024
1 parent 8b71c60 commit 6782d15
Show file tree
Hide file tree
Showing 14 changed files with 437 additions and 18 deletions.
1 change: 0 additions & 1 deletion api/v1alpha1/loadbalancer_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ type ConsistentHash struct {
// +kubebuilder:validation:Maximum=5000011
// +kubebuilder:default=65537
// +optional
// +notImplementedHide
TableSize *uint64 `json:"tableSize,omitempty"`
}

Expand Down
54 changes: 39 additions & 15 deletions internal/gatewayapi/backendtrafficpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"math"
"math/big"
"net"
"sort"
"strings"
Expand All @@ -28,6 +29,10 @@ import (
"github.com/envoyproxy/gateway/internal/utils/regex"
)

const (
MaxConsistentHashTableSize = 5000011 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-maglevlbconfig
)

func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv1a1.BackendTrafficPolicy,
gateways []*GatewayContext,
routes []RouteContext,
Expand Down Expand Up @@ -307,7 +312,10 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
}
}
if policy.Spec.LoadBalancer != nil {
lb = t.buildLoadBalancer(policy)
if lb, err = t.buildLoadBalancer(policy); err != nil {
err = perr.WithMessage(err, "LoadBalancer")
errs = errors.Join(errs, err)
}
}
if policy.Spec.ProxyProtocol != nil {
pp = t.buildProxyProtocol(policy)
Expand Down Expand Up @@ -431,7 +439,10 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
}
}
if policy.Spec.LoadBalancer != nil {
lb = t.buildLoadBalancer(policy)
if lb, err = t.buildLoadBalancer(policy); err != nil {
err = perr.WithMessage(err, "LoadBalancer")
errs = errors.Join(errs, err)
}
}
if policy.Spec.ProxyProtocol != nil {
pp = t.buildProxyProtocol(policy)
Expand Down Expand Up @@ -764,12 +775,17 @@ func buildRateLimitRule(rule egv1a1.RateLimitRule) (*ir.RateLimitRule, error) {
return irRule, nil
}

func (t *Translator) buildLoadBalancer(policy *egv1a1.BackendTrafficPolicy) *ir.LoadBalancer {
func (t *Translator) buildLoadBalancer(policy *egv1a1.BackendTrafficPolicy) (*ir.LoadBalancer, error) {
var lb *ir.LoadBalancer
switch policy.Spec.LoadBalancer.Type {
case egv1a1.ConsistentHashLoadBalancerType:
consistentHash, err := t.buildConsistentHashLoadBalancer(policy)
if err != nil {
return nil, perr.WithMessage(err, "ConsistentHash")
}

lb = &ir.LoadBalancer{
ConsistentHash: t.buildConsistentHashLoadBalancer(policy),
ConsistentHash: consistentHash,
}
case egv1a1.LeastRequestLoadBalancerType:
lb = &ir.LoadBalancer{}
Expand Down Expand Up @@ -803,24 +819,32 @@ func (t *Translator) buildLoadBalancer(policy *egv1a1.BackendTrafficPolicy) *ir.
}
}

return lb
return lb, nil
}

func (t *Translator) buildConsistentHashLoadBalancer(policy *egv1a1.BackendTrafficPolicy) *ir.ConsistentHash {
func (t *Translator) buildConsistentHashLoadBalancer(policy *egv1a1.BackendTrafficPolicy) (*ir.ConsistentHash, error) {
consistentHash := &ir.ConsistentHash{}

if policy.Spec.LoadBalancer.ConsistentHash.TableSize != nil {
tableSize := policy.Spec.LoadBalancer.ConsistentHash.TableSize

if *tableSize > MaxConsistentHashTableSize || !big.NewInt(int64(*tableSize)).ProbablyPrime(0) {
return nil, fmt.Errorf("invalid TableSize value %d", *tableSize)
}

consistentHash.TableSize = tableSize
}

switch policy.Spec.LoadBalancer.ConsistentHash.Type {
case egv1a1.SourceIPConsistentHashType:
return &ir.ConsistentHash{
SourceIP: ptr.To(true),
}
consistentHash.SourceIP = ptr.To(true)
case egv1a1.HeaderConsistentHashType:
return &ir.ConsistentHash{
Header: &ir.Header{
Name: policy.Spec.LoadBalancer.ConsistentHash.Header.Name,
},
consistentHash.Header = &ir.Header{
Name: policy.Spec.LoadBalancer.ConsistentHash.Header.Name,
}
default:
return &ir.ConsistentHash{}
}

return consistentHash, nil
}

func (t *Translator) buildProxyProtocol(policy *egv1a1.BackendTrafficPolicy) *ir.ProxyProtocol {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: default
name: httproute-1
spec:
hostnames:
- gateway.envoyproxy.io
parentRefs:
- namespace: envoy-gateway
name: gateway-1
sectionName: http
rules:
- matches:
- path:
value: "/"
backendRefs:
- name: service-1
port: 8080
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: default
name: httproute-2
spec:
hostnames:
- gateway.envoyproxy.io
parentRefs:
- namespace: envoy-gateway
name: gateway-1
sectionName: http
rules:
- matches:
- path:
value: "/test2"
backendRefs:
- name: service-2
port: 8080
backendTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
namespace: default
name: policy-for-route
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: httproute-1
loadBalancer:
type: ConsistentHash
consistentHash:
tableSize: 1024
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
namespace: default
name: policy-for-route2
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: httproute-2
loadBalancer:
type: ConsistentHash
consistentHash:
tableSize: 5000012
Loading

0 comments on commit 6782d15

Please sign in to comment.