You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SSABasedGenericKubernetesResourceMatcher Incorrectly Detects Mismatch for initialDelaySeconds=0 in Deployment ReadinessProbe #2742
Define a Deployment CRUDKubernetesDependentResource in a Java Operator SDK controller with desired resource containing spec.template.spec.containers[0].readinessProbe.initialDelaySeconds=0.
Trigger reconciliation.
Observe that the controller repeatedly considers the resource as out-of-sync, even though there is no actual change needed.
The SSABasedGenericKubernetesResourceMatcher in Java Operator SDK incorrectly considers a Deployment resource as not matching the actual Kubernetes resource when spec.template.spec.containers[*].readinessProbe.initialDelaySeconds is set to 0.
Kubernetes omits fields with default values (0 for initialDelaySeconds) when storing resources, meaning the actual resource map retrieved from Kubernetes does not contain this field. However, the desired resource map includes initialDelaySeconds: 0, leading to an unnecessary update being triggered.
What did you expect to see?
If initialDelaySeconds: 0 is absent in the actual resource due to Kubernetes' defaulting behavior, the matcher should recognize this as equivalent to explicitly setting it to 0 in the desired resource.
What did you see instead? Under which circumstances?
The matcher detects a difference because the desired resource contains initialDelaySeconds: 0, while the actual resource lacks this field. This results in an unnecessary update being applied.
Environment
Kubernetes cluster type:
vanilla
$ Mention java-operator-sdk version from pom.xml file
4.9.7
$ java -version
21
$ kubectl version
v1.30.4
Possible Solution
Modify SSABasedGenericKubernetesResourceMatcher to handle cases where Kubernetes omits fields with default values, treating their absence as equivalent to explicitly setting the default value.
Additional context
This issue may affect other defaulted fields in Kubernetes objects, not just initialDelaySeconds. A general approach to handling default values might be necessary.
It is infinite reconciliation loop. The problem is that the desired resource contains the default (0) value while k8s does not contain the default value (0). I have no control over actual resource in io.javaoperatorsdk.operator.processing.dependent.kubernetes.SSABasedGenericKubernetesResourceMatcher.
It looks like 0 for Integer is threaten as null by k8s but difference between setting 0 and null is that if you set 0 then field is marked as managed by operator controller.
Activity
csviri commentedon Mar 27, 2025
Thx @kamilchociej , I think the current workaround is to fill the defaults in you current resources.
csviri commentedon Mar 27, 2025
Just to make sure I understand, this does not result in an infinite loop in your side, just an additional reconciliation right?
kamilchociej commentedon Mar 27, 2025
It is infinite reconciliation loop. The problem is that the desired resource contains the default (0) value while k8s does not contain the default value (0). I have no control over actual resource in io.javaoperatorsdk.operator.processing.dependent.kubernetes.SSABasedGenericKubernetesResourceMatcher.
kamilchociej commentedon Mar 27, 2025
Default value is removed from resource definition on k8s side while the property remains as managed field in controller managed fields entry.
kamilchociej commentedon Mar 27, 2025
Whole process looks like:
kamilchociej commentedon Mar 27, 2025
It looks like 0 for Integer is threaten as null by k8s but difference between setting 0 and null is that if you set 0 then field is marked as managed by operator controller.
csviri commentedon Mar 27, 2025
can you try to set
previousAnnotationForDependentResourcesEventFilteringto false, if it helps with infinite loop?kamilchociej commentedon Mar 27, 2025
Where can I set this?
kamilchociej commentedon Mar 27, 2025
Following logic applied on each desired Probe resolves the issue:
This is ugly workaround but at least it works for Probes.
csviri commentedon Mar 27, 2025
java-operator-sdk/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java
Line 447 in e48a44c
within
ConfigurationService, similar to this:java-operator-sdk/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageOperator.java
Line 28 in e48a44c
csviri commentedon Mar 27, 2025
That should fix the infinite loop.
csviri commentedon Mar 31, 2025
closing this as duplicate: #2553