Skip to content

Commit

Permalink
Merge pull request #82 from zqzten/external-generator
Browse files Browse the repository at this point in the history
HorizontalPortrait: Introduce external generator mechanism
  • Loading branch information
dayko2019 authored Dec 14, 2023
2 parents e01015f + e29051a commit f51a642
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 57 deletions.
68 changes: 38 additions & 30 deletions apis/autoscaling/v1alpha1/horizontalportrait_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
k8sautoscalingv2 "k8s.io/api/autoscaling/v2"
batchv1 "k8s.io/api/batch/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)

//+kubebuilder:object:root=true
Expand All @@ -46,9 +47,16 @@ type HorizontalPortraitSpec struct {

// PortraitSpec defines general specs of portrait.
type PortraitSpec struct {
// PortraitType is the type of portrait. Different type has different portrait generating logic.
// PortraitType is the type of portrait.
// Different type has different semantics with different portrait generating logic.
PortraitType PortraitType `json:"portraitType"`

// ExternalGeneratorName is the identifier of external controller which shall generate this portrait.
// External controllers should use this field to filter portraits to generate.
// Kapacity's built-in portrait generators would ignore portraits with this field set.
// +optional
ExternalGeneratorName string `json:"externalGeneratorName,omitempty"`

// Metrics contains the specifications for which to use to generate the portrait.
// +optional
Metrics []MetricSpec `json:"metrics,omitempty"`
Expand Down Expand Up @@ -121,10 +129,10 @@ type PortraitAlgorithm struct {
KubeHPA *KubeHPAPortraitAlgorithm `json:"kubeHPA,omitempty"`

// Config is the general configuration data for arbitrary algorithm those
// used by external user-defined portraits.
// TODO: consider if we can make it structural
// used by external portrait generators.
// +optional
Config map[string]string `json:"config,omitempty"`
// +kubebuilder:pruning:PreserveUnknownFields
Config *runtime.RawExtension `json:"config,omitempty"`
}

type PortraitAlgorithmType string
Expand All @@ -137,32 +145,6 @@ const (
KubeHPAPortraitAlgorithmType PortraitAlgorithmType = "KubeHPA"
)

// KubeHPAPortraitAlgorithm defines parameters of KubeHPA algorithm.
type KubeHPAPortraitAlgorithm struct {
// SyncPeriod is the period for syncing the portrait.
// +optional
// +kubebuilder:default="15s"
SyncPeriod metav1.Duration `json:"syncPeriod"`

// Tolerance is the tolerance for when resource usage suggests upscaling/downscaling.
// Should be a string formatted float64 number.
// +optional
// +kubebuilder:default="0.1"
Tolerance string `json:"tolerance"`

// CPUInitializationPeriod is the period after pod start when CPU samples might be skipped.
// +optional
// +kubebuilder:default="5m"
CPUInitializationPeriod metav1.Duration `json:"cpuInitializationPeriod"`

// InitialReadinessDelay is period after pod start during which readiness changes
// are treated as readiness being set for the first time. The only effect of this is that
// HPA will disregard CPU samples from unready pods that had last readiness change during that period.
// +optional
// +kubebuilder:default="30s"
InitialReadinessDelay metav1.Duration `json:"initialReadinessDelay"`
}

// ExternalJobPortraitAlgorithm defines configurations of ExternalJob algorithm.
type ExternalJobPortraitAlgorithm struct {
// Job is the external job that runs the algorithm.
Expand Down Expand Up @@ -226,6 +208,32 @@ const (
// ConfigMapPortraitAlgorithmResultSource defines configurations of ConfigMap result source.
type ConfigMapPortraitAlgorithmResultSource struct{}

// KubeHPAPortraitAlgorithm defines parameters of KubeHPA algorithm.
type KubeHPAPortraitAlgorithm struct {
// SyncPeriod is the period for syncing the portrait.
// +optional
// +kubebuilder:default="15s"
SyncPeriod metav1.Duration `json:"syncPeriod"`

// Tolerance is the tolerance for when resource usage suggests upscaling/downscaling.
// Should be a string formatted float64 number.
// +optional
// +kubebuilder:default="0.1"
Tolerance string `json:"tolerance"`

// CPUInitializationPeriod is the period after pod start when CPU samples might be skipped.
// +optional
// +kubebuilder:default="5m"
CPUInitializationPeriod metav1.Duration `json:"cpuInitializationPeriod"`

// InitialReadinessDelay is period after pod start during which readiness changes
// are treated as readiness being set for the first time. The only effect of this is that
// HPA will disregard CPU samples from unready pods that had last readiness change during that period.
// +optional
// +kubebuilder:default="30s"
InitialReadinessDelay metav1.Duration `json:"initialReadinessDelay"`
}

// HorizontalPortraitStatus defines the observed state of HorizontalPortrait.
type HorizontalPortraitStatus struct {
// PortraitData is the data of generated portrait.
Expand Down
8 changes: 3 additions & 5 deletions apis/autoscaling/v1alpha1/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,10 @@ spec:
the portrait.
properties:
config:
additionalProperties:
type: string
description: 'Config is the general configuration data for arbitrary
algorithm those used by external user-defined portraits. TODO:
consider if we can make it structural'
description: Config is the general configuration data for arbitrary
algorithm those used by external portrait generators.
type: object
x-kubernetes-preserve-unknown-fields: true
externalJob:
description: ExternalJob is the configuration for ExternalJob
algorithm.
Expand Down Expand Up @@ -15937,6 +15935,12 @@ spec:
required:
- type
type: object
externalGeneratorName:
description: ExternalGeneratorName is the identifier of external controller
which shall generate this portrait. External controllers should
use this field to filter portraits to generate. Kapacity's built-in
portrait generators would ignore portraits with this field set.
type: string
metrics:
description: Metrics contains the specifications for which to use
to generate the portrait.
Expand Down Expand Up @@ -16423,7 +16427,7 @@ spec:
type: array
portraitType:
description: PortraitType is the type of portrait. Different type
has different portrait generating logic.
has different semantics with different portrait generating logic.
type: string
scaleTargetRef:
description: ScaleTargetRef points to the target resource to scale.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,11 @@ spec:
to generate the portrait.
properties:
config:
additionalProperties:
type: string
description: 'Config is the general configuration data
for arbitrary algorithm those used by external user-defined
portraits. TODO: consider if we can make it structural'
description: Config is the general configuration data
for arbitrary algorithm those used by external portrait
generators.
type: object
x-kubernetes-preserve-unknown-fields: true
externalJob:
description: ExternalJob is the configuration for ExternalJob
algorithm.
Expand Down Expand Up @@ -25277,6 +25276,13 @@ spec:
required:
- type
type: object
externalGeneratorName:
description: ExternalGeneratorName is the identifier of
external controller which shall generate this portrait.
External controllers should use this field to filter portraits
to generate. Kapacity's built-in portrait generators would
ignore portraits with this field set.
type: string
metrics:
description: Metrics contains the specifications for which
to use to generate the portrait.
Expand Down Expand Up @@ -25800,7 +25806,8 @@ spec:
type: array
portraitType:
description: PortraitType is the type of portrait. Different
type has different portrait generating logic.
type has different semantics with different portrait generating
logic.
type: string
required:
- algorithm
Expand Down
16 changes: 6 additions & 10 deletions controllers/autoscaling/horizontalportrait_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,11 @@ func (r *HorizontalPortraitReconciler) Reconcile(ctx context.Context, req ctrl.R

portraitGenerator, ok := r.PortraitGenerators[hp.Spec.PortraitType]
if !ok {
// this should not happen because we have watch predicates
l.Info("unknown portrait type, ignore", "portraitType", hp.Spec.PortraitType)
err := fmt.Errorf("unknown portrait type %q", hp.Spec.PortraitType)
l.Error(err, "failed to get portrait generator")
r.errorOut(ctx, hp, hpStatusOriginal, autoscalingv1alpha1.PortraitGenerated, metav1.ConditionFalse,
"FailedGetPortraitGenerator", fmt.Sprintf("failed to get portrait generator: %v", err))
// do not requeue because it won't help
return ctrl.Result{}, nil
}

Expand Down Expand Up @@ -190,14 +193,7 @@ func (r *HorizontalPortraitReconciler) SetupWithManager(mgr ctrl.Manager) error
if !ok {
return false
}
switch hp.Spec.PortraitType {
case autoscalingv1alpha1.ReactivePortraitType:
case autoscalingv1alpha1.PredictivePortraitType:
case autoscalingv1alpha1.BurstPortraitType:
default:
return false
}
return true
return hp.Spec.ExternalGeneratorName == ""
}),
)).
Watches(&source.Channel{Source: r.EventTrigger}, &handler.EnqueueRequestForObject{}).
Expand Down

0 comments on commit f51a642

Please sign in to comment.