fix conflict race in statefulset rest update

statefulset controller does less requests per sync now and thus can
reconcile status faster, thus resulting in a higher chance for conflicts
This commit is contained in:
Filip Křepinský 2024-03-11 17:02:59 +01:00
parent 7d9b913d10
commit 2956e294c4

View File

@ -25,12 +25,12 @@ import (
appsv1 "k8s.io/api/apps/v1" appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/util/retry"
"k8s.io/kubectl/pkg/util/podutils" "k8s.io/kubectl/pkg/util/podutils"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
e2emanifest "k8s.io/kubernetes/test/e2e/framework/manifest" e2emanifest "k8s.io/kubernetes/test/e2e/framework/manifest"
@ -247,21 +247,23 @@ func ExecInStatefulPods(ctx context.Context, c clientset.Interface, ss *appsv1.S
} }
// update updates a statefulset, and it is only used within rest.go // update updates a statefulset, and it is only used within rest.go
func update(ctx context.Context, c clientset.Interface, ns, name string, replicas int32) *appsv1.StatefulSet { func update(ctx context.Context, c clientset.Interface, ns, name string, replicas int32) (ss *appsv1.StatefulSet) {
for i := 0; i < 3; i++ { err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
ss, err := c.AppsV1().StatefulSets(ns).Get(ctx, name, metav1.GetOptions{}) var err error
ss, err = c.AppsV1().StatefulSets(ns).Get(ctx, name, metav1.GetOptions{})
if err != nil { if err != nil {
framework.Failf("failed to get statefulset %q: %v", name, err) framework.Failf("failed to get statefulset %q: %v", name, err)
} }
if *(ss.Spec.Replicas) == replicas {
return nil
}
*(ss.Spec.Replicas) = replicas *(ss.Spec.Replicas) = replicas
ss, err = c.AppsV1().StatefulSets(ns).Update(ctx, ss, metav1.UpdateOptions{}) ss, err = c.AppsV1().StatefulSets(ns).Update(ctx, ss, metav1.UpdateOptions{})
if err == nil { return err
return ss })
} if err == nil {
if !apierrors.IsConflict(err) && !apierrors.IsServerTimeout(err) { return ss
framework.Failf("failed to update statefulset %q: %v", name, err)
}
} }
framework.Failf("too many retries draining statefulset %q", name) framework.Failf("failed to update statefulset %q: %v", name, err)
return nil return nil
} }