Skip to content

(WIP)CKS: reconcile node capacity after live resize - #14223

Draft
andrijapanicsb wants to merge 10 commits into
mainfrom
cks-live-resize-capacity-reconciliation
Draft

andrijapanicsb wants to merge 10 commits into
mainfrom
cks-live-resize-capacity-reconciliation

Conversation

@andrijapanicsb

@andrijapanicsb andrijapanicsb commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Why this follow-up is needed

#13226 allowed CKS node compute offerings to change while a KVM cluster was running, building on the fixed-offering live resize support in #12975. The VM could gain CPU or RAM while Kubernetes continued advertising the old capacity. Operators still had to activate the guest resources where needed, restart kubelet, and check the Node's capacity and allocatable values themselves.

#14213 tracks that gap. This PR puts those steps into the CKS scale workflow so that success means the guest and Kubernetes have caught up with the new offering.

Package-based QA also exposed a pre-existing bug in cluster CPU/RAM totals, not a regression introduced by this PR. The faulty calculation and resize-before-accounting order were already present in the base main commit (af9764b87a). After a control node and worker each grew from 2 vCPU / 2048 MiB to 3 vCPU / 3072 MiB, their offerings and actual resources were correct, but the cluster API and UI still showed 4 CPU / 4096 MiB. The old calculation read the VM offering after resize and treated it as the previous offering, producing a zero difference. The total is now recalculated from each node type's configured offering and node count. This also avoids carrying an already stale total into the next scale operation and preserves separate control, worker, and etcd offerings when the worker count changes.

The wider QA run found two more existing per-node-offering edge cases: a global offering change tried to look up dedicated etcd nodes even when there were none, and adding workers required the legacy global offering even when a worker offering was configured. Both paths now use the applicable node types and offerings.

QA also caught a gap in retry selection: looking at the first VM's current offering could skip the group after that VM had already resized. The decision now uses the cluster's committed node-type offering, so a retry can reconcile the partially resized node and continue with the untouched nodes.

What changes

For a CPU-count or RAM increase on a running, Cloud-managed KVM worker or control-plane node, CKS handles one node at a time:

  1. Record its schedulability and Kubernetes resource values, then cordon it if needed.
  2. Resize the VM through the existing CloudStack workflow and activate hot-plugged guest CPU and memory.
  3. Check the guest's online CPU count and MemTotal.
  4. Restart kubelet when Kubernetes still has the old resources, then wait for the Node to be Ready with matching capacity and increased allocatable resources.
  5. Restore schedulability only when CKS owns the cordon.

The node SSH connection uses its actual port-forwarding rule on isolated/VPC networks, or its private address on direct-access networks. A failed post-resize verification leaves the CKS cordon in place and reports the failing phase. A previously operator-cordoned node remains cordoned. The workflow does not drain or evict resident Pods.

Guest/kubelet reconciliation applies to running managed KVM workers and control-plane nodes. Stopped clusters retain the existing VM lifecycle workflow. Dedicated etcd live resize remains rejected pending explicit etcd health/quorum handling.

Validation

  • All 146 CKS module tests pass, including 22 focused scale-worker/reconciler tests. Checkstyle passed in the Linux Maven reactor and RPM build.
  • The published 2a404aa1ff RPMs were installed and tested first. Final QA uses locally built EL9 RPMs from 978b29173ed70c695b50bce9ea7ecdf7436ae070 on both management servers and both KVM hosts. Embedded revisions and the installed scale-worker class were checked against the build output.
  • Two-worker CPU-only, RAM-only and combined increases through the UI, including a previously operator-cordoned worker. VM boot IDs, resident Pod UIDs and restart counts were preserved. Kubernetes capacity/allocatable values matched the resized guests, and DNS/HTTP service checks passed.
  • An injected kubelet start failure left the resized first worker CKS-cordoned, kept the second worker untouched and reported a failed job. Retrying through the UI converged both workers to 3 CPU / 4096 MiB, cleared CKS ownership and produced the correct 8 CPU / 10240 MiB aggregate. The temporary fault and recovery timer were removed.
  • Cap-only and repeated same-offering requests caused no kubelet restart. Stopped global offering change/start, worker scale-out/in with mixed offerings, and control-plane live migration also passed.
  • Separate control-plane CPU and RAM increases through the UI preserved system and test Pods. The final mixed-offering cluster shows 6 CPU / 7168 MiB in the API and UI, including after Refresh; both Nodes are Ready and schedulable. All seven UI scale tasks show successful completion.
  • QA7 RAM allocation peaked at 12 of approximately 14 GiB and finished at 9 GiB, including system VMs. A 4-vCPU request was correctly rejected because each QA7 routing host has only 3 CPU cores.

