Skip to content

Commit

Permalink
Merge pull request #3729 from jwcesign/cronhpa-imp
Browse files Browse the repository at this point in the history
feat: Support CronFederatedHPA
  • Loading branch information
karmada-bot committed Jul 3, 2023
2 parents b01cf50 + 068022d commit 3909fcc
Show file tree
Hide file tree
Showing 56 changed files with 6,731 additions and 12 deletions.
14 changes: 14 additions & 0 deletions artifacts/deploy/webhook-configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,17 @@ webhooks:
sideEffects: None
admissionReviewVersions: [ "v1" ]
timeoutSeconds: 10
- name: cronfederatedhpa.karmada.io
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["autoscaling.karmada.io"]
apiVersions: ["*"]
resources: ["cronfederatedhpas"]
scope: "Namespaced"
clientConfig:
url: https://karmada-webhook.karmada-system.svc:443/validate-cronfederatedhpa
caBundle: {{caBundle}}
failurePolicy: Fail
sideEffects: None
admissionReviewVersions: [ "v1" ]
timeoutSeconds: 10
2 changes: 2 additions & 0 deletions cluster/images/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ FROM alpine:3.18.2
ARG BINARY

RUN apk add --no-cache ca-certificates
#tzdata is used to parse the time zone information when using CronFederatedHPA
RUN apk add --no-cache tzdata

COPY ${BINARY} /bin/${BINARY}
2 changes: 2 additions & 0 deletions cluster/images/buildx.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ ARG BINARY
ARG TARGETPLATFORM

RUN apk add --no-cache ca-certificates
#tzdata is used to parse the time zone information when using CronFederatedHPA
RUN apk add --no-cache tzdata

COPY ${TARGETPLATFORM}/${BINARY} /bin/${BINARY}
14 changes: 14 additions & 0 deletions cmd/controller-manager/app/controllermanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/karmada-io/karmada/pkg/controllers/binding"
"github.com/karmada-io/karmada/pkg/controllers/cluster"
controllerscontext "github.com/karmada-io/karmada/pkg/controllers/context"
"github.com/karmada-io/karmada/pkg/controllers/cronfederatedhpa"
"github.com/karmada-io/karmada/pkg/controllers/execution"
"github.com/karmada-io/karmada/pkg/controllers/federatedhpa"
metricsclient "github.com/karmada-io/karmada/pkg/controllers/federatedhpa/metrics"
Expand Down Expand Up @@ -204,6 +205,7 @@ func init() {
controllers["gracefulEviction"] = startGracefulEvictionController
controllers["applicationFailover"] = startApplicationFailoverController
controllers["federatedHorizontalPodAutoscaler"] = startFederatedHorizontalPodAutoscalerController
controllers["cronFederatedHorizontalPodAutoscaler"] = startCronFederatedHorizontalPodAutoscalerController
}

