Skip to content

Stage CHK scale-up so 1→3 does not create all Raft members at once - #2087

Merged
alex-zaitsev merged 9 commits into
0.28.0from
fix/chk-staged-scale-up
Oct 22, 2026
Merged

alex-zaitsev merged 9 commits into
0.28.0from
fix/chk-staged-scale-up

Conversation

@alex-zaitsev

@alex-zaitsev alex-zaitsev commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Summary

  • During CHK 1→3 / 2→3, extra new members stay out of raft_configuration until the previous join is Ready, so the operator never creates every new StatefulSet in one pass.
  • Fresh bootstrap is unchanged. 3→N added hosts still skip Ready so existing members can roll first.
  • test_020005_2 fail-fast: sts_count <= ready_count + 1 on the existing test-052 manifests.

Not in this PR (still #2041): /keeper/config + mntr barriers, scale-down purge, start_as_follower, rqld, lease election.

Test plan

  • go test -mod=mod ./pkg/controller/chk/ ./pkg/apis/common/types/
  • e2e test_020005_2 (fail-fast 1→3 invariant)
  • e2e test_020005 (happy-path 1→3→1 + CHI replication)

@alex-zaitsev
alex-zaitsev force-pushed the fix/chk-staged-scale-up branch from ffb6ba9 to 9bfc2c0 Compare September 30, 2026 17:21
@alex-zaitsev
alex-zaitsev marked this pull request as ready for review October 1, 2026 07:03
@alex-zaitsev alex-zaitsev added the planned for review This feature is planned for review label Oct 12, 2026
alex-zaitsev and others added 5 commits October 21, 2026 12:14
Publish one new keeper at a time and wait Ready before the next STS, instead of writing the full raft_configuration and creating every replica after a fixed sleep.

Co-authored-by: Cursor <cursoragent@cursor.com>
Do not create a new Keeper STS if raft_configuration was not published, and do not expand membership when STS existence is unknown. Restrict staging to 1→N / 2→3 and require the e2e join to become Ready.

Co-authored-by: Cursor <cursoragent@cursor.com>
Identify 1→N / 2→3 joiners by topology so an interrupted Ready wait still serializes the next STS after status becomes Same. Do not publish raft_configuration until immediately before STS create, and do not honor readiness:false for that gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
@alex-zaitsev
alex-zaitsev force-pushed the fix/chk-staged-scale-up branch from ab45d0e to d249758 Compare October 21, 2026 09:41

@Slach Slach left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

A few inline notes. The main one is the retry path at worker-reconciler-chk.go:948: after an interrupted pass, the next joiner can still be created while the previous one isn't Ready.

Comment thread pkg/controller/chk/worker-reconciler-chk.go
Comment thread pkg/controller/chk/worker-raft-safety_test.go Outdated
Comment thread pkg/controller/chk/worker-raft-safety.go Outdated
Comment thread pkg/controller/chk/worker-reconciler-chk.go Outdated
Comment thread pkg/controller/chk/worker-wait-exclude-include-restart.go
Comment thread pkg/apis/common/types/reconcile_attributes.go Outdated
Comment thread pkg/controller/chk/worker-raft-safety.go
@Slach
Slach self-requested a review October 21, 2026 19:40

@Slach Slach left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks, the state-based gate fixes the retry fan-out. A few new issues in 9731a37 below.

getErr = peerErr
return nil
}
if sts != nil && sts.Status.ReadyReplicas < 1 {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

P1 — the deferral is unbounded, and every pass of it is expensive.

If h1 never becomes Ready (Keeper doesn't pick up the new raft_configuration live, bad image, PVC Pending), h2 is deferred on every pass, forever:

  • each pass costs membershipSettleDelay (30s) + ConfigMap writes, then a fixed 5s requeue that bypasses the rate limiter. With the default single CHK worker, other CHKs starve;
  • reconcileCR pushes [RaftQuorumUnsafe] deferred host disruption... on every pass (worker-reconciler-chk.go:133) with no dedupe. After ~10 passes, status.errors holds only that line, and it names the wrong reason.

Bound it (like quorumDisruptWaitTimeout), give it its own status reason with a deduped push, and show in e2e that h1 becomes Ready while h0 is never restarted.

Comment thread pkg/controller/chk/worker-reconciler-chk.go
Comment thread pkg/controller/chk/worker-raft-safety.go
Comment thread pkg/controller/chk/worker-raft-safety_test.go
@alex-zaitsev

Copy link
Copy Markdown
Member Author

#2087 (comment) will be addressed in a separate PR

@alex-zaitsev
alex-zaitsev merged commit baef171 into 0.28.0 Oct 22, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

planned for review This feature is planned for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants