From d0dfac8a99a1fa60624496b6be74aec2dbde4d20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 24 Mar 2025 09:51:18 +0100 Subject: [PATCH 1/7] Update reconciler.md --- .../en/docs/documentation/reconciler.md | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/docs/content/en/docs/documentation/reconciler.md b/docs/content/en/docs/documentation/reconciler.md index 330bc15ac7..5678ab604f 100644 --- a/docs/content/en/docs/documentation/reconciler.md +++ b/docs/content/en/docs/documentation/reconciler.md @@ -5,44 +5,40 @@ weight: 45 ## Reconciliation Execution in a Nutshell -Reconciliation execution is always triggered by an event. Events typically come from a +An event always triggers reconciliation execution. Events typically come from a primary resource, most of the time a custom resource, triggered by changes made to that resource -on the server (e.g. a resource is created, updated or deleted). Reconciler implementations are -associated with a given resource type and listens for such events from the Kubernetes API server +on the server (e.g. a resource is created, updated, or deleted). Reconciler implementations are +associated with a given resource type and listen for such events from the Kubernetes API server so that they can appropriately react to them. It is, however, possible for secondary sources to trigger the reconciliation process. This usually occurs via the [event source](#handling-related-events-with-event-sources) mechanism. -When an event is received reconciliation is executed, unless a reconciliation is already +When we receive an event it triggers the reconciliation, unless a reconciliation is already underway for this particular resource. In other words, the framework guarantees that no -concurrent reconciliation happens for any given resource. +concurrent reconciliation happens for a resource. Once the reconciliation is done, the framework checks if: -- an exception was thrown during execution and if yes schedules a retry. -- new events were received during the controller execution, if yes schedule a new reconciliation. -- the reconcilier instructed the SDK to re-schedule a reconciliation at a later date, if yes - schedules a timer event with the specified delay. -- none of the above, the reconciliation is finished. +- an exception was thrown during execution, and if yes, schedules a retry. +- new events were received during the controller execution; if yes, schedule a new reconciliation. +- the reconciler results explicitly re-schedules (`UpdateControl.rescheduleAfter(..)`) a reconciliation with a time delay, if yes, + schedules a timer event with the specific delay. +- if none above applies, the reconciliation is finished. -In summary, the core of the SDK is implemented as an eventing system, where events trigger +In summary, the core of the SDK is implemented as an eventing system where events trigger reconciliation requests. ## Implementing a [`Reconciler`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java) and/or [`Cleaner`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Cleaner.java) -The lifecycle of a Kubernetes resource can be clearly separated into two phases from the -perspective of an operator depending on whether a resource is created or updated, or on the -other hand if it is marked for deletion. +The lifecycle of a Kubernetes resource can be separated into two phases depending on weather the resource is already marked for deletion or not. -This separation-related logic is automatically handled by the framework. The framework will always -call the `reconcile` method, unless the custom resource is +The framework out of the box supports this logic, it will always +call the `reconcile` method unless the custom resource is [marked from deletion](https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/#how-finalizers-work) . On the other, if the resource is marked from deletion and if the `Reconciler` implements the -`Cleaner` interface, only the `cleanup` method will be called. Implementing the `Cleaner` -interface allows developers to let the SDK know that they are interested in cleaning related -state (e.g. out-of-cluster resources). The SDK will therefore automatically add a finalizer -associated with your `Reconciler` so that the Kubernetes server doesn't delete your resources -before your `Reconciler` gets a chance to clean things up. +`Cleaner` interface, only the `cleanup` method is called. By implementing the `Cleaner` +the framework will automatically handle (add/remove) the finalizers for you. + See [Finalizer support](#finalizer-support) for more details. ### Using `UpdateControl` and `DeleteControl` @@ -175,4 +171,4 @@ You can specify the name of the finalizer to use for your `Reconciler` using the [`@ControllerConfiguration`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java) annotation. If you do not specify a finalizer name, one will be automatically generated for you. -From v5 by default finalizer is added using Served Side Apply. See also UpdateControl in docs. \ No newline at end of file +From v5 by default finalizer is added using Served Side Apply. See also UpdateControl in docs. From 6a8c675548ec8363bda9e5d97ce69465a8cb6ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 24 Mar 2025 09:57:54 +0100 Subject: [PATCH 2/7] Update reconciler.md --- .../en/docs/documentation/reconciler.md | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/docs/content/en/docs/documentation/reconciler.md b/docs/content/en/docs/documentation/reconciler.md index 5678ab604f..24a8b08ea4 100644 --- a/docs/content/en/docs/documentation/reconciler.md +++ b/docs/content/en/docs/documentation/reconciler.md @@ -6,16 +6,15 @@ weight: 45 ## Reconciliation Execution in a Nutshell An event always triggers reconciliation execution. Events typically come from a -primary resource, most of the time a custom resource, triggered by changes made to that resource -on the server (e.g. a resource is created, updated, or deleted). Reconciler implementations are -associated with a given resource type and listen for such events from the Kubernetes API server +primary resource, usually a custom resource, triggered by changes made to that resource +on the server (e.g. a resource is created, updated, or deleted) or from secondary resources for which there is a registered event source. +Reconciler implementations are associated with a given resource type and listen for such events from the Kubernetes API server so that they can appropriately react to them. It is, however, possible for secondary sources to -trigger the reconciliation process. This usually occurs via +trigger the reconciliation process. This occurs via the [event source](#handling-related-events-with-event-sources) mechanism. -When we receive an event it triggers the reconciliation, unless a reconciliation is already -underway for this particular resource. In other words, the framework guarantees that no -concurrent reconciliation happens for a resource. +When we receive an event, it triggers the reconciliation unless a reconciliation is already +underway for this particular resource. In other words, the framework guarantees that no concurrent reconciliation happens for a resource. Once the reconciliation is done, the framework checks if: @@ -23,7 +22,7 @@ Once the reconciliation is done, the framework checks if: - new events were received during the controller execution; if yes, schedule a new reconciliation. - the reconciler results explicitly re-schedules (`UpdateControl.rescheduleAfter(..)`) a reconciliation with a time delay, if yes, schedules a timer event with the specific delay. -- if none above applies, the reconciliation is finished. +- if none of the above applies, the reconciliation is finished. In summary, the core of the SDK is implemented as an eventing system where events trigger reconciliation requests. @@ -43,7 +42,7 @@ See [Finalizer support](#finalizer-support) for more details. ### Using `UpdateControl` and `DeleteControl` -These two classes are used to control the outcome or the desired behaviour after the reconciliation. +These two classes control the outcome or the desired behavior after the reconciliation. The [`UpdateControl`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java) can instruct the framework to update the status sub-resource of the resource @@ -71,13 +70,10 @@ without an update: } ``` -Note, though, that using `EventSources` should be preferred to rescheduling since the -reconciliation will then be triggered only when needed instead than on a timely basis. - -Those are the typical use cases of resource updates, however in some cases there it can happen that -the controller wants to update the resource itself (for example to add annotations) or not perform -any updates, which is also supported. +Note, though, that using `EventSources` is the preferred way of scheduling since the +reconciliation is triggered only when a resource is changed, not on a timely basis. +At the end of the reconciliation, you typically update the status sub-resources. It is also possible to update both the status and the resource with the `patchResourceAndStatus` method. In this case, the resource is updated first followed by the status, using two separate requests to the Kubernetes API. From 9ddaf28d8276d3cf288e4e108e675d5220431776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 24 Mar 2025 10:05:27 +0100 Subject: [PATCH 3/7] Update reconciler.md --- .../en/docs/documentation/reconciler.md | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/docs/content/en/docs/documentation/reconciler.md b/docs/content/en/docs/documentation/reconciler.md index 24a8b08ea4..bc5de86971 100644 --- a/docs/content/en/docs/documentation/reconciler.md +++ b/docs/content/en/docs/documentation/reconciler.md @@ -27,18 +27,21 @@ Once the reconciliation is done, the framework checks if: In summary, the core of the SDK is implemented as an eventing system where events trigger reconciliation requests. -## Implementing a [`Reconciler`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java) and/or [`Cleaner`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Cleaner.java) +## Implementing a Reconciler and Cleaner interfaces -The lifecycle of a Kubernetes resource can be separated into two phases depending on weather the resource is already marked for deletion or not. +To implement a reconciler, you always have to implement the [`Reconciler`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java) interface. + +The lifecycle of a Kubernetes resource can be separated into two phases depending on whether the resource has already been marked for deletion or not. The framework out of the box supports this logic, it will always call the `reconcile` method unless the custom resource is -[marked from deletion](https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/#how-finalizers-work) -. On the other, if the resource is marked from deletion and if the `Reconciler` implements the -`Cleaner` interface, only the `cleanup` method is called. By implementing the `Cleaner` +[marked from deletion](https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/#how-finalizers-work). + +On the other, if the resource is marked from deletion and if the `Reconciler` implements the +[`Cleaner`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Cleaner.java) interface, only the `cleanup` method is called. By implementing the `Cleaner` the framework will automatically handle (add/remove) the finalizers for you. -See [Finalizer support](#finalizer-support) for more details. +In short, if you need to provide explicit cleanup logic, you always want to use finalizers; for a more detailed explanation, see [Finalizer support](#finalizer-support) for more details. ### Using `UpdateControl` and `DeleteControl` @@ -133,32 +136,30 @@ Kubernetes cluster (e.g. external resources), you might not need to use finalize use the Kubernetes [garbage collection](https://kubernetes.io/docs/concepts/architecture/garbage-collection/#owners-dependents) mechanism as much as possible by setting owner references for your secondary resources so that -the cluster can automatically deleted them for you whenever the associated primary resource is +the cluster can automatically delete them for you whenever the associated primary resource is deleted. Note that setting owner references is the responsibility of the `Reconciler` implementation, though [dependent resources](https://javaoperatorsdk.io/docs/dependent-resources) make that process easier. -If you do need to clean such state, you need to use finalizers so that their +If you do need to clean such a state, you need to use finalizers so that their presence will prevent the Kubernetes server from deleting the resource before your operator is -ready to allow it. This allows for clean up to still occur even if your operator was down when -the resources was "deleted" by a user. +ready to allow it. This allows for clean-up even if your operator was down when the resource was marked for deletion. JOSDK makes cleaning resources in this fashion easier by taking care of managing finalizers automatically for you when needed. The only thing you need to do is let the SDK know that your -operator is interested in cleaning state associated with your primary resources by having it +operator is interested in cleaning the state associated with your primary resources by having it implement the [`Cleaner

