Skip to content

Depends On and Conditions to describe workflows Dependent Resources #850

Closed
@csviri

Description

@csviri

Problem statement

  1. If for a resource we need an input what is an output (or status in K8S of the other resource). (Ideally these would be detected automatically? probably that is not feasable)
  2. When we want to make sure that something happens after an other resource is ready. Like if database is deployed, and want to create a specific default schema.

Solution

Both of these issues, can be addressed by with notions.

  1. dependsOn - If a dependent resource B depends on an other dependent A, this will ensure that B will be reconciled after A is ready (see optional ReadyCondition).
  2. ReconcilePrecondition is optional for a dependent, if available it is evaluated if a resource should be reconciled or not.
  3. ReadyPostcondition is optional, is provided the dependent is considered reconciled if the certain state reached. The condition check is async.
  4. DeletePostcondition - on cleanup (backwards workflow) checks if the resource is deleted successfully (or delete completed) , or the cleanup execution should be re-scheduled (the finalizer not removed).
@ControllerConfiguration( ... ,
    dependents = {
       @Dependent(name="dep1", type = DeploymentDependentResource.class, readyPostcondition = ReadyCondition.class )
       @Dependent(name="ser1", type = ServiceDependentResource.class, reconcilePrecondition = MyCondition.class),
       @Dependent(type = OtherResource.class,  reconcilePrecondition = OtherCondition.class,
              deletePostcondition = DeleteCondition.class , dependsOn = {"dep1","ser1"}
         })
   })
 public class MyResourceReconciler implements Reconciler<MyResource>, EventSourceInitializer<MyResource> {
   ....
 }

Behavior Details

  • If a dependent resource B depends on A, but A has a ReconcilePrecondition is evaluated as false, then B will not be reconciled either.
  • If a ReconcilePrecondition is evaluated false on A dependent resource it is a Deleter, delete should be called on it. And all the resources which are dependent on A and are deleters should be deleted. This should work in a transitive manner too ( in reveres order, so the resource with reconcile condition closer to the top is deleted later). (See: https://github.com/java-operator-sdk/java-operator-sdk/blob/4d63e1260efeb70ac7550d52e48117bf8982fabb/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStandaloneDependentsReconciler.java#L68-L72 )
  • if ReadyPostcondition can define an UpdateControl to return if the condition is now reached, this means that effectively wait is always async. It can also defined time delay to reschedule the reconciliation.
  • For cleanup (TBD) - we could dry run the actual workflow (evaulating the conditions), and execute deleters backwards, also taking in mind delete post conditions (this might be an issue if dependent changes just parallel with the CR deletion). - Alternatively, what might a more bulletproof way is just based on the backwards order red the state of all the resources defined, and delete them if present.
  • Eventually a possible concurrency option could be implemented (maybe think of it from early design). Not dependent resources could be reconciled concurrently.

Sync and Async Waiting Condition

Note that waiting for a state condition can happen synchronously or asynchronously, thus if we know that we will wait for deployment quite a long time to be ready, the scheduling algirthm can just exit the reonciliation and schedule a new reconciliation for a specified delay (UpdateControl.noUpdate().rescheduleAfter(2, TimeUnit.MINUTES) if the condition not holds at the moment.

UPDATE: we discussed, for now and sync wait will be out of scope

Notes

  1. Not that without cycles the result is a DAG, what can be nicely scheduled for execution, more precisely a set of DAGs.
  2. The cycle detection will be needed, to help developers detect cycles as early as possible.
  3. This is an implementation detail, but 1 thing to think about is actually how to manage state, so if it's not in the status but a ConfigMap/Secret/CR the execution of two dependent resource reconciliation in the DAG cannot be parallel. Or at least not of those which update the state, so there are no conflicts. Maybe those should be marked explicitly as an improvement later?
  4. DeletePostcondition makes sense only for Deleter dependent resources.

To Discuss

  1. DeletePostcondition could be replaced by returning a boolean from delete of Deleter.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions