Skip to content

Commit 8d36a33

Browse files
committed
fix: adds linear rollout strategy
Signed-off-by: Juliana Oliveira <[email protected]>
1 parent 72e2359 commit 8d36a33

File tree

1 file changed

+40
-4
lines changed

1 file changed

+40
-4
lines changed

internal/controller/postgrescluster/pgbackrest.go

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"context"
99
"fmt"
1010
"io"
11+
"math/rand"
12+
"os"
1113
"reflect"
1214
"regexp"
1315
"sort"
@@ -24,6 +26,7 @@ import (
2426
"k8s.io/apimachinery/pkg/api/meta"
2527
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2628
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
29+
"k8s.io/apimachinery/pkg/labels"
2730
"k8s.io/apimachinery/pkg/runtime"
2831
"k8s.io/apimachinery/pkg/runtime/schema"
2932
"k8s.io/apimachinery/pkg/types"
@@ -604,11 +607,14 @@ func (r *Reconciler) generateRepoHostIntent(ctx context.Context, postgresCluster
604607
Namespace: postgresCluster.GetNamespace(),
605608
}
606609

607-
if err := r.Client.Get(ctx, secretKey, existingSecret); err == nil {
608-
if podAnnotations == nil {
609-
podAnnotations = make(map[string]string)
610+
if podAnnotations == nil {
611+
podAnnotations = make(map[string]string)
612+
}
613+
614+
if shouldAnnotateRepoHost(podAnnotations) {
615+
if err := r.Client.Get(ctx, secretKey, existingSecret); err == nil {
616+
podAnnotations["postgres-operator.crunchydata.com/pgbackrest-secret-version"] = existingSecret.ResourceVersion
610617
}
611-
podAnnotations["postgres-operator.crunchydata.com/pgbackrest-secret-version"] = existingSecret.ResourceVersion
612618
}
613619

614620
repo := &appsv1.StatefulSet{
@@ -764,6 +770,36 @@ func (r *Reconciler) generateRepoHostIntent(ctx context.Context, postgresCluster
764770
return repo, nil
765771
}
766772

773+
// In order to avoid multiple repo-hosts restarting per cycle, we adopt a gradual rollout strategy.
774+
// Distribution is (pseudo-)random, but we should see ~20 restarts/per cycle.
775+
// When all repo-hosts are annotated, this function can be removed.
776+
func shouldAnnotateRepoHost(annotations labels.Set) bool {
777+
if _, exists := annotations["postgres-operator.crunchydata.com/pgbackrest-secret-version"]; exists {
778+
// 1. If the annotation already exist, we keep it.
779+
return true
780+
}
781+
782+
// 2. Otherwise, given the start time of the rollout, we calculate a linear increasing threshold and
783+
// roll a d100. If the value of the dice is lower than the threshold, we add the annotation in this
784+
// reconciliation cycle. Note that this means a machine restart.
785+
// By the end of a week, the threshold should reach 100 and any dice value will allow for the
786+
// annotation to be added, effectively annotating all remaining pods.
787+
if rolloutStartStr := os.Getenv("PGBACKREST_SECRET_ROLLOUT_START_TIME"); rolloutStartStr != "" {
788+
if rolloutStart, err := time.Parse(time.RFC3339, rolloutStartStr); err == nil {
789+
oneWeekInMinutes := 7 * 24 * 60
790+
minutesElapsed := int(time.Since(rolloutStart).Minutes())
791+
792+
// Increases every minute. Reconciliation cycles happen every 10 minutes.
793+
threshold := min((minutesElapsed*100)/oneWeekInMinutes, 100)
794+
d100 := rand.Intn(100)
795+
796+
return d100 <= threshold
797+
}
798+
}
799+
800+
return false
801+
}
802+
767803
func (r *Reconciler) generateRepoVolumeIntent(postgresCluster *v1beta1.PostgresCluster,
768804
spec corev1.PersistentVolumeClaimSpec, repoName string,
769805
repoResources *RepoResources) (*corev1.PersistentVolumeClaim, error) {

0 commit comments

Comments
 (0)