fix(cozy-lib): round CPU request to whole milliCPU - #2920
Conversation
The cozy-lib.resources.sanitize helper divided the CPU limit by cpuAllocationRatio without rounding to an integer milliCPU, producing values like 0.0357142... when cpuAllocationRatio did not evenly divide the input. kube-apiserver tolerates sub-milliCPU on pod requests, but the VPA admission webhook rejects MinAllowed and MaxAllowed when they are not whole milliCPU, so any chart that feeds the sanitized output into VPA bounds failed to install. The etcd chart was the only place feeding sanitize output into VPA bounds in the tree, and its HelmRelease failed for any cpuAllocationRatio that is not a divisor of 250 (e.g. 7, 3, 6, 8, 9). Round the milliCPU value to the nearest whole milliCPU before formatting. Pod resources.requests.cpu is now emitted in milliCPU form (e.g. 200m instead of 0.2) which is semantically identical. Closes #2917 Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThe resource sanitizer now rounds allocation-adjusted CPU requests to whole milliCPU quantities. New Helm tests cover rounding across ratios and input formats, while the quota expectation uses milliCPU notation. ChangesCPU request formatting
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Checkov (3.3.8)packages/tests/cozy-lib-tests/templates/tests/resources.yamlTraceback (most recent call last): packages/tests/cozy-lib-tests/tests/quota_test.yamlTraceback (most recent call last): packages/tests/cozy-lib-tests/tests/resources_test.yamlTraceback (most recent call last): Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
LGTM — approving.
Business context: cozy-lib.resources.sanitize is a shared Helm template that derives requests from limits using the cluster CPU-allocation ratio, and is consumed by every managed app. When the ratio did not evenly divide the input, the CPU request came out as a sub-milliCPU float; the etcd chart — the only place that feeds sanitize output into VPA minAllowed/maxAllowed — then failed admission because VPA requires whole milliCPU. This change rounds the CPU request to whole milliCPU and emits the m form.
I verified the fix: with ratio 7, 250m→36m and 5000m→714m (whole milliCPU, accepted by VPA), and helm unittest passes 5/5. No consumer performs arithmetic on the sanitized CPU request that would break on the new m suffix — the kubernetes chart's reservation math reads the raw limit and its helper already strips m, and cozy-lib.resources.toFloat handles m elsewhere.
No blockers.
Non-blocking:
-
CPU request can exceed the limit for sub-milliCPU inputs at a low ratio. Round-half-up is applied only to the request while the limit is emitted unchanged, so the request can be pushed above the limit, which kube-apiserver rejects. Evidence:
packages/library/cozy-lib/templates/_resources.tpl:107-108; renderingresources.cpu=0.0006withcpu-allocation-ratio=1yieldsrequests.cpu: 1magainstlimits.cpu: "0.0006", andresources.cpu=1.5myieldsrequests.cpu: 2magainstlimits.cpu: 1.5m— bothrequest > limit. No in-tree chart uses fractional-milliCPU CPU values, butvalues.schema.jsonpermits them and this is a shared library, so consider clamping the request to the integer-milliCPU limit (or rounding the limit the same way) sorequest <= limitalways holds, with a regression case to match. -
Sub-0.5m requests collapse to
0m. The same rounding applied to tiny values drops the CPU request floor entirely. Evidence: renderingresources.cpu=0.4mwithcpu-allocation-ratio=1yieldsrequests.cpu: 0m. This is valid for kube-apiserver but removes the guaranteed CPU share, and is only reachable with sub-milliCPU input. -
One-time
requests.cpudiff across every app usingsanitize. The format change from e.g.0.2to200mrewritesrequests.cpuon every existing HelmRelease, so pods may roll on the next reconcile even though the value is semantically identical. This is already called out in the PR description; noting it for upgrade awareness. Evidence:packages/library/cozy-lib/templates/_resources.tpl:108, whereprintf "%dm"replaces the prior floattoString.
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Closing this in favour of #3522, and the reason is arithmetic rather than preference, so it is worth stating. Both PRs fix a real bug and both ship tests that genuinely fail against main. The tiebreak is which way to round, and the answer is that kube-apiserver already rounds this value up. I checked it server-side: a pod requesting Your approach does have one advantage over the one being taken, and it should not go unsaid: it cannot emit a value VPA rejects, by construction. #3522 as written still can, in 53 cases out of a 905k-combination sweep, and it needs a one-line change to close that. It is being asked for there. The diagnosis in #2917 was right and this sat too long. Thank you for it. |
What this PR does
cozy-lib.resources.sanitizedivided the CPU limit bycpuAllocationRatiowithout rounding to an integer milliCPU, producing values like0.035714286(kube-apiserver representation:35714286n) whencpuAllocationRatiodid not evenly divide the input.kube-apiservertolerates sub-milliCPU on podrequests, but the VPA admission webhook rejectsMinAllowed/MaxAllowedthat are not whole milliCPU. As a result, charts that feed the sanitized output into VPA bounds (the etcd chart is currently the only one in-tree) failed to install for anycpuAllocationRatiothat is not a divisor of 250 (e.g. 3, 6, 7, 8, 9):This PR rounds the milliCPU value to the nearest whole milliCPU in
_resources.tplbefore formatting, and emits the value with themsuffix (200minstead of0.2) which is semantically identical forkube-apiserver.Verification
helm template etcd packages/extra/etcd --set _cluster.cpu-allocation-ratio=7 --show-only templates/vpa.yaml:minAllowed.cpu: 36m(was rejected as35714286n)maxAllowed.cpu: 714m(was rejected as714285714n)helm template etcd packages/extra/etcd --set _cluster.cpu-allocation-ratio=3 --show-only templates/vpa.yaml:minAllowed.cpu: 83m,maxAllowed.cpu: 1667mhelm unittestpasses in all packages that exercisesanitize(cozy-lib-tests, backupstrategy-controller, cilium-networkpolicy, ouroboros, harbor, linstor-scheduler, platform).packages/tests/cozy-lib-tests/tests/resources_test.yamlcovers default ratio (10), non-divisor ratio (7), upper-bound rounding, and whole-core inputs.The format change from
0.025to25mflows through to every Pod template that usessanitize. Both forms are accepted bykube-apiserver; existing HelmReleases will see a one-time diff on therequests.cpufield.Release note
Closes #2917
Summary by CodeRabbit
Bug Fixes
Tests