Skip to content

Orphan secondary resources are left when using annotation based owner reference #2259

Open
@AleksanderBrzozowski

Description

@AleksanderBrzozowski

Bug Report

What did you do?

We have a primary resource, let's call it MyCustomResource. The reconciler for this resource creates and maintains a ConfigMap based on the MyCustomResource. The ConfigMap is created in a different namespace than MyCustomResource, thus we cannot use the ownerReference mechanism to ensure that the resource is deleted when the primary resource is deleted. To do so, we use JOSDK annotations (primary-name and primary-namespace).

The issue is that sometimes when the primary resource is deleted very quickly - right after it was created, the secondary resource is not created:

2024-03-04 10:12:17,918 ERROR [io.jav.ope.pro.eve.EventProcessor] (ReconcilerExecutor-mycustomresourcereconciler-117) Error during event processing ExecutionScope{ resource id: ResourceID{name='test', namespace='default'}, version: 7364248}: java.lang.NullPointerException: Cannot invoke "io.fabric8.kubernetes.api.model.HasMetadata.addFinalizer(String)" because "r" is null
	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.lambda$updateCustomResourceWithFinalizer$2(ReconciliationDispatcher.java:331)
	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.conflictRetryingUpdate(ReconciliationDispatcher.java:353)
	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.updateCustomResourceWithFinalizer(ReconciliationDispatcher.java:330)
	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.handleReconcile(ReconciliationDispatcher.java:116)
	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.handleDispatch(ReconciliationDispatcher.java:90)
	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.handleExecution(ReconciliationDispatcher.java:64)
	at io.javaoperatorsdk.operator.processing.event.EventProcessor$ReconcilerExecutor.run(EventProcessor.java:450)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:833)

So it seems that the secondary resource is created, even though the primary resource has no finalizer added.

This issue was reproduced with a sample repo. There is a repeated test that fails after several test loops - it is non deterministic.

What did you expect to see?

There are no Orphan secondary resources left, when the Primary is deleted.

What did you see instead? Under which circumstances?

There is an Orphan secondary resource left, that will be never deleted.

Environment

Kubernetes cluster type:

rancher desktop, version: 1.25

$ Mention java-operator-sdk version from pom.xml file

4.8.0

$ java -version

Java Temurin 17.0.6

$ kubectl version

kubectl version doesn't seem to be related, under the hood JOSDK is using fabric8 kubernetes client with version 6.10.0

Possible Solution

Make sure that the finalizer is applied first before creating secondary resources

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions