Skip to content
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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

zimnx
Copy link
Collaborator

@zimnx zimnx commented Jun 16, 2023

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

@zimnx zimnx added the kind/feature Categorizes issue or PR as related to a new feature. label Jun 16, 2023
@zimnx zimnx added this to the v1.10 milestone Jun 16, 2023
@zimnx zimnx force-pushed the mz/1188-shortest-scale-path branch from 593ed6b to cf5178c Compare June 16, 2023 15:02
@zimnx zimnx force-pushed the mz/1188-shortest-scale-path branch from cf5178c to 431e7cd Compare June 27, 2023 09:38
Copy link
Member

@rzetelskik rzetelskik left a 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)),
Copy link
Member

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)
Copy link
Member

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.
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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 {
Copy link
Member

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() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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")
Copy link
Member

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)
Copy link
Member

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

Copy link
Member

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

@tnozicka tnozicka removed this from the v1.10 milestone Aug 17, 2023
@scylla-operator-bot scylla-operator-bot bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 7, 2023
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.
@scylla-operator-bot scylla-operator-bot bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 12, 2023
@scylla-operator-bot
Copy link
Contributor

[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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@scylla-operator-bot scylla-operator-bot bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Sep 12, 2023
@scylla-operator-bot
Copy link
Contributor

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.

@scylla-operator-bot scylla-operator-bot bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 19, 2023
Copy link
Contributor

@zimnx: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-gke 431e7cd link true /test e2e-gke
ci/prow/verify-vendorability 5b0b343 link true /test verify-vendorability
ci/prow/helm-build 5b0b343 link true /test helm-build
ci/prow/verify 5b0b343 link true /test verify
ci/prow/unit 5b0b343 link true /test unit
ci/prow/verify-deps 5b0b343 link true /test verify-deps
ci/prow/e2e-gke-serial 5b0b343 link true /test e2e-gke-serial
ci/prow/e2e-gke-parallel 5b0b343 link true /test e2e-gke-parallel
ci/prow/build 5b0b343 link true /test build
ci/prow/docs 5b0b343 link true /test docs
ci/prow/e2e-gke-parallel-clusterip 5b0b343 link true /test e2e-gke-parallel-clusterip
ci/prow/images 5b0b343 link true /test images
ci/prow/e2e-gke-release-script-latest 5b0b343 link true /test e2e-gke-release-script-latest

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. kind/feature Categorizes issue or PR as related to a new feature. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Adjusting the scale doesn't take the shortest path
3 participants