`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Cleaner.java) interface. If your `Reconciler` doesn't implement the `Cleaner` interface, the SDK will consider -that you don't need to perform any clean-up when resources are deleted and will therefore not -activate finalizer support. In other words, finalizer support is added only if your `Reconciler` -implements the `Cleaner` interface. +that you don't need to perform any clean-up when resources are deleted and will, therefore, not activate finalizer support. +In other words, finalizer support is added only if your `Reconciler` implements the `Cleaner` interface. -Finalizers are automatically added by the framework as the first step, thus after a resource -is created, but before the first reconciliation. The finalizer is added via a separate +The framework automatically adds finalizers as the first step, thus after a resource +is created but before the first reconciliation. The finalizer is added via a separate Kubernetes API call. As a result of this update, the finalizer will then be present on the resource. The reconciliation can then proceed as normal. -The finalizer that is automatically added will be also removed after the `cleanup` is executed on +The automatically added finalizer will also be removed after the `cleanup` is executed on the reconciler. This behavior is customizable as explained [above](#using-updatecontrol-and-deletecontrol) when we addressed the use of `DeleteControl`. @@ -167,4 +168,4 @@ You can specify the name of the finalizer to use for your `Reconciler` using the [`@ControllerConfiguration`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java) annotation. If you do not specify a finalizer name, one will be automatically generated for you. -From v5 by default finalizer is added using Served Side Apply. See also UpdateControl in docs. +From v5, by default, the finalizer is added using the Served Side Apply. See also UpdateControl in docs. From 6037da5ee1b5e11be01905213ed0adcb56a1a714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 24 Mar 2025 13:50:48 +0100 Subject: [PATCH 4/7] Update docs/content/en/docs/documentation/reconciler.md Co-authored-by: Chris Laprun --- docs/content/en/docs/documentation/reconciler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/en/docs/documentation/reconciler.md b/docs/content/en/docs/documentation/reconciler.md index bc5de86971..0bb8431e9c 100644 --- a/docs/content/en/docs/documentation/reconciler.md +++ b/docs/content/en/docs/documentation/reconciler.md @@ -38,7 +38,7 @@ call the `reconcile` method unless the custom resource is [marked from deletion](https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/#how-finalizers-work). On the other, if the resource is marked from deletion and if the `Reconciler` implements the -[`Cleaner`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Cleaner.java) interface, only the `cleanup` method is called. By implementing the `Cleaner` +[`Cleaner`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Cleaner.java) interface, only the `cleanup` method is called. By implementing this interface the framework will automatically handle (add/remove) the finalizers for you. In short, if you need to provide explicit cleanup logic, you always want to use finalizers; for a more detailed explanation, see [Finalizer support](#finalizer-support) for more details. From e4045900c9507dc6bdf468982460da0c2db5eb6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 24 Mar 2025 13:50:55 +0100 Subject: [PATCH 5/7] Update docs/content/en/docs/documentation/reconciler.md Co-authored-by: Chris Laprun --- docs/content/en/docs/documentation/reconciler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/en/docs/documentation/reconciler.md b/docs/content/en/docs/documentation/reconciler.md index 0bb8431e9c..b126bf8ded 100644 --- a/docs/content/en/docs/documentation/reconciler.md +++ b/docs/content/en/docs/documentation/reconciler.md @@ -37,7 +37,7 @@ The framework out of the box supports this logic, it will always call the `reconcile` method unless the custom resource is [marked from deletion](https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/#how-finalizers-work). -On the other, if the resource is marked from deletion and if the `Reconciler` implements the +On the other hand, if the resource is marked from deletion and if the `Reconciler` implements the [`Cleaner`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Cleaner.java) interface, only the `cleanup` method is called. By implementing this interface the framework will automatically handle (add/remove) the finalizers for you. From 148aeb5f9f5847da965306568888e2acadb9b524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 24 Mar 2025 13:54:56 +0100 Subject: [PATCH 6/7] Update docs/content/en/docs/documentation/reconciler.md Co-authored-by: Chris Laprun --- docs/content/en/docs/documentation/reconciler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/en/docs/documentation/reconciler.md b/docs/content/en/docs/documentation/reconciler.md index b126bf8ded..a5e14e1919 100644 --- a/docs/content/en/docs/documentation/reconciler.md +++ b/docs/content/en/docs/documentation/reconciler.md @@ -168,4 +168,4 @@ You can specify the name of the finalizer to use for your `Reconciler` using the [`@ControllerConfiguration`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java) annotation. If you do not specify a finalizer name, one will be automatically generated for you. -From v5, by default, the finalizer is added using the Served Side Apply. See also UpdateControl in docs. +From v5, by default, the finalizer is added using Server Side Apply. See also `UpdateControl` in docs. From 4d429f3a3b48cb634197ac3b74c3bc910ee612a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 24 Mar 2025 13:55:05 +0100 Subject: [PATCH 7/7] Update docs/content/en/docs/documentation/reconciler.md Co-authored-by: Chris Laprun --- docs/content/en/docs/documentation/reconciler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/en/docs/documentation/reconciler.md b/docs/content/en/docs/documentation/reconciler.md index a5e14e1919..26a2a20d61 100644 --- a/docs/content/en/docs/documentation/reconciler.md +++ b/docs/content/en/docs/documentation/reconciler.md @@ -20,7 +20,7 @@ Once the reconciliation is done, the framework checks if: - an exception was thrown during execution, and if yes, schedules a retry. - new events were received during the controller execution; if yes, schedule a new reconciliation. -- the reconciler results explicitly re-schedules (`UpdateControl.rescheduleAfter(..)`) a reconciliation with a time delay, if yes, +- the reconciler results explicitly re-scheduled (`UpdateControl.rescheduleAfter(..)`) a reconciliation with a time delay, if yes, schedules a timer event with the specific delay. - if none of the above applies, the reconciliation is finished.