Skip to content

Commit

Permalink
feat: add HorizontalPodAutoscaler support for EnvoyProxy API
Browse files Browse the repository at this point in the history
Signed-off-by: Ardika Bagus <[email protected]>
  • Loading branch information
ardikabs committed Nov 30, 2023
1 parent d60b4f7 commit 6f89560
Show file tree
Hide file tree
Showing 16 changed files with 1,080 additions and 6 deletions.
24 changes: 24 additions & 0 deletions api/v1alpha1/envoyproxy_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import (
"fmt"
"sort"
"strings"

autoscalingv2 "k8s.io/api/autoscaling/v2"
v1 "k8s.io/api/core/v1"

"github.com/envoyproxy/gateway/internal/utils/ptr"
)

// DefaultEnvoyProxyProvider returns a new EnvoyProxyProvider with default settings.
Expand Down Expand Up @@ -37,6 +42,21 @@ func DefaultEnvoyProxyKubeProvider() *EnvoyProxyKubernetesProvider {
}
}

func DefaultEnvoyProxyHpaMetrics() []autoscalingv2.MetricSpec {
return []autoscalingv2.MetricSpec{
{
Resource: &autoscalingv2.ResourceMetricSource{
Name: v1.ResourceCPU,
Target: autoscalingv2.MetricTarget{
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: ptr.To[int32](80),
},
},
Type: autoscalingv2.ResourceMetricSourceType,
},
}
}

// GetEnvoyProxyKubeProvider returns the EnvoyProxyKubernetesProvider of EnvoyProxyProvider or
// a default EnvoyProxyKubernetesProvider if unspecified. If EnvoyProxyProvider is not of
// type "Kubernetes", a nil EnvoyProxyKubernetesProvider is returned.
Expand Down Expand Up @@ -64,6 +84,10 @@ func (r *EnvoyProxyProvider) GetEnvoyProxyKubeProvider() *EnvoyProxyKubernetesPr
r.Kubernetes.EnvoyService.Type = GetKubernetesServiceType(ServiceTypeLoadBalancer)
}

if r.Kubernetes.EnvoyHpa != nil {
r.Kubernetes.EnvoyHpa.setDefault()
}

return r.Kubernetes
}

Expand Down
8 changes: 8 additions & 0 deletions api/v1alpha1/envoyproxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ type EnvoyProxyKubernetesProvider struct {
// +kubebuilder:validation:XValidation:message="loadBalancerIP can only be set for LoadBalancer type",rule="!has(self.loadBalancerIP) || self.type == 'LoadBalancer'"
// +kubebuilder:validation:XValidation:message="loadBalancerIP must be a valid IPv4 address",rule="!has(self.loadBalancerIP) || self.loadBalancerIP.matches(r\"^(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.|$)){4})\")"
EnvoyService *KubernetesServiceSpec `json:"envoyService,omitempty"`

// EnvoyHpa defines the Horizontal Pod Autoscaler settings for Envoy Proxy Deployment.
// Once the HPA is being set, Replicas field from EnvoyDeployment will be ignored.
//
// +optional
// +kubebuilder:validation:XValidation:message="maxReplicas must be greater than 0",rule="self.maxReplicas > 0"
// +kubebuilder:validation:XValidation:message="maxReplicas cannot be less than minReplicas",rule="!has(self.minReplicas) || self.maxReplicas >= self.minReplicas"
EnvoyHpa *KubernetesHorizontalPodAutoscalerSpec `json:"envoyHpa,omitempty"`
}

// ProxyLogging defines logging parameters for managed proxies.
Expand Down
10 changes: 10 additions & 0 deletions api/v1alpha1/kubernetes_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,13 @@ func (deployment *KubernetesDeploymentSpec) defaultKubernetesDeploymentSpec(imag
deployment.Container.Image = DefaultKubernetesContainerImage(image)
}
}

func (hpa *KubernetesHorizontalPodAutoscalerSpec) setDefault() {
if hpa.MaxReplicas == 0 {
hpa.MaxReplicas = 1
}

if len(hpa.Metrics) == 0 {
hpa.Metrics = DefaultEnvoyProxyHpaMetrics()
}
}
37 changes: 37 additions & 0 deletions api/v1alpha1/shared_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package v1alpha1

import (
appv1 "k8s.io/api/apps/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
)

Expand Down Expand Up @@ -275,3 +276,39 @@ const (
// https://github.com/google/re2/wiki/Syntax.
StringMatchRegularExpression StringMatchType = "RegularExpression"
)

// KubernetesHorizontalPodAutoscalerSpec defines Kubernetes Horizontal Pod Autoscaler settings of Envoy Proxy Deployment
type KubernetesHorizontalPodAutoscalerSpec struct {
// minReplicas is the lower limit for the number of replicas to which the autoscaler
// can scale down. It defaults to 1 replica.
// See k8s.io.autoscaling.v2.HorizontalPodAutoScalerSpec
//
// +optional
MinReplicas *int32 `json:"minReplicas,omitempty"`

// maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up.
// It cannot be less that minReplicas. It defaults to 1 replica.
// See k8s.io.autoscaling.v2.HorizontalPodAutoScalerSpec
//
// +optional
// +kubebuilder:default=1
MaxReplicas int32 `json:"maxReplicas,omitempty"`

// metrics contains the specifications for which to use to calculate the
// desired replica count (the maximum replica count across all metrics will
// be used).
// If left empty, it defaults to being based on CPU utilization with average on 80% usage.
//
// +optional
//
// See k8s.io.autoscaling.v2.HorizontalPodAutoScalerBehavior.
Metrics []autoscalingv2.MetricSpec `json:"metrics,omitempty"`

// behavior configures the scaling behavior of the target
// in both Up and Down directions (scaleUp and scaleDown fields respectively).
// If not set, the default HPAScalingRules for scale up and scale down are used.
// See k8s.io.autoscaling.v2.HorizontalPodAutoScalerBehavior.
//
// +optional
Behavior *autoscalingv2.HorizontalPodAutoscalerBehavior `json:"behavior,omitempty"`
}
38 changes: 38 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6f89560

Please sign in to comment.