What is your environment(Kubernetes version, Fluid version, etc.)
Describe the bug
AdvancedStatefulSetManager.updateResources replaces the container's entire ResourceRequirements struct rather than merging it key by key:
// pkg/ddc/cache/component/advanced_statefulset_manager.go:299
container.Resources = *resources.DeepCopy()
ResourceRequirements holds Limits, Requests and Claims. Anything the user does not restate in CacheRuntime.spec.<component>.resources is dropped from the workload on the next reconcile, including values that were rendered from the CacheRuntimeClass template at creation time. There is no error and no event.
The practical case is a user who only wants to raise one number. Setting just limits.memory also clears requests.cpu, limits.cpu, requests.memory and claims, which changes both how the pod is scheduled and what caps its usage on the node.
What you expect to happen:
Only the keys the user actually set should change. Values that came from the CacheRuntimeClass template and were not mentioned in the CacheRuntime should survive the sync.
How to reproduce it
- CacheRuntimeClass whose worker template declares a full set of resources:
topology:
worker:
template:
spec:
containers:
- name: worker
resources:
requests: {cpu: "1", memory: 2Gi}
limits: {cpu: "2", memory: 4Gi}
- Create a CacheRuntime that does not set
spec.worker.resources. The AdvancedStatefulSet correctly
inherits the template values and stays there (verified stable over 70s of reconciles, generation 1):
gen = 1 {"limits":{"cpu":"2","memory":"4Gi"},"requests":{"cpu":"1","memory":"2Gi"}}
- Now raise a single value — the memory limit only:
kubectl patch cacheruntime restest --type=merge \
-p '{"spec":{"worker":{"resources":{"limits":{"memory":"8Gi"}}}}}'
- Everything else is gone, and the pods roll (generation 1 -> 2):
gen = 2 {"limits":{"memory":"8Gi"}}
limits.cpu: 2, requests.cpu: 1 and requests.memory: 2Gi were all dropped. On the resulting pod:
qosClass = Burstable
worker {"limits":{"memory":"8Gi"},"requests":{"memory":"8Gi"}}
The container now has no CPU request and no CPU limit at all, so the scheduler stops reserving CPU for it
and nothing caps its CPU usage on the node. The requests.memory: 8Gi is Kubernetes defaulting requests to
limits, which also silently raises the memory reservation from the intended 2Gi to 8Gi.
Additional Information
What is your environment(Kubernetes version, Fluid version, etc.)
2a4968a9, i.e. the fix for [BUG]containerresourcesin CacheRuntimeClass are silently dropped #6161 (PR fix(cache): preserve CacheRuntimeClass template resources when unset #6165) is already applied — this matters, see Additional InformationDescribe the bug
AdvancedStatefulSetManager.updateResourcesreplaces the container's entireResourceRequirementsstruct rather than merging it key by key:ResourceRequirementsholdsLimits,RequestsandClaims. Anything the user does not restate inCacheRuntime.spec.<component>.resourcesis dropped from the workload on the next reconcile, including values that were rendered from the CacheRuntimeClass template at creation time. There is no error and no event.The practical case is a user who only wants to raise one number. Setting just
limits.memoryalso clearsrequests.cpu,limits.cpu,requests.memoryandclaims, which changes both how the pod is scheduled and what caps its usage on the node.What you expect to happen:
Only the keys the user actually set should change. Values that came from the CacheRuntimeClass template and were not mentioned in the CacheRuntime should survive the sync.
How to reproduce it
spec.worker.resources. The AdvancedStatefulSet correctlyinherits the template values and stays there (verified stable over 70s of reconciles, generation 1):
kubectl patch cacheruntime restest --type=merge \ -p '{"spec":{"worker":{"resources":{"limits":{"memory":"8Gi"}}}}}'limits.cpu: 2,requests.cpu: 1andrequests.memory: 2Giwere all dropped. On the resulting pod:The container now has no CPU request and no CPU limit at all, so the scheduler stops reserving CPU for it
and nothing caps its CPU usage on the node. The
requests.memory: 8Giis Kubernetes defaulting requests tolimits, which also silently raises the memory reservation from the intended 2Gi to 8Gi.
Additional Information
resourcesin CacheRuntimeClass are silently dropped #6161, although both land on the same lines. [BUG]containerresourcesin CacheRuntimeClass are silently dropped #6161 covers the case whereresourcesis not set at all, and its fix (fix(cache): preserve CacheRuntimeClass template resources when unset #6165) makesComponentSpec.Resourcesa pointer so that nil means "leave the workload alone". A partially filled value is still non-nil, so it is still applied wholesale and this case survives that fix. The reproduction above was run on a build that already contains fix(cache): preserve CacheRuntimeClass template resources when unset #6165, so this isnot the old bug resurfacing. The two also want different remedies: [BUG]container
resourcesin CacheRuntimeClass are silently dropped #6161 needed a nil check, this one needs adecision about merge semantics.
updateResourcesdirectly confirmsClaimsis dropped the same way, alongsideLimitsandRequests. The cluster reproduction above does not exerciseClaimsbecause the test workloaddoes not use DRA.
imageandreplicason the same code path are not affected.updateImage(advanced_statefulset_manager.go:271) returns early when eitherImageorImageTagis empty, andreplicasis protected by+kubebuilder:default=1in the CRD.