This QA7 run covers Cloud-managed KVM on an isolated network; it does not qualify VPC/direct-access networking or multi-control HA. Dedicated etcd live resize remains unsupported. The PR stays a draft for review and remaining coverage. The latest coverage workflow hit a Maven Central HTTP 502 before producing a Java report; its failed job has been requeued rather than treating the older coverage result as current.

@codecov

codecov Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 41.20000% with 147 lines in your changes missing coverage. Please review.
✅ Project coverage is 20.46%. Comparing base (af9764b) to head (978b291).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...er/actionworkers/KubernetesClusterScaleWorker.java 26.54% 76 Missing and 7 partials ⚠️
...s/KubernetesClusterNodeCapacityReconcilerImpl.java 50.42% 35 Missing and 24 partials ⚠️
...utils/KubernetesClusterNodeCapacityReconciler.java 72.22% 4 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #14223      +/-   ##
============================================
+ Coverage     20.45%   20.46%   +0.01%     
- Complexity    21415    21480      +65     
============================================
  Files          6487     6489       +2     
  Lines        589303   589540     +237     
  Branches      72245    72307      +62     
============================================
+ Hits         120525   120655     +130     
- Misses       455643   455706      +63     
- Partials      13135    13179      +44     
Flag Coverage Δ
uitests 3.70% <ø> (ø)
unittests 21.76% <41.20%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@andrijapanicsb andrijapanicsb changed the title CKS: reconcile node capacity after live resize (WIP)CKS: reconcile node capacity after live resize Sep 22, 2026
@andrijapanicsb

Copy link
Copy Markdown
Contributor Author

@ACSHomeBot package G

@ACSHomeBot

ACSHomeBot commented Sep 22, 2026 •

Copy link
Copy Markdown

Packaging results:

Result Artifact Platform
PASS RPM EL (EL8/9/10)
PASS DEB Ubuntu, Debian

Test packages are available at:

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

🔴 Test Coverage Grade: D — Marginal

Metric Value
Line coverage 25.51%
Branch coverage 19.86%

Grade Scale

Grade Line Coverage Meaning
🟢 A ≥ 80% Excellent - this code sleeps well at night 😴
🟡 B 60-79% Good - almost there, don't stop now 😉
🟠 C 40-59% Acceptable - your code is wearing a seatbelt, but no airbags 😬
🔴 D 20-39% Marginal - boldly shipping where no test has gone before 🖖
⛔ F < 20% Failing - tests? what tests? 🔥

Branch coverage is shown as a secondary signal. Grade is determined by line coverage.
View full Actions run

@andrijapanicsb
andrijapanicsb force-pushed the cks-live-resize-capacity-reconciliation branch from 40b50b0 to 7e5a95a Compare October 20, 2026 05:18
@andrijapanicsb

Copy link
Copy Markdown
Contributor Author

@ACSHomeBot package G

@ACSHomeBot

Copy link
Copy Markdown

Accepted: package kvm G for 548011910846.

Planned: RPM + DEB, KVM SystemVM.

Status: Queued for worker G. Jobs ahead: 0.

@ACSHomeBot

Copy link
Copy Markdown

Packaging results:

Result Artifact Platform Build Time
NOT RUN RPM EL (EL8/9/10) n/a
NOT RUN DEB Ubuntu, Debian n/a

Package building did not start. No repository was published.

Status: Infrastructure failure before package building started.

@andrijapanicsb

Copy link
Copy Markdown
Contributor Author

@ACSHomeBot package G

@ACSHomeBot

Copy link
Copy Markdown

Accepted: package kvm G for 2a404aa1ffcc.

Planned: RPM + DEB, KVM SystemVM.

Status: Queued for worker G. Jobs ahead: 0.

@ACSHomeBot

Copy link
Copy Markdown

Package building started on worker G.

@ACSHomeBot

Copy link
Copy Markdown

Packaging results:

Result Artifact Platform Build Time
PASS RPM EL (EL8/9/10) 31 min
PASS DEB Ubuntu, Debian 22 min

Test packages are available at:

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
35.8% Coverage on New Code (required ≥ 40%)

See analysis details on SonarQube Cloud

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants