Merge pull request #740 from tr-fteixeira/hpa-behavior

Add support to HPA behaviors on canaries
This commit is contained in:
Stefan Prodan
2020-12-07 11:13:52 +02:00
committed by GitHub
4 changed files with 32 additions and 25 deletions
+14 -11
View File
@@ -7,7 +7,7 @@ import (
"github.com/google/go-cmp/cmp"
"go.uber.org/zap"
appsv1 "k8s.io/api/apps/v1"
hpav1 "k8s.io/api/autoscaling/v2beta1"
hpav2 "k8s.io/api/autoscaling/v2beta2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -292,14 +292,14 @@ func (c *DeploymentController) createPrimaryDeployment(cd *flaggerv1.Canary, inc
func (c *DeploymentController) reconcilePrimaryHpa(cd *flaggerv1.Canary, init bool) error {
primaryName := fmt.Sprintf("%s-primary", cd.Spec.TargetRef.Name)
hpa, err := c.kubeClient.AutoscalingV2beta1().HorizontalPodAutoscalers(cd.Namespace).Get(context.TODO(), cd.Spec.AutoscalerRef.Name, metav1.GetOptions{})
hpa, err := c.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers(cd.Namespace).Get(context.TODO(), cd.Spec.AutoscalerRef.Name, metav1.GetOptions{})
if err != nil {
return fmt.Errorf("HorizontalPodAutoscaler %s.%s get query error: %w",
cd.Spec.AutoscalerRef.Name, cd.Namespace, err)
}
hpaSpec := hpav1.HorizontalPodAutoscalerSpec{
ScaleTargetRef: hpav1.CrossVersionObjectReference{
hpaSpec := hpav2.HorizontalPodAutoscalerSpec{
ScaleTargetRef: hpav2.CrossVersionObjectReference{
Name: primaryName,
Kind: hpa.Spec.ScaleTargetRef.Kind,
APIVersion: hpa.Spec.ScaleTargetRef.APIVersion,
@@ -307,14 +307,15 @@ func (c *DeploymentController) reconcilePrimaryHpa(cd *flaggerv1.Canary, init bo
MinReplicas: hpa.Spec.MinReplicas,
MaxReplicas: hpa.Spec.MaxReplicas,
Metrics: hpa.Spec.Metrics,
Behavior: hpa.Spec.Behavior,
}
primaryHpaName := fmt.Sprintf("%s-primary", cd.Spec.AutoscalerRef.Name)
primaryHpa, err := c.kubeClient.AutoscalingV2beta1().HorizontalPodAutoscalers(cd.Namespace).Get(context.TODO(), primaryHpaName, metav1.GetOptions{})
primaryHpa, err := c.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers(cd.Namespace).Get(context.TODO(), primaryHpaName, metav1.GetOptions{})
// create HPA
if errors.IsNotFound(err) {
primaryHpa = &hpav1.HorizontalPodAutoscaler{
primaryHpa = &hpav2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: primaryHpaName,
Namespace: cd.Namespace,
@@ -330,7 +331,7 @@ func (c *DeploymentController) reconcilePrimaryHpa(cd *flaggerv1.Canary, init bo
Spec: hpaSpec,
}
_, err = c.kubeClient.AutoscalingV2beta1().HorizontalPodAutoscalers(cd.Namespace).Create(context.TODO(), primaryHpa, metav1.CreateOptions{})
_, err = c.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers(cd.Namespace).Create(context.TODO(), primaryHpa, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("creating HorizontalPodAutoscaler %s.%s failed: %w",
primaryHpa.Name, primaryHpa.Namespace, err)
@@ -345,15 +346,17 @@ func (c *DeploymentController) reconcilePrimaryHpa(cd *flaggerv1.Canary, init bo
// update HPA
if !init && primaryHpa != nil {
diff := cmp.Diff(hpaSpec.Metrics, primaryHpa.Spec.Metrics)
if diff != "" || int32Default(hpaSpec.MinReplicas) != int32Default(primaryHpa.Spec.MinReplicas) || hpaSpec.MaxReplicas != primaryHpa.Spec.MaxReplicas {
fmt.Println(diff, hpaSpec.MinReplicas, primaryHpa.Spec.MinReplicas, hpaSpec.MaxReplicas, primaryHpa.Spec.MaxReplicas)
diffMetrics := cmp.Diff(hpaSpec.Metrics, primaryHpa.Spec.Metrics)
diffBehavior := cmp.Diff(hpaSpec.Behavior, primaryHpa.Spec.Behavior)
if diffMetrics != "" || diffBehavior != "" || int32Default(hpaSpec.MinReplicas) != int32Default(primaryHpa.Spec.MinReplicas) || hpaSpec.MaxReplicas != primaryHpa.Spec.MaxReplicas {
fmt.Println(diffMetrics, diffBehavior, hpaSpec.MinReplicas, primaryHpa.Spec.MinReplicas, hpaSpec.MaxReplicas, primaryHpa.Spec.MaxReplicas)
hpaClone := primaryHpa.DeepCopy()
hpaClone.Spec.MaxReplicas = hpaSpec.MaxReplicas
hpaClone.Spec.MinReplicas = hpaSpec.MinReplicas
hpaClone.Spec.Metrics = hpaSpec.Metrics
hpaClone.Spec.Behavior = hpaSpec.Behavior
_, err := c.kubeClient.AutoscalingV2beta1().HorizontalPodAutoscalers(cd.Namespace).Update(context.TODO(), hpaClone, metav1.UpdateOptions{})
_, err := c.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers(cd.Namespace).Update(context.TODO(), hpaClone, metav1.UpdateOptions{})
if err != nil {
return fmt.Errorf("updating HorizontalPodAutoscaler %s.%s failed: %w",
hpaClone.Name, hpaClone.Namespace, err)
+5 -5
View File
@@ -31,7 +31,7 @@ func TestDeploymentController_Sync_ConsistentNaming(t *testing.T) {
primarySelectorValue := depPrimary.Spec.Selector.MatchLabels[dc.label]
assert.Equal(t, primarySelectorValue, fmt.Sprintf("%s-primary", dc.labelValue))
hpaPrimary, err := mocks.kubeClient.AutoscalingV2beta1().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{})
hpaPrimary, err := mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, depPrimary.Name, hpaPrimary.Spec.ScaleTargetRef.Name)
}
@@ -52,7 +52,7 @@ func TestDeploymentController_Sync_InconsistentNaming(t *testing.T) {
primarySelectorValue := depPrimary.Spec.Selector.MatchLabels[dc.label]
assert.Equal(t, primarySelectorValue, fmt.Sprintf("%s-primary", dc.labelValue))
hpaPrimary, err := mocks.kubeClient.AutoscalingV2beta1().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{})
hpaPrimary, err := mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, depPrimary.Name, hpaPrimary.Spec.ScaleTargetRef.Name)
}
@@ -70,13 +70,13 @@ func TestDeploymentController_Promote(t *testing.T) {
_, err = mocks.kubeClient.CoreV1().ConfigMaps("default").Update(context.TODO(), config2, metav1.UpdateOptions{})
require.NoError(t, err)
hpa, err := mocks.kubeClient.AutoscalingV2beta1().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo", metav1.GetOptions{})
hpa, err := mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo", metav1.GetOptions{})
require.NoError(t, err)
hpaClone := hpa.DeepCopy()
hpaClone.Spec.MaxReplicas = 2
_, err = mocks.kubeClient.AutoscalingV2beta1().HorizontalPodAutoscalers("default").Update(context.TODO(), hpaClone, metav1.UpdateOptions{})
_, err = mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Update(context.TODO(), hpaClone, metav1.UpdateOptions{})
require.NoError(t, err)
err = mocks.controller.Promote(mocks.canary)
@@ -93,7 +93,7 @@ func TestDeploymentController_Promote(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, config2.Data["color"], configPrimary.Data["color"])
hpaPrimary, err := mocks.kubeClient.AutoscalingV2beta1().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{})
hpaPrimary, err := mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, int32(2), hpaPrimary.Spec.MaxReplicas)
}
+6 -4
View File
@@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/require"
"go.uber.org/zap"
appsv1 "k8s.io/api/apps/v1"
hpav2 "k8s.io/api/autoscaling/v2beta1"
hpav2 "k8s.io/api/autoscaling/v2beta2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -319,7 +319,7 @@ func newDeploymentControllerTestCanary(cc canaryConfigs) *flaggerv1.Canary {
},
AutoscalerRef: &flaggerv1.CrossNamespaceObjectReference{
Name: "podinfo",
APIVersion: "autoscaling/v2beta1",
APIVersion: "autoscaling/v2beta2",
Kind: "HorizontalPodAutoscaler",
}, Service: flaggerv1.CanaryService{
Port: 9898,
@@ -766,8 +766,10 @@ func newDeploymentControllerTestHPA() *hpav2.HorizontalPodAutoscaler {
{
Type: "Resource",
Resource: &hpav2.ResourceMetricSource{
Name: "cpu",
TargetAverageUtilization: int32p(99),
Name: "cpu",
Target: hpav2.MetricTarget{
AverageUtilization: int32p(99),
},
},
},
},
@@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/require"
"go.uber.org/zap"
appsv1 "k8s.io/api/apps/v1"
hpav2 "k8s.io/api/autoscaling/v2beta1"
hpav2 "k8s.io/api/autoscaling/v2beta2"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
@@ -280,7 +280,7 @@ func newDeploymentTestCanary() *flaggerv1.Canary {
},
AutoscalerRef: &flaggerv1.CrossNamespaceObjectReference{
Name: "podinfo",
APIVersion: "autoscaling/v2beta1",
APIVersion: "autoscaling/v2beta2",
Kind: "HorizontalPodAutoscaler",
}, Service: flaggerv1.CanaryService{
Port: 9898,
@@ -342,7 +342,7 @@ func newDeploymentTestCanaryAB() *flaggerv1.Canary {
},
AutoscalerRef: &flaggerv1.CrossNamespaceObjectReference{
Name: "podinfo",
APIVersion: "autoscaling/v2beta1",
APIVersion: "autoscaling/v2beta2",
Kind: "HorizontalPodAutoscaler",
}, Service: flaggerv1.CanaryService{
Port: 9898,
@@ -694,8 +694,10 @@ func newDeploymentTestHPA() *hpav2.HorizontalPodAutoscaler {
{
Type: "Resource",
Resource: &hpav2.ResourceMetricSource{
Name: "cpu",
TargetAverageUtilization: int32p(99),
Name: "cpu",
Target: hpav2.MetricTarget{
AverageUtilization: int32p(99),
},
},
},
},