diff --git a/docs/gitbook/usage/how-it-works.md b/docs/gitbook/usage/how-it-works.md index 78cb9c08..ef8dcea2 100644 --- a/docs/gitbook/usage/how-it-works.md +++ b/docs/gitbook/usage/how-it-works.md @@ -128,7 +128,7 @@ in the primary autoscaler when a rollout for the deployment starts and completes Optionally, you can create two HPAs, one for canary and one for the primary to update the HPA without doing a new rollout. As the canary deployment will be scaled to 0, the HPA on the canary will be inactive. -**Note** Flagger requires `autoscaling/v2` or `autoscaling/v2beta2` API version for HPAs. +**Note** Flagger requires `autoscaling/v2` API version for HPAs. The progress deadline represents the maximum time in seconds for the canary deployment to make progress before it is rolled back, defaults to ten minutes. diff --git a/pkg/apis/keda/v1alpha1/scaledobject.go b/pkg/apis/keda/v1alpha1/scaledobject.go index ca6d28f2..210ec07b 100644 --- a/pkg/apis/keda/v1alpha1/scaledobject.go +++ b/pkg/apis/keda/v1alpha1/scaledobject.go @@ -17,7 +17,7 @@ limitations under the License. package v1alpha1 import ( - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" + autoscalingv2 "k8s.io/api/autoscaling/v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -106,7 +106,7 @@ type HorizontalPodAutoscalerConfig struct { // +optional Name string `json:"name,omitempty"` // +optional - Behavior *autoscalingv2beta2.HorizontalPodAutoscalerBehavior `json:"behavior,omitempty"` + Behavior *autoscalingv2.HorizontalPodAutoscalerBehavior `json:"behavior,omitempty"` } // ScaleTarget holds the a reference to the scale target Object @@ -129,7 +129,7 @@ type ScaleTriggers struct { // +optional AuthenticationRef *ScaledObjectAuthRef `json:"authenticationRef,omitempty"` // +optional - MetricType autoscalingv2beta2.MetricTargetType `json:"metricType,omitempty"` + MetricType autoscalingv2.MetricTargetType `json:"metricType,omitempty"` } // +k8s:openapi-gen=true diff --git a/pkg/apis/keda/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/keda/v1alpha1/zz_generated.deepcopy.go index 6b5311d5..140625d2 100644 --- a/pkg/apis/keda/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/keda/v1alpha1/zz_generated.deepcopy.go @@ -22,7 +22,7 @@ limitations under the License. package v1alpha1 import ( - v2beta2 "k8s.io/api/autoscaling/v2beta2" + v2 "k8s.io/api/autoscaling/v2" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -141,7 +141,7 @@ func (in *HorizontalPodAutoscalerConfig) DeepCopyInto(out *HorizontalPodAutoscal *out = *in if in.Behavior != nil { in, out := &in.Behavior, &out.Behavior - *out = new(v2beta2.HorizontalPodAutoscalerBehavior) + *out = new(v2.HorizontalPodAutoscalerBehavior) (*in).DeepCopyInto(*out) } return diff --git a/pkg/canary/deployment_controller.go b/pkg/canary/deployment_controller.go index 708f4bab..d8f8a946 100644 --- a/pkg/canary/deployment_controller.go +++ b/pkg/canary/deployment_controller.go @@ -191,14 +191,6 @@ func (c *DeploymentController) ScaleFromZero(cd *flaggerv1.Canary) error { if hpa.Spec.MinReplicas != nil && *hpa.Spec.MinReplicas > 1 { replicas = hpa.Spec.MinReplicas } - } else { - // fallback to v2beta2 - hpa, err := c.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers(cd.Namespace).Get(context.TODO(), cd.Spec.AutoscalerRef.Name, metav1.GetOptions{}) - if err == nil { - if hpa.Spec.MinReplicas != nil && *hpa.Spec.MinReplicas > 1 { - replicas = hpa.Spec.MinReplicas - } - } } } else if cd.Spec.AutoscalerRef.Kind == "ScaledObject" { so, err := c.flaggerClient.KedaV1alpha1().ScaledObjects(cd.Namespace).Get(context.TODO(), cd.Spec.AutoscalerRef.Name, metav1.GetOptions{}) diff --git a/pkg/canary/deployment_fixture_test.go b/pkg/canary/deployment_fixture_test.go index 7ed0ec48..42688b9e 100644 --- a/pkg/canary/deployment_fixture_test.go +++ b/pkg/canary/deployment_fixture_test.go @@ -398,7 +398,7 @@ func newDeploymentControllerTestCanary(cc canaryConfigs) *flaggerv1.Canary { }, AutoscalerRef: &flaggerv1.AutoscalerReference{ Name: "podinfo", - APIVersion: "autoscaling/v2beta2", + APIVersion: "autoscaling/v2", Kind: "HorizontalPodAutoscaler", }, Service: flaggerv1.CanaryService{ Port: 9898, diff --git a/pkg/canary/hpa_reconciler.go b/pkg/canary/hpa_reconciler.go index fa76e667..77d50e9d 100644 --- a/pkg/canary/hpa_reconciler.go +++ b/pkg/canary/hpa_reconciler.go @@ -9,7 +9,6 @@ import ( "github.com/google/go-cmp/cmp" "go.uber.org/zap" hpav2 "k8s.io/api/autoscaling/v2" - hpav2beta2 "k8s.io/api/autoscaling/v2beta2" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -35,28 +34,19 @@ func (hr *HPAReconciler) ReconcilePrimaryScaler(cd *flaggerv1.Canary, init bool) } func (hr *HPAReconciler) reconcilePrimaryHpa(cd *flaggerv1.Canary, init bool) error { - var betaHpa *hpav2beta2.HorizontalPodAutoscaler hpa, err := hr.kubeClient.AutoscalingV2().HorizontalPodAutoscalers(cd.Namespace).Get(context.TODO(), cd.Spec.AutoscalerRef.Name, metav1.GetOptions{}) if err != nil { hpa = nil - hr.logger.Debugf("v2 HorizontalPodAutoscaler %s.%s get query error: %s; falling back to v2beta2", + hr.logger.Debugf("v2 HorizontalPodAutoscaler %s.%s get query error: %s;", cd.Namespace, cd.Spec.AutoscalerRef.Name, err) - var betaErr error - betaHpa, betaErr = hr.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers(cd.Namespace).Get(context.TODO(), cd.Spec.AutoscalerRef.Name, metav1.GetOptions{}) - if betaErr != nil { - return fmt.Errorf("HorizontalPodAutoscaler %s.%s get query error for both v2beta2: %s and v2: %s", - cd.Spec.AutoscalerRef.Name, cd.Namespace, betaErr, err) - } + return fmt.Errorf("HorizontalPodAutoscaler %s.%s get query error: %s", + cd.Spec.AutoscalerRef.Name, cd.Namespace, err) } if hpa != nil { if err = hr.reconcilePrimaryHpaV2(cd, hpa, init); err != nil { return err } - } else if betaHpa != nil { - if err = hr.reconcilePrimaryHpaV2Beta2(cd, betaHpa, init); err != nil { - return err - } } return nil @@ -155,99 +145,6 @@ func (hr *HPAReconciler) reconcilePrimaryHpaV2(cd *flaggerv1.Canary, hpa *hpav2. return nil } -func (hr *HPAReconciler) reconcilePrimaryHpaV2Beta2(cd *flaggerv1.Canary, hpa *hpav2beta2.HorizontalPodAutoscaler, init bool) error { - primaryName := fmt.Sprintf("%s-primary", cd.Spec.TargetRef.Name) - - hpaSpec := hpav2beta2.HorizontalPodAutoscalerSpec{ - ScaleTargetRef: hpav2beta2.CrossVersionObjectReference{ - Name: primaryName, - Kind: hpa.Spec.ScaleTargetRef.Kind, - APIVersion: hpa.Spec.ScaleTargetRef.APIVersion, - }, - MinReplicas: hpa.Spec.MinReplicas, - MaxReplicas: hpa.Spec.MaxReplicas, - Metrics: hpa.Spec.Metrics, - Behavior: hpa.Spec.Behavior, - } - - if replicas := cd.Spec.AutoscalerRef.PrimaryScalerReplicas; replicas != nil { - if minReplicas := replicas.MinReplicas; minReplicas != nil { - hpaSpec.MinReplicas = minReplicas - } - if maxReplicas := replicas.MaxReplicas; maxReplicas != nil { - hpaSpec.MaxReplicas = *maxReplicas - } - } - - primaryHpaName := fmt.Sprintf("%s-primary", cd.Spec.AutoscalerRef.Name) - primaryHpa, err := hr.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers(cd.Namespace).Get(context.TODO(), primaryHpaName, metav1.GetOptions{}) - - // create HPA - if errors.IsNotFound(err) { - primaryHpa = &hpav2beta2.HorizontalPodAutoscaler{ - ObjectMeta: makeObjectMeta(primaryHpaName, hpa.Labels, cd), - Spec: hpaSpec, - } - - _, err = hr.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers(cd.Namespace).Create(context.TODO(), primaryHpa, metav1.CreateOptions{}) - if err != nil { - return fmt.Errorf("creating HorizontalPodAutoscaler v2beta2 %s.%s failed: %w", - primaryHpa.Name, primaryHpa.Namespace, err) - } - hr.logger.With("canary", fmt.Sprintf("%s.%s", cd.Name, cd.Namespace)).Infof( - "HorizontalPodAutoscaler v2beta2 %s.%s created", primaryHpa.GetName(), cd.Namespace) - return nil - } else if err != nil { - return fmt.Errorf("HorizontalPodAutoscaler v2beta2 %s.%s get query failed: %w", - primaryHpa.Name, primaryHpa.Namespace, err) - } - - // update HPA - if !init && primaryHpa != nil { - targetFields := hpaFields{ - metrics: hpaSpec.Metrics, - behavior: hpaSpec.Behavior, - annotations: hpa.Annotations, - labels: hpa.Labels, - min: hpaSpec.MinReplicas, - max: hpaSpec.MaxReplicas, - } - primaryFields := hpaFields{ - metrics: primaryHpa.Spec.Metrics, - behavior: primaryHpa.Spec.Behavior, - annotations: primaryHpa.Annotations, - labels: primaryHpa.Labels, - min: primaryHpa.Spec.MinReplicas, - max: primaryHpa.Spec.MaxReplicas, - } - if hasHPAChanged(targetFields, primaryFields) { - err = retry.RetryOnConflict(retry.DefaultRetry, func() error { - primaryHpa, err := hr.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers(cd.Namespace).Get(context.TODO(), primaryHpaName, metav1.GetOptions{}) - if err != nil { - return err - } - primaryHpaClone := primaryHpa.DeepCopy() - primaryHpaClone.Spec.MaxReplicas = hpaSpec.MaxReplicas - primaryHpaClone.Spec.MinReplicas = hpaSpec.MinReplicas - primaryHpaClone.Spec.Metrics = hpaSpec.Metrics - primaryHpaClone.Spec.Behavior = hpaSpec.Behavior - - hr.updateObjectMeta(primaryHpaClone.ObjectMeta, hpa.ObjectMeta) - - _, err = hr.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers(cd.Namespace).Update(context.TODO(), primaryHpaClone, metav1.UpdateOptions{}) - return err - }) - if err != nil { - return fmt.Errorf("updating HorizontalPodAutoscaler v2beta2 %s.%s failed: %w", - primaryHpa.Name, primaryHpa.Namespace, err) - } - hr.logger.With("canary", fmt.Sprintf("%s.%s", cd.Name, cd.Namespace)). - Infof("HorizontalPodAutoscaler v2beta2 %s.%s updated", primaryHpa.GetName(), cd.Namespace) - } - } - return nil -} - func (hr *HPAReconciler) PauseTargetScaler(cd *flaggerv1.Canary) error { return nil } diff --git a/pkg/canary/hpa_reconciler_test.go b/pkg/canary/hpa_reconciler_test.go index 8be8e156..59bb2090 100644 --- a/pkg/canary/hpa_reconciler_test.go +++ b/pkg/canary/hpa_reconciler_test.go @@ -8,8 +8,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" hpav2 "k8s.io/api/autoscaling/v2" - hpav2beta2 "k8s.io/api/autoscaling/v2beta2" - "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -17,27 +15,17 @@ func Test_reconcilePrimaryHpa(t *testing.T) { mocks := newScalerReconcilerFixture(scalerConfig{ targetName: "podinfo", scaler: "HorizontalPodAutoscaler", - // avoid creating a v2 HPA. - excludeObjs: []string{"HPAV2"}, }) hpaReconciler := mocks.scalerReconciler.(*HPAReconciler) err := hpaReconciler.reconcilePrimaryHpa(mocks.canary, true) require.NoError(t, err) - // assert that we fallback to v2beta2, when HPAv2 fails. - _, err = mocks.kubeClient.AutoscalingV2().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{}) - assert.True(t, errors.IsNotFound(err)) - - hpa, err := mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{}) - require.NoError(t, err) - require.NotNil(t, hpa) - mocks = newScalerReconcilerFixture(scalerConfig{ targetName: "podinfo", scaler: "HorizontalPodAutoscaler", // avoid creating _any_ HPAs. - excludeObjs: []string{"HPAV2", "HPAV2Beta2"}, + excludeObjs: []string{"HPAV2"}, }) hpaReconciler = mocks.scalerReconciler.(*HPAReconciler) // assert that we return an error if no HPAs are found. @@ -88,48 +76,3 @@ func Test_reconcilePrimaryHpaV2(t *testing.T) { assert.Equal(t, primaryHPA.Spec.MinReplicas, mocks.canary.Spec.AutoscalerRef.PrimaryScalerReplicas.MinReplicas) assert.Equal(t, primaryHPA.Spec.MaxReplicas, *mocks.canary.Spec.AutoscalerRef.PrimaryScalerReplicas.MaxReplicas) } - -func Test_reconcilePrimaryHpaV2Beta2(t *testing.T) { - mocks := newScalerReconcilerFixture(scalerConfig{ - targetName: "podinfo", - scaler: "HorizontalPodAutoscaler", - }) - - hpaReconciler := mocks.scalerReconciler.(*HPAReconciler) - - hpa, err := mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo", metav1.GetOptions{}) - require.NoError(t, err) - - err = hpaReconciler.reconcilePrimaryHpaV2Beta2(mocks.canary, hpa, true) - require.NoError(t, err) - - primaryHPA, err := mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{}) - require.NoError(t, err) - assert.Equal(t, int(*primaryHPA.Spec.Metrics[0].Resource.Target.AverageUtilization), 99) - - hpa.Spec.Metrics[0].Resource.Target = hpav2beta2.MetricTarget{AverageUtilization: int32p(50)} - hpa.Spec.MaxReplicas = 10 - _, err = mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Update(context.TODO(), hpa, metav1.UpdateOptions{}) - require.NoError(t, err) - - err = hpaReconciler.reconcilePrimaryHpaV2Beta2(mocks.canary, hpa, false) - require.NoError(t, err) - - primaryHPA, err = mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{}) - require.NoError(t, err) - assert.Equal(t, int(*primaryHPA.Spec.Metrics[0].Resource.Target.AverageUtilization), 50) - assert.Equal(t, int(primaryHPA.Spec.MaxReplicas), 10) - - // Test reconcile with PrimaryHorizontalPodAutoscalerOverride - mocks.canary.Spec.AutoscalerRef.PrimaryScalerReplicas = &flaggerv1.ScalerReplicas{ - MinReplicas: int32p(2), - MaxReplicas: int32p(15), - } - err = hpaReconciler.reconcilePrimaryHpaV2Beta2(mocks.canary, hpa, false) - require.NoError(t, err) - - primaryHPA, err = mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{}) - require.NoError(t, err) - assert.Equal(t, primaryHPA.Spec.MinReplicas, mocks.canary.Spec.AutoscalerRef.PrimaryScalerReplicas.MinReplicas) - assert.Equal(t, primaryHPA.Spec.MaxReplicas, *mocks.canary.Spec.AutoscalerRef.PrimaryScalerReplicas.MaxReplicas) -} diff --git a/pkg/canary/scaler_reconciler_fixture_test.go b/pkg/canary/scaler_reconciler_fixture_test.go index ce8c7003..3a4e22cf 100644 --- a/pkg/canary/scaler_reconciler_fixture_test.go +++ b/pkg/canary/scaler_reconciler_fixture_test.go @@ -3,7 +3,6 @@ package canary import ( "go.uber.org/zap" hpav2 "k8s.io/api/autoscaling/v2" - hpav2beta2 "k8s.io/api/autoscaling/v2beta2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/kubernetes" @@ -40,7 +39,6 @@ func newScalerReconcilerFixture(cfg scalerConfig) scalerReconcilerFixture { kubeClient := fake.NewSimpleClientset( newScalerReconcilerTestHPAV2(), - newScalerReconcilerTestHPAV2Beta2(), ) for _, obj := range cfg.excludeObjs { if obj == "HPAV2" { @@ -50,13 +48,6 @@ func newScalerReconcilerFixture(cfg scalerConfig) scalerReconcilerFixture { Resource: "horizontalpodautoscalers", }, "default", "podinfo") } - if obj == "HPAV2Beta2" { - kubeClient.Tracker().Delete(schema.GroupVersionResource{ - Group: "autoscaling", - Version: "v2beta2", - Resource: "horizontalpodautoscalers", - }, "default", "podinfo") - } } logger, _ := logger.NewLogger("debug") @@ -88,36 +79,6 @@ func newScalerReconcilerFixture(cfg scalerConfig) scalerReconcilerFixture { } } -func newScalerReconcilerTestHPAV2Beta2() *hpav2beta2.HorizontalPodAutoscaler { - h := &hpav2beta2.HorizontalPodAutoscaler{ - TypeMeta: metav1.TypeMeta{APIVersion: hpav2beta2.SchemeGroupVersion.String()}, - ObjectMeta: metav1.ObjectMeta{ - Namespace: "default", - Name: "podinfo", - }, - Spec: hpav2beta2.HorizontalPodAutoscalerSpec{ - ScaleTargetRef: hpav2beta2.CrossVersionObjectReference{ - Name: "podinfo", - APIVersion: "apps/v1", - Kind: "Deployment", - }, - Metrics: []hpav2beta2.MetricSpec{ - { - Type: "Resource", - Resource: &hpav2beta2.ResourceMetricSource{ - Name: "cpu", - Target: hpav2beta2.MetricTarget{ - AverageUtilization: int32p(99), - }, - }, - }, - }, - }, - } - - return h -} - func newScalerReconcilerTestHPAV2() *hpav2.HorizontalPodAutoscaler { h := &hpav2.HorizontalPodAutoscaler{ TypeMeta: metav1.TypeMeta{APIVersion: hpav2.SchemeGroupVersion.String()}, diff --git a/pkg/controller/scheduler_deployment_fixture_test.go b/pkg/controller/scheduler_deployment_fixture_test.go index 4efb9b63..a4e04622 100644 --- a/pkg/controller/scheduler_deployment_fixture_test.go +++ b/pkg/controller/scheduler_deployment_fixture_test.go @@ -26,7 +26,7 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap" appsv1 "k8s.io/api/apps/v1" - hpav2 "k8s.io/api/autoscaling/v2beta2" + hpav2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -300,7 +300,7 @@ func newDeploymentTestCanary() *flaggerv1.Canary { }, AutoscalerRef: &flaggerv1.AutoscalerReference{ Name: "podinfo", - APIVersion: "autoscaling/v2beta2", + APIVersion: "autoscaling/v2", Kind: "HorizontalPodAutoscaler", }, Service: flaggerv1.CanaryService{ Port: 9898, @@ -362,7 +362,7 @@ func newDeploymentTestCanaryAB() *flaggerv1.Canary { }, AutoscalerRef: &flaggerv1.AutoscalerReference{ Name: "podinfo", - APIVersion: "autoscaling/v2beta2", + APIVersion: "autoscaling/v2", Kind: "HorizontalPodAutoscaler", }, Service: flaggerv1.CanaryService{ Port: 9898,