-
Notifications
You must be signed in to change notification settings - Fork 158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support scaling changes during ongoing scaling #1283
base: master
Are you sure you want to change the base?
Conversation
593ed6b
to
cf5178c
Compare
cf5178c
to
431e7cd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall well done, I like how much more readable the scaling code is now. I left some comments though, especially regarding the edge case of scaling down and up immediatelly.
ctx, | ||
service.Name, | ||
types.MergePatchType, | ||
[]byte(fmt.Sprintf(`{"metadata": {"annotations": {%q: %q} } }`, naming.NodeInitialized, naming.LabelValueTrue)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the semantics behind this annotation. The comment for naming.NodeInitialized
says "NodeInitialized means given node was started.", while the Scylla process is run at a later time. Should this be moved to after the process is started?
// Do not delete services that weren't properly decommissioned. | ||
if svc.Labels[naming.DecommissionedLabel] != naming.LabelValueTrue { | ||
// Do not delete services that were bootstrapped but weren't properly decommissioned. | ||
if svc.Annotations[naming.NodeInitialized] != "" && svc.Labels[naming.DecommissionedLabel] != naming.LabelValueTrue { | ||
klog.Warningf("Refusing to cleanup service %s/%s whose member wasn't decommissioned.", svc.Namespace, svc.Name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Can you also switch from using "%s/%s" to KObj or similar while we're at it?
if sts.Status.Replicas < *sts.Spec.Replicas { | ||
scale.Spec.Replicas = sts.Status.Replicas | ||
} else { | ||
// Scale bootstrapped nodes one by one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Scale is a variable in this context so I found it confusing. s/Scale/Downscale
return progressingConditions, err | ||
// Scale down is required | ||
if *req.Spec.Replicas < *sts.Spec.Replicas { | ||
// Stop ongoing scaling up |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s/scaling up/scale-up
_, err := scc.kubeClient.CoreV1().Services(lastSvcCopy.Namespace).Update(ctx, lastSvcCopy, metav1.UpdateOptions{}) | ||
if err != nil { | ||
return progressingConditions, err | ||
// Scale down is required |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s/Scale down/Scale-down
Message: fmt.Sprintf("Waiting for rack service %q to decommission.", naming.ObjRef(svc)), | ||
ObservedGeneration: sc.Generation, | ||
}) | ||
if *req.Spec.Replicas == *sts.Spec.Replicas { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't a regression, but since you're changing the logic a bit, I think we should handle the case I described here: #1293 (comment), i.e. a scale-down followed immediately by a scale-up should result in the node being decommissioned and deleted, which with current implementation won't trigger a downscale.
) | ||
|
||
var _ = g.Describe("ScyllaCluster", func() { | ||
defer g.GinkgoRecover() | ||
|
||
f := framework.NewFramework("scyllacluster") | ||
|
||
g.It("should react on scaling up in the middle of scaling down", func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
g.It("should react on scaling up in the middle of scaling down", func() { | |
g.It("should react to scaling up in the middle of scaling down", func() { |
o.Expect(secondNodeWasLeaving.Load()).To(o.BeFalse()) | ||
}) | ||
|
||
g.It("should react on scaling down in the middle of scaling up", func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
g.It("should react on scaling down in the middle of scaling up", func() { | |
g.It("should react to scaling down in the middle of scaling up", func() { |
}, time.Second, observerCtx.Done()) | ||
}() | ||
|
||
framework.By("Scaling up the ScyllaCluster to 4 replicas") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason scaling to 4 replicas makes it not hit the edge case described here #1293 (comment). Try changing it to 3 and maybe lower the polling interval a bit and you'll see the test failing.
} | ||
|
||
if s.Spec.Type != corev1.ServiceTypeClusterIP { | ||
return "", fmt.Errorf("service %s/%s is of type %q instead of %q", s.Namespace, s.Name, s.Spec.Type, corev1.ServiceTypeClusterIP) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit : use KObj or similar instead of %s/%s
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kobj is to be used with klog, there is an equivalent function in naming package for everything else
Decommissioning label reconcilation was moved from StatefulSet controller into Service controller. StatefulSet controller can now react dynamically to scaling events occuring while scaling operations are still ongoing.
431e7cd
to
5b0b343
Compare
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: zimnx The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
PR needs rebase. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
@zimnx: The following tests failed, say
Full PR test history. Your PR dashboard. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
Decommissioning label reconcilation was moved from StatefulSet controller into Service controller.
StatefulSet controller can now react dynamically to scaling events occuring while scaling operations are still ongoing.
Fixes #1188