fix: fix HorizontalPodAutoscaler update at every reconcile

This commit is contained in:
Jonas Kaninda
2024-11-27 20:08:26 +01:00
parent 59e2f0164b
commit e4ca801d29
4 changed files with 13 additions and 21 deletions

View File

@@ -18,8 +18,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log"
) )
// createDeployment creates Kubernetes deployment // createUpdateDeployment creates Kubernetes deployment
func createDeployment(r GatewayReconciler, ctx context.Context, req ctrl.Request, gateway gomaprojv1beta1.Gateway, imageName string) error { func createUpdateDeployment(r GatewayReconciler, ctx context.Context, req ctrl.Request, gateway gomaprojv1beta1.Gateway, imageName string) error {
logger := log.FromContext(ctx) logger := log.FromContext(ctx)
// Define the desired Deployment // Define the desired Deployment
deployment := &v1.Deployment{ deployment := &v1.Deployment{

View File

@@ -19,21 +19,19 @@ package controller
import ( import (
"context" "context"
"fmt" "fmt"
v1 "k8s.io/api/apps/v1"
autoscalingv1 "k8s.io/api/autoscaling/v1"
"strings"
gomaprojv1beta1 "github.com/jkaninda/goma-operator/api/v1beta1" gomaprojv1beta1 "github.com/jkaninda/goma-operator/api/v1beta1"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
v1 "k8s.io/api/apps/v1"
autoscalingv1 "k8s.io/api/autoscaling/v1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime" ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log"
"strings"
) )
// GatewayReconciler reconciles a Gateway object // GatewayReconciler reconciles a Gateway object
@@ -157,7 +155,7 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
} }
} }
err = createDeployment(*r, ctx, req, *gateway, imageName) err = createUpdateDeployment(*r, ctx, req, *gateway, imageName)
if err != nil { if err != nil {
addCondition(&gateway.Status, "DeploymentNotReady", metav1.ConditionFalse, "DeploymentNotReady", "Failed to created deployment for Gateway") addCondition(&gateway.Status, "DeploymentNotReady", metav1.ConditionFalse, "DeploymentNotReady", "Failed to created deployment for Gateway")
logger.Error(err, "Failed to create Deployment") logger.Error(err, "Failed to create Deployment")
@@ -185,11 +183,10 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
} }
gateway.Status.Routes = int32(len(gomaConfig.Gateway.Routes)) gateway.Status.Routes = int32(len(gomaConfig.Gateway.Routes))
if err := r.updateStatus(ctx, gateway); err != nil { if err = r.updateStatus(ctx, gateway); err != nil {
logger.Error(err, "Failed to update resource status") logger.Error(err, "Failed to update resource status")
return ctrl.Result{}, err return ctrl.Result{}, err
} }
logger.Info("Successfully updated resource status") logger.Info("Successfully updated resource status")
return ctrl.Result{}, nil return ctrl.Result{}, nil
} }

View File

@@ -2,7 +2,6 @@ package controller
import ( import (
"context" "context"
"fmt"
"slices" "slices"
"strings" "strings"
@@ -35,8 +34,6 @@ func gatewayConfig(r GatewayReconciler, ctx context.Context, req ctrl.Request, g
logger.Error(err, "Failed to list Middlewares") logger.Error(err, "Failed to list Middlewares")
return *gomaConfig return *gomaConfig
} }
logger.Info(fmt.Sprintf("Listing Routes: size: %d", len(routes.Items)))
for _, route := range routes.Items { for _, route := range routes.Items {
logger.Info("Found Route", "Name", route.Name) logger.Info("Found Route", "Name", route.Name)
if route.Spec.Gateway == gateway.Name { if route.Spec.Gateway == gateway.Name {
@@ -76,8 +73,6 @@ func updateGatewayConfig(r RouteReconciler, ctx context.Context, req ctrl.Reques
logger.Error(err, "Failed to list Middlewares") logger.Error(err, "Failed to list Middlewares")
return err return err
} }
logger.Info(fmt.Sprintf("Listing Routes: size: %d", len(routes.Items)))
for _, route := range routes.Items { for _, route := range routes.Items {
logger.Info("Found Route", "Name", route.Name) logger.Info("Found Route", "Name", route.Name)
if route.Spec.Gateway == gateway.Name { if route.Spec.Gateway == gateway.Name {

View File

@@ -83,6 +83,7 @@ func createHpa(r GatewayReconciler, ctx context.Context, req ctrl.Request, gatew
} }
logger.Info("Created HorizontalPodAutoscaler", "HorizontalPodAutoscaler.Name", hpa.Name) logger.Info("Created HorizontalPodAutoscaler", "HorizontalPodAutoscaler.Name", hpa.Name)
} else { } else {
logger.Info("HorizontalPodAutoscaler already exists", "HorizontalPodAutoscaler.Name", hpa.Name)
// Update the Deployment if the spec has changed // Update the Deployment if the spec has changed
if !equalHpaSpec(existHpa, *hpa) { if !equalHpaSpec(existHpa, *hpa) {
existHpa.Spec = hpa.Spec existHpa.Spec = hpa.Spec
@@ -98,17 +99,16 @@ func createHpa(r GatewayReconciler, ctx context.Context, req ctrl.Request, gatew
// Helper function to compare Deployment specs // Helper function to compare Deployment specs
func equalHpaSpec(existing, desired autoscalingv2.HorizontalPodAutoscaler) bool { func equalHpaSpec(existing, desired autoscalingv2.HorizontalPodAutoscaler) bool {
// A deep equality check or field-by-field comparison would be more accurate if *existing.Spec.MinReplicas != *desired.Spec.MinReplicas {
if existing.Spec.MinReplicas != desired.Spec.MinReplicas {
return false return false
} }
if existing.Spec.MaxReplicas != desired.Spec.MaxReplicas { if existing.Spec.MaxReplicas != desired.Spec.MaxReplicas {
return false return false
} }
if existing.Spec.Metrics[0].Resource.Target.AverageUtilization != desired.Spec.Metrics[0].Resource.Target.AverageUtilization { if *existing.Spec.Metrics[0].Resource.Target.AverageUtilization != *desired.Spec.Metrics[0].Resource.Target.AverageUtilization {
return false return false
} }
if existing.Spec.Metrics[1].Resource.Target.AverageUtilization != desired.Spec.Metrics[1].Resource.Target.AverageUtilization { if *existing.Spec.Metrics[1].Resource.Target.AverageUtilization != *desired.Spec.Metrics[1].Resource.Target.AverageUtilization {
return false return false
} }
return true return true