Skip to content

Commit

Permalink
feat(autoscaing): support intelligent hpa
Browse files Browse the repository at this point in the history
  • Loading branch information
kapybar4 committed Jun 17, 2024
1 parent de2f4ec commit a84f481
Show file tree
Hide file tree
Showing 22 changed files with 2,636 additions and 15 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.0
creationTimestamp: null
name: virtualworkloads.autoscaling.katalyst.kubewharf.io
spec:
group: autoscaling.katalyst.kubewharf.io
names:
kind: VirtualWorkload
listKind: VirtualWorkloadList
plural: virtualworkloads
singular: virtualworkload
scope: Namespaced
versions:
- name: v1alpha2
schema:
openAPIV3Schema:
description: VirtualWorkload is the Schema for the virtualworkloads API VirtualWorkload
is used to support IHPA's Preview mode, that is, by providing a virtual
workload reference so that scaling will not affect the real workload.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: VirtualWorkloadSpec defines the desired state of VirtualWorkload
properties:
replicas:
format: int32
type: integer
required:
- replicas
type: object
status:
description: VirtualWorkloadStatus defines the observed state of VirtualWorkload
properties:
replicas:
format: int32
type: integer
selector:
type: string
required:
- replicas
- selector
type: object
type: object
served: true
storage: true
subresources:
scale:
labelSelectorPath: .status.selector
specReplicasPath: .spec.replicas
statusReplicasPath: .status.replicas
status: {}
220 changes: 220 additions & 0 deletions pkg/apis/autoscaling/v1alpha2/ihpa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package v1alpha2