func startClusterController(ctx controllerscontext.Context) (enabled bool, err error) {
Expand Down Expand Up @@ -591,6 +593,18 @@ func startFederatedHorizontalPodAutoscalerController(ctx controllerscontext.Cont
return true, nil
}

func startCronFederatedHorizontalPodAutoscalerController(ctx controllerscontext.Context) (enabled bool, err error) {
cronFHPAController := cronfederatedhpa.CronFHPAController{
Client: ctx.Mgr.GetClient(),
EventRecorder: ctx.Mgr.GetEventRecorderFor(cronfederatedhpa.ControllerName),
RateLimiterOptions: ctx.Opts.RateLimiterOptions,
}
if err = cronFHPAController.SetupWithManager(ctx.Mgr); err != nil {
return false, err
}
return true, nil
}

// setupControllers initialize controllers and setup one by one.
func setupControllers(mgr controllerruntime.Manager, opts *options.Options, stopChan <-chan struct{}) {
restConfig := mgr.GetConfig()
Expand Down
2 changes: 2 additions & 0 deletions cmd/webhook/app/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/karmada-io/karmada/pkg/webhook/clusteroverridepolicy"
"github.com/karmada-io/karmada/pkg/webhook/clusterpropagationpolicy"
"github.com/karmada-io/karmada/pkg/webhook/configuration"
"github.com/karmada-io/karmada/pkg/webhook/cronfederatedhpa"
"github.com/karmada-io/karmada/pkg/webhook/federatedhpa"
"github.com/karmada-io/karmada/pkg/webhook/federatedresourcequota"
"github.com/karmada-io/karmada/pkg/webhook/multiclusteringress"
Expand Down Expand Up @@ -129,6 +130,7 @@ func Run(ctx context.Context, opts *options.Options) error {
hookServer.Register("/validate-resourceinterpreterwebhookconfiguration", &webhook.Admission{Handler: &configuration.ValidatingAdmission{}})
hookServer.Register("/validate-federatedresourcequota", &webhook.Admission{Handler: &federatedresourcequota.ValidatingAdmission{}})
hookServer.Register("/validate-federatedhpa", &webhook.Admission{Handler: &federatedhpa.ValidatingAdmission{}})
hookServer.Register("/validate-cronfederatedhpa", &webhook.Admission{Handler: &cronfederatedhpa.ValidatingAdmission{}})
hookServer.Register("/validate-resourceinterpretercustomization", &webhook.Admission{Handler: &resourceinterpretercustomization.ValidatingAdmission{Client: hookManager.GetClient()}})
hookServer.Register("/validate-multiclusteringress", &webhook.Admission{Handler: &multiclusteringress.ValidatingAdmission{}})
hookServer.Register("/mutate-federatedhpa", &webhook.Admission{Handler: &federatedhpa.MutatingAdmission{}})
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ module github.com/karmada-io/karmada
go 1.20

require (
github.com/adhocore/gronx v1.6.3
github.com/distribution/distribution/v3 v3.0.0-20210507173845-9329f6a62b67
github.com/emirpasic/gods v1.18.1
github.com/evanphx/json-patch/v5 v5.6.0
github.com/go-co-op/gocron v1.30.1
github.com/gogo/protobuf v1.3.2
github.com/golang/mock v1.6.0
github.com/google/go-cmp v0.5.9
Expand Down Expand Up @@ -133,7 +135,8 @@ require (
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/rivo/uniseg v0.4.2 // indirect
github.com/rogpeppe/go-internal v1.6.1 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/rs/zerolog v1.26.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/afero v1.9.3 // indirect
Expand Down
10 changes: 9 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/adhocore/gronx v1.6.3 h1:bnm5vieTrY3QQPpsfB0hrAaeaHDpuZTUC2LLCVMLe9c=
github.com/adhocore/gronx v1.6.3/go.mod h1:7oUY1WAU8rEJWmAxXR2DN0JaO4gi9khSgKjiRypqteg=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
Expand Down Expand Up @@ -246,6 +248,8 @@ github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2H
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/go-co-op/gocron v1.30.1 h1:tjWUvJl5KrcwpkEkSXFSQFr4F9h5SfV/m4+RX0cV2fs=
github.com/go-co-op/gocron v1.30.1/go.mod h1:39f6KNSGVOU1LO/ZOoZfcSxwlsJDQOKSu8erN0SH48Y=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
Expand Down Expand Up @@ -649,6 +653,7 @@ github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvI
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
Expand Down Expand Up @@ -702,11 +707,14 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/autoscaling/v1alpha1/well_known_constants.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package v1alpha1

const (
// FederatedHPAKind is the kind of FederatedHPA in group autoscaling.karmada.io
FederatedHPAKind = "FederatedHPA"

// QuerySourceAnnotationKey is the annotation used in karmada-metrics-adapter to
// record the query source cluster
QuerySourceAnnotationKey = "resource.karmada.io/query-from-cluster"
Expand Down
204 changes: 204 additions & 0 deletions pkg/controllers/cronfederatedhpa/cronfederatedhpa_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/*
Copyright 2023 The Karmada Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cronfederatedhpa

import (
"context"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/tools/record"
"k8s.io/klog/v2"
controllerruntime "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"

autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1"
"github.com/karmada-io/karmada/pkg/sharedcli/ratelimiterflag"
"github.com/karmada-io/karmada/pkg/util/helper"
)

const (
// ControllerName is the controller name that will be used when reporting events.
ControllerName = "cronfederatedhpa-controller"
)

// CronFHPAController is used to operate CronFederatedHPA.
type CronFHPAController struct {
client.Client // used to operate Cron resources.
EventRecorder record.EventRecorder

RateLimiterOptions ratelimiterflag.Options
CronHandler *CronHandler
}

// Reconcile performs a full reconciliation for the object referred to by the Request.
// The Controller will requeue the Request to be processed again if an error is non-nil or
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
func (c *CronFHPAController) Reconcile(ctx context.Context, req controllerruntime.Request) (controllerruntime.Result, error) {
klog.V(4).Infof("Reconciling CronFederatedHPA %s", req.NamespacedName)

cronFHPA := &autoscalingv1alpha1.CronFederatedHPA{}
if err := c.Client.Get(ctx, req.NamespacedName, cronFHPA); err != nil {
if apierrors.IsNotFound(err) {
klog.V(4).Infof("Begin to cleanup the cron jobs for CronFederatedHPA:%s", req.NamespacedName)
c.CronHandler.StopCronFHPAExecutor(req.NamespacedName.String())
return controllerruntime.Result{}, nil
}

klog.Errorf("Fail to get CronFederatedHPA(%s):%v", req.NamespacedName, err)
return controllerruntime.Result{Requeue: true}, err
}

// If this CronFederatedHPA is deleting, stop all related cron executors
if !cronFHPA.DeletionTimestamp.IsZero() {
c.CronHandler.StopCronFHPAExecutor(req.NamespacedName.String())
return controllerruntime.Result{}, nil
}

origRuleSets := sets.New[string]()
for _, history := range cronFHPA.Status.ExecutionHistories {
origRuleSets.Insert(history.RuleName)
}

// If scale target is updated, stop all the rule executors, and next steps will create the new executors
if c.CronHandler.CronFHPAScaleTargetRefUpdates(req.NamespacedName.String(), cronFHPA.Spec.ScaleTargetRef) {
c.CronHandler.StopCronFHPAExecutor(req.NamespacedName.String())
}

c.CronHandler.AddCronExecutorIfNotExist(req.NamespacedName.String())

newRuleSets := sets.New[string]()
for _, rule := range cronFHPA.Spec.Rules {
if err := c.processCronRule(cronFHPA, rule); err != nil {
return controllerruntime.Result{Requeue: true}, err
}
newRuleSets.Insert(rule.Name)
}

// If rule is deleted, remove the rule executor from the handler
for name := range origRuleSets {
if newRuleSets.Has(name) {
continue
}
c.CronHandler.StopRuleExecutor(req.NamespacedName.String(), name)
if err := c.removeCronFHPAHistory(cronFHPA, name); err != nil {
return controllerruntime.Result{Requeue: true}, err
}
}

return controllerruntime.Result{}, nil
}

// SetupWithManager creates a controller and register to controller manager.
func (c *CronFHPAController) SetupWithManager(mgr controllerruntime.Manager) error {
c.CronHandler = NewCronHandler(mgr.GetClient(), mgr.GetEventRecorderFor(ControllerName))
return controllerruntime.NewControllerManagedBy(mgr).
For(&autoscalingv1alpha1.CronFederatedHPA{}).
WithOptions(controller.Options{RateLimiter: ratelimiterflag.DefaultControllerRateLimiter(c.RateLimiterOptions)}).
Complete(c)
}

// processCronRule processes the cron rule
func (c *CronFHPAController) processCronRule(cronFHPA *autoscalingv1alpha1.CronFederatedHPA, rule autoscalingv1alpha1.CronFederatedHPARule) error {
cronFHPAKey := helper.GetCronFederatedHPAKey(cronFHPA)
if ruleOld, exists := c.CronHandler.RuleCronExecutorExists(cronFHPAKey, rule.Name); exists {
if equality.Semantic.DeepEqual(ruleOld, rule) {
return nil
}
c.CronHandler.StopRuleExecutor(cronFHPAKey, rule.Name)
}

if !helper.IsCronFederatedHPARuleSuspend(rule) {
if err := c.CronHandler.CreateCronJobForExecutor(cronFHPA, rule); err != nil {
c.EventRecorder.Event(cronFHPA, corev1.EventTypeWarning, "StartRuleFailed", err.Error())
klog.Errorf("Fail to start cron for CronFederatedHPA(%s) rule(%s):%v", cronFHPAKey, rule.Name, err)
return err
}
}

if err := c.updateRuleHistory(cronFHPA, rule); err != nil {
c.EventRecorder.Event(cronFHPA, corev1.EventTypeWarning, "UpdateCronFederatedHPAFailed", err.Error())
return err
}
return nil
}

// updateRuleHistory updates the rule history
func (c *CronFHPAController) updateRuleHistory(cronFHPA *autoscalingv1alpha1.CronFederatedHPA, rule autoscalingv1alpha1.CronFederatedHPARule) error {
var nextExecutionTime *metav1.Time
if !helper.IsCronFederatedHPARuleSuspend(rule) {
// If rule is not suspended, we should set the nextExecutionTime filed, or the nextExecutionTime will be nil
next, err := c.CronHandler.GetRuleNextExecuteTime(cronFHPA, rule.Name)
if err != nil {
klog.Errorf("Fail to get next execution time for CronFederatedHPA(%s/%s) rule(%s):%v",
cronFHPA.Namespace, cronFHPA.Name, rule.Name, err)
return err
}
nextExecutionTime = &metav1.Time{Time: next}
}

exists := false
for index, history := range cronFHPA.Status.ExecutionHistories {
if history.RuleName != rule.Name {
continue
}
exists = true
cronFHPA.Status.ExecutionHistories[index].NextExecutionTime = nextExecutionTime
break
}

if !exists {
ruleHistory := autoscalingv1alpha1.ExecutionHistory{
RuleName: rule.Name,
NextExecutionTime: nextExecutionTime,
}
cronFHPA.Status.ExecutionHistories = append(cronFHPA.Status.ExecutionHistories, ruleHistory)
}

if err := c.Client.Status().Update(context.Background(), cronFHPA); err != nil {
klog.Errorf("Fail to update CronFederatedHPA(%s/%s) rule(%s)'s next execution time:%v",
cronFHPA.Namespace, cronFHPA.Name, err)
return err
}

return nil
}

// removeCronFHPAHistory removes the rule history in status
func (c *CronFHPAController) removeCronFHPAHistory(cronFHPA *autoscalingv1alpha1.CronFederatedHPA, ruleName string) error {
exists := false
for index, history := range cronFHPA.Status.ExecutionHistories {
if history.RuleName != ruleName {
continue
}
cronFHPA.Status.ExecutionHistories = append(cronFHPA.Status.ExecutionHistories[:index], cronFHPA.Status.ExecutionHistories[index+1:]...)
exists = true
break
}

if !exists {
return nil
}
if err := c.Client.Status().Update(context.Background(), cronFHPA); err != nil {
c.EventRecorder.Event(cronFHPA, corev1.EventTypeWarning, "UpdateCronFederatedHPAFailed", err.Error())
klog.Errorf("Fail to remove CronFederatedHPA(%s/%s) rule(%s) history:%v", cronFHPA.Namespace, cronFHPA.Name, ruleName, err)
return err
}

return nil
}
Loading

0 comments on commit 3909fcc

Please sign in to comment.