◐ Shell
clean mode source ↗

feat: Horizontal scaling support to the Feast operator by ntkathole · Pull Request #6000 · feast-dev/feast

Expand Up @@ -18,6 +18,7 @@ package v1
import ( appsv1 "k8s.io/api/apps/v1" autoscalingv2 "k8s.io/api/autoscaling/v2" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" Expand Down Expand Up @@ -67,6 +68,10 @@ const ( )
// FeatureStoreSpec defines the desired state of FeatureStore // +kubebuilder:validation:XValidation:rule="self.replicas <= 1 || !has(self.services) || !has(self.services.scaling) || !has(self.services.scaling.autoscaling)",message="replicas > 1 and services.scaling.autoscaling are mutually exclusive." // +kubebuilder:validation:XValidation:rule="self.replicas <= 1 && (!has(self.services) || !has(self.services.scaling) || !has(self.services.scaling.autoscaling)) || (has(self.services) && has(self.services.onlineStore) && has(self.services.onlineStore.persistence) && has(self.services.onlineStore.persistence.store))",message="Scaling requires DB-backed persistence for the online store. Configure services.onlineStore.persistence.store when using replicas > 1 or autoscaling." // +kubebuilder:validation:XValidation:rule="self.replicas <= 1 && (!has(self.services) || !has(self.services.scaling) || !has(self.services.scaling.autoscaling)) || (!has(self.services) || !has(self.services.offlineStore) || (has(self.services.offlineStore.persistence) && has(self.services.offlineStore.persistence.store)))",message="Scaling requires DB-backed persistence for the offline store. Configure services.offlineStore.persistence.store when using replicas > 1 or autoscaling." // +kubebuilder:validation:XValidation:rule="self.replicas <= 1 && (!has(self.services) || !has(self.services.scaling) || !has(self.services.scaling.autoscaling)) || (has(self.services) && has(self.services.registry) && (has(self.services.registry.remote) || (has(self.services.registry.local) && has(self.services.registry.local.persistence) && (has(self.services.registry.local.persistence.store) || (has(self.services.registry.local.persistence.file) && has(self.services.registry.local.persistence.file.path) && (self.services.registry.local.persistence.file.path.startsWith('s3://') || self.services.registry.local.persistence.file.path.startsWith('gs://')))))))",message="Scaling requires DB-backed or remote registry. Configure registry.local.persistence.store or use a remote registry when using replicas > 1 or autoscaling. S3/GCS-backed registry is also allowed." type FeatureStoreSpec struct { // +kubebuilder:validation:Pattern="^[A-Za-z0-9][A-Za-z0-9_-]*$" // FeastProject is the Feast project id. This can be any alphanumeric string with underscores and hyphens, but it cannot start with an underscore or hyphen. Required. Expand All @@ -76,6 +81,11 @@ type FeatureStoreSpec struct { AuthzConfig *AuthzConfig `json:"authz,omitempty"` CronJob *FeastCronJob `json:"cronJob,omitempty"` BatchEngine *BatchEngineConfig `json:"batchEngine,omitempty"` // Replicas is the desired number of pod replicas. Used by the scale sub-resource. // Mutually exclusive with services.scaling.autoscaling. // +kubebuilder:default=1 // +kubebuilder:validation:Minimum=1 Replicas *int32 `json:"replicas"` }
// FeastProjectDir defines how to create the feast project directory. Expand Down Expand Up @@ -301,6 +311,35 @@ type FeatureStoreServices struct { DisableInitContainers bool `json:"disableInitContainers,omitempty"` // Volumes specifies the volumes to mount in the FeatureStore deployment. A corresponding `VolumeMount` should be added to whichever feast service(s) require access to said volume(s). Volumes []corev1.Volume `json:"volumes,omitempty"` // Scaling configures horizontal scaling for the FeatureStore deployment (e.g. HPA autoscaling). // For static replicas, use spec.replicas instead. Scaling *ScalingConfig `json:"scaling,omitempty"` }
// ScalingConfig configures horizontal scaling for the FeatureStore deployment. type ScalingConfig struct { // Autoscaling configures a HorizontalPodAutoscaler for the FeatureStore deployment. // Mutually exclusive with spec.replicas. // +optional Autoscaling *AutoscalingConfig `json:"autoscaling,omitempty"` }
// AutoscalingConfig defines HPA settings for the FeatureStore deployment. type AutoscalingConfig struct { // MinReplicas is the lower limit for the number of replicas. Defaults to 1. // +kubebuilder:validation:Minimum=1 // +optional MinReplicas *int32 `json:"minReplicas,omitempty"` // MaxReplicas is the upper limit for the number of replicas. Required. // +kubebuilder:validation:Minimum=1 MaxReplicas int32 `json:"maxReplicas"` // Metrics contains the specifications for which to use to calculate the desired replica count. // If not set, defaults to 80% CPU utilization. // +optional Metrics []autoscalingv2.MetricSpec `json:"metrics,omitempty"` // Behavior configures the scaling behavior of the target. // +optional Behavior *autoscalingv2.HorizontalPodAutoscalerBehavior `json:"behavior,omitempty"` }
// OfflineStore configures the offline store service Expand Down Expand Up @@ -690,6 +729,20 @@ type FeatureStoreStatus struct { FeastVersion string `json:"feastVersion,omitempty"` Phase string `json:"phase,omitempty"` ServiceHostnames ServiceHostnames `json:"serviceHostnames,omitempty"` // Replicas is the current number of ready pod replicas (used by the scale sub-resource). Replicas int32 `json:"replicas,omitempty"` // Selector is the label selector for pods managed by the FeatureStore deployment (used by the scale sub-resource). Selector string `json:"selector,omitempty"` // ScalingStatus reports the current scaling state of the FeatureStore deployment. ScalingStatus *ScalingStatus `json:"scalingStatus,omitempty"` }
// ScalingStatus reports the observed scaling state. type ScalingStatus struct { // CurrentReplicas is the current number of pod replicas. CurrentReplicas int32 `json:"currentReplicas,omitempty"` // DesiredReplicas is the desired number of pod replicas. DesiredReplicas int32 `json:"desiredReplicas,omitempty"` }
// ServiceHostnames defines the service hostnames in the format of <domain>:<port>, e.g. example.svc.cluster.local:80 Expand All @@ -706,6 +759,7 @@ type ServiceHostnames struct { // +kubebuilder:resource:shortName=feast // +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase` // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` // +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector // +kubebuilder:storageversion
// FeatureStore is the Schema for the featurestores API Expand Down