import (
autoscalingv2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/kubewharf/katalyst-api/pkg/apis/config/v1alpha1"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:storageversion
// +kubebuilder:resource:shortName=ihpa

// IntelligentHorizontalPodAutoscaler captures information about a IHPA object
type IntelligentHorizontalPodAutoscaler struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`

// Spec defines the behavior of a IntelligentHorizontalPodAutoscaler.
// +optional
Spec IntelligentHorizontalPodAutoscalerSpec `json:"spec,omitempty"`

// Status represents the current information about a IntelligentHorizontalPodAutoscaler.
// +optional
Status IntelligentHorizontalPodAutoscalerStatus `json:"status,omitempty"`
}

// IntelligentHorizontalPodAutoscalerSpec is the specification of the behavior of the autoscaler.
type IntelligentHorizontalPodAutoscalerSpec struct {
// Autoscaler defines the overall scaling configuration.
Autoscaler AutoscalerSpec `json:"autoscaler"`

// ScaleStrategy defines whether to enable IHPA to scale workloads.
// IHPA provides a preview mode. In preview mode, IHPA does not modify the number of replicas of the workload.
// The default is 'Preview'.
// +kubebuilder:default:=Preview
ScaleStrategy ScaleStrategyType `json:"scaleStrategy,omitempty"`

// AlgorithmConfig defines the algorithm configuration. If there is no configuration,
// the default configuration will be used.
AlgorithmConfig v1alpha1.AlgorithmConfig `json:"algorithmConfig,omitempty"`

// TimeBounds supports dynamically adjusting HPA Replicas in different time periods,
// providing capability similar to CronHPA.
TimeBounds []TimeBound `json:"timeBounds,omitempty"`
}

// IntelligentHorizontalPodAutoscalerStatus describes the runtime state of the autoscaler.
type IntelligentHorizontalPodAutoscalerStatus struct {
// LastHorizontalPodAutoscalerUpdatedTime is the time when the HPA replicas configuration was last refreshed by IHPA.
// +optional
LastHorizontalPodAutoscalerUpdatedTime *metav1.Time `json:"lastHorizontalPodAutoscalerUpdatedTime,omitempty"`

// Conditions record the creation or modification time of IHPA's associated resource objects.
// +optional
// +patchMergeKey=type
// +patchStrategy=merge
Conditions []IntelligentHorizontalPodAutoscalerCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
}

// AutoscalerSpec defines the associated workload, the metrics used, and the scaling behavior.
type AutoscalerSpec struct {
// ScaleTargetRef defines the associated workload.
ScaleTargetRef autoscalingv2.CrossVersionObjectReference `json:"scaleTargetRef"`

// Behavior defines scaling actions, which are transparently transmitted to HPA and implemented by HPA Controller.
// +optional
Behavior *autoscalingv2.HorizontalPodAutoscalerBehavior `json:"behavior,omitempty"`

// Metrics define the metrics used for workload scaling.
// +optional
Metrics []MetricSpec `json:"metrics,omitempty"`

// MinReplicas and MaxReplicas are consistent with those in HPA.
// +optional
MinReplicas *int32 `json:"minReplicas,omitempty"`
MaxReplicas int32 `json:"maxReplicas"`
}

// MetricSpec is used to define a single metric of HPA.
// Metric is preferred. Only one of Metric and CustomMetric will take effect.
// The metrics source of Metric is API Server.
// The metrics source of CustomMetric is the resource portrait.
type MetricSpec struct {
Metric *autoscalingv2.MetricSpec `json:"metric,omitempty"`
CustomMetric *CustomMetricSpec `json:"customMetric,omitempty"`
}

// CustomMetricSpec configures metrics derived from resource portraits.
type CustomMetricSpec struct {
// Identify defines the name of the resource metric
Identify corev1.ResourceName `json:"identify"`

// Query defines the metrics query statement.
// There are preset templates for resource portraits, so the query statement can be empty.
Query string `json:"query,omitempty"`

// Value represents the threshold, corresponding to the AverageValue in HPA.
Value *resource.Quantity `json:"value"`
}

// TimeBound supports adjusting HPA max/min replicas based on the period and the time within the period.
type TimeBound struct {
// Start and End are the time period.
Start metav1.Time `json:"start,omitempty"`
End metav1.Time `json:"end,omitempty"`
Bounds []Bound `json:"bounds,omitempty"`
}

// Bound defines the max/min replicas of HPA configured under the specified CronTab.
type Bound struct {
CronTab string `json:"cronTab"`

MinReplicas *int32 `json:"minReplicas,omitempty"`
MaxReplicas *int32 `json:"maxReplicas,omitempty"`
}

// ScaleStrategyType is the strategy of IHPA to scale workloads.
type ScaleStrategyType string

const (
Preview ScaleStrategyType = "Preview"
Auto ScaleStrategyType = "Auto"
)

// IntelligentHorizontalPodAutoscalerConditionType are the valid conditions of IntelligentHorizontalPodAutoscaler
type IntelligentHorizontalPodAutoscalerConditionType string

const (
// ServiceProfileDescriptorSynced indicates that the SPD had been synced.
ServiceProfileDescriptorSynced IntelligentHorizontalPodAutoscalerConditionType = "SPDSynced"
// VirtualWorkloadSynced indicates that the VW had been synced.
VirtualWorkloadSynced IntelligentHorizontalPodAutoscalerConditionType = "VWCreated"
// HorizontalPodAutoscalerSynced indicates that the HPA had been synced.
HorizontalPodAutoscalerSynced IntelligentHorizontalPodAutoscalerConditionType = "HPASynced"
)

// IntelligentHorizontalPodAutoscalerCondition describes the state of
// a IntelligentHorizontalPodAutoscaler at a certain point.
type IntelligentHorizontalPodAutoscalerCondition struct {
// type describes the current condition
Type IntelligentHorizontalPodAutoscalerConditionType `json:"type"`
// status is the status of the condition (True, False, Unknown)
Status corev1.ConditionStatus `json:"status"`
// lastTransitionTime is the last time the condition transitioned from
// one status to another
// +optional
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
// reason is the reason for the condition's last transition.
// +optional
Reason string `json:"reason,omitempty"`
// message is a human-readable explanation containing details about
// the transition
// +optional
Message string `json:"message,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// IntelligentHorizontalPodAutoscalerList is a collection of IntelligentHorizontalPodAutoscaler objects.
type IntelligentHorizontalPodAutoscalerList struct {
metav1.TypeMeta `json:",inline"`

// Standard list metadata
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`

// items is the list of IntelligentHorizontalPodAutoscaler
Items []IntelligentHorizontalPodAutoscaler `json:"items"`
}

// VirtualWorkloadSpec defines the desired state of VirtualWorkload
type VirtualWorkloadSpec struct {
Replicas int32 `json:"replicas"`
}

// VirtualWorkloadStatus defines the observed state of VirtualWorkload
type VirtualWorkloadStatus struct {
Replicas int32 `json:"replicas"`
Selector string `json:"selector"`
}

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector

// VirtualWorkload is the Schema for the virtualworkloads API
// VirtualWorkload is used to support IHPA's Preview mode, that is, by providing
// a virtual workload reference so that scaling will not affect the real workload.
type VirtualWorkload struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec VirtualWorkloadSpec `json:"spec,omitempty"`
Status VirtualWorkloadStatus `json:"status,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// VirtualWorkloadList contains a list of VirtualWorkload
type VirtualWorkloadList struct {
metav1.TypeMeta `json:",inline"`

// Standard list metadata
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`

// items is the list of VirtualWorkload
Items []VirtualWorkload `json:"items"`
}
8 changes: 7 additions & 1 deletion pkg/apis/autoscaling/v1alpha2/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha

// ResourceName const is used to construct standard gvr
const (
ResourceNameKatalystVPA = "katalystverticalpodautoscalers"
ResourceNameKatalystVPA = "katalystverticalpodautoscalers"
ResourceNameIHPA = "intelligenthorizontalpodautoscalers"
ResourceNameVirtualWorkload = "virtualworkloads"
)

// Resource takes an unqualified resource and returns a Group qualified GroupResource
Expand All @@ -52,6 +54,10 @@ func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&KatalystVerticalPodAutoscaler{},
&KatalystVerticalPodAutoscalerList{},
&IntelligentHorizontalPodAutoscaler{},
&IntelligentHorizontalPodAutoscalerList{},
&VirtualWorkload{},
&VirtualWorkloadList{},
)

metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
Expand Down
File renamed without changes.
Loading

0 comments on commit a84f481

Please sign in to comment.