Skip to content

Commit

Permalink
controller: jitter requeue interval
Browse files Browse the repository at this point in the history
Add a `--interval-jitter-percentage` flag to the controller to
add a +/- percentage jitter to the `Kustomization.spec.interval`.

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
  • Loading branch information
stefanprodan committed Aug 7, 2023
1 parent 0657083 commit 04c5a8f
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 4 deletions.
2 changes: 2 additions & 0 deletions api/v1/kustomization_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ type KustomizationSpec struct {
Decryption *Decryption `json:"decryption,omitempty"`

// The interval at which to reconcile the Kustomization.
// This interval is approximate and may be subject to jitter to ensure
// efficient use of resources.
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// +required
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ spec:
type: array
interval:
description: The interval at which to reconcile the Kustomization.
This interval is approximate and may be subject to jitter to ensure
efficient use of resources.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
kubeConfig:
Expand Down
8 changes: 6 additions & 2 deletions docs/api/v1/kustomize.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ Kubernetes meta/v1.Duration
</em>
</td>
<td>
<p>The interval at which to reconcile the Kustomization.</p>
<p>The interval at which to reconcile the Kustomization.
This interval is approximate and may be subject to jitter to ensure
efficient use of resources.</p>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -607,7 +609,9 @@ Kubernetes meta/v1.Duration
</em>
</td>
<td>
<p>The interval at which to reconcile the Kustomization.</p>
<p>The interval at which to reconcile the Kustomization.
This interval is approximate and may be subject to jitter to ensure
efficient use of resources.</p>
</td>
</tr>
<tr>
Expand Down
5 changes: 5 additions & 0 deletions docs/spec/v1/kustomizations.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ If the `.metadata.generation` of a resource changes (due to e.g. a change to
the spec) or the Source revision changes (which generates a Kubernetes event),
this is handled instantly outside the interval window.

**Note:** The controller can be configured to apply a jitter to the interval in
order to distribute the load more evenly when multiple Kustomization objects are
set up with the same interval. For more information, please refer to the
[kustomize-controller configuration options](https://fluxcd.io/flux/components/kustomize/options/).

### Retry interval

`.spec.retryInterval` is an optional field to specify the interval at which to
Expand Down
6 changes: 4 additions & 2 deletions internal/controller/kustomization_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ package controller
import (
"bytes"
"context"
"errors"
"fmt"
"os"
"sort"
"strings"
"time"

securejoin "github.com/cyphar/filepath-securejoin"
"github.com/fluxcd/pkg/runtime/jitter"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
apimeta "k8s.io/apimachinery/pkg/api/meta"
Expand Down Expand Up @@ -263,7 +265,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
reconcileErr := r.reconcile(ctx, obj, artifactSource, patcher)

// Requeue at the specified retry interval if the artifact tarball is not found.
if reconcileErr == fetch.FileNotFoundError {
if errors.Is(reconcileErr, fetch.FileNotFoundError) {
msg := fmt.Sprintf("Source is not ready, artifact not found, retrying in %s", r.requeueDependency.String())
conditions.MarkFalse(obj, meta.ReadyCondition, kustomizev1.ArtifactFailedReason, msg)
log.Info(msg)
Expand All @@ -283,7 +285,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
}

// Requeue the reconciliation at the specified interval.
return ctrl.Result{RequeueAfter: obj.Spec.Interval.Duration}, nil
return ctrl.Result{RequeueAfter: jitter.JitteredIntervalDuration(obj.GetRequeueAfter())}, nil
}

func (r *KustomizationReconciler) reconcile(
Expand Down
8 changes: 8 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
runtimeCtrl "github.com/fluxcd/pkg/runtime/controller"
"github.com/fluxcd/pkg/runtime/events"
feathelper "github.com/fluxcd/pkg/runtime/features"
"github.com/fluxcd/pkg/runtime/jitter"
"github.com/fluxcd/pkg/runtime/leaderelection"
"github.com/fluxcd/pkg/runtime/logger"
"github.com/fluxcd/pkg/runtime/pprof"
Expand Down Expand Up @@ -84,6 +85,7 @@ func main() {
leaderElectionOptions leaderelection.Options
rateLimiterOptions runtimeCtrl.RateLimiterOptions
watchOptions runtimeCtrl.WatchOptions
intervalJitterOptions jitter.IntervalOptions
aclOptions acl.Options
noRemoteBases bool
httpRetry int
Expand All @@ -109,6 +111,7 @@ func main() {
rateLimiterOptions.BindFlags(flag.CommandLine)
featureGates.BindFlags(flag.CommandLine)
watchOptions.BindFlags(flag.CommandLine)
intervalJitterOptions.BindFlags(flag.CommandLine)

flag.Parse()

Expand All @@ -121,6 +124,11 @@ func main() {
os.Exit(1)
}

if err := intervalJitterOptions.SetGlobalJitter(nil); err != nil {
setupLog.Error(err, "unable to set global jitter")
os.Exit(1)
}

watchNamespace := ""
if !watchOptions.AllNamespaces {
watchNamespace = os.Getenv("RUNTIME_NAMESPACE")
Expand Down

0 comments on commit 04c5a8f

Please sign in to